Index: trunk/nv/engine/model_manager.hh
===================================================================
--- trunk/nv/engine/model_manager.hh	(revision 509)
+++ trunk/nv/engine/model_manager.hh	(revision 510)
@@ -27,4 +27,10 @@
 namespace nv
 {
+	enum class model_node_choice
+	{
+		ALL,
+		WEIGHTED,
+		PATTERN_CHECKER
+	};
 
 	struct model_node
@@ -40,5 +46,5 @@
 		float                        chance    = 1.0f;
 		bool                         force     = false;
-		bool                         choice    = false;
+		model_node_choice            choice    = model_node_choice::ALL;
 
 		void clone_values_to( model_node* target ) const
@@ -118,5 +124,11 @@
 		virtual string_view get_storage_name() const { return "models"; }
 		virtual string_view get_resource_name() const { return "model"; }
-		static flat_model flatten( const model* m, random_base& rng, vector< const model_node* >* map = nullptr, uint32 gen_flags = 0, const model_node* select = nullptr )
+		static flat_model flatten( 
+			const model* m, 
+			random_base& rng, 
+			ivec2 control,
+			vector< const model_node* >* map = nullptr, 
+			uint32 gen_flags = 0, 
+			const model_node* select = nullptr )
 		{
 			flat_model result;
@@ -125,5 +137,5 @@
 			result.local = m->root;
 			result.count = 0;
-			flatten( result, m, rng, transform(), -1, map, gen_flags, 0, select );
+			flatten( result, m, rng, control, transform(), -1, map, gen_flags, 0, select );
 			return result;
 		}
@@ -133,4 +145,5 @@
 			const model_node* m, 
 			random_base& rng, 
+			ivec2 control,
 			const transform& ptr, 
 			sint16 parent_id, 
@@ -198,37 +211,40 @@
 			}
 
-			if ( m->choice )
+			if ( m->choice != model_node_choice::ALL )
 			{
-				uint16 total_weight = 0;
-				for ( auto c : m->children ) 
-					total_weight += c->weight;
-				if ( total_weight > 0 )
-				{
+				model_node* pick = nullptr;
+				if ( m->choice == model_node_choice::WEIGHTED )
+				{
+					uint16 total_weight = 0;
+					for ( auto c : m->children )
+						total_weight += c->weight;
+					if ( total_weight == 0 ) return;
 					sint32 roll = rng.srand( total_weight );
-					model_node* pick = nullptr;
 					for ( auto c : m->children )
 					{
 						roll -= c->weight;
-						if ( roll < 0 )
-						{
-							pick = c;
-							break;
-						}
+						if ( roll < 0 ) { pick = c; break; }
 					}
-					if ( gen_flags & FF_GENERATE_CHOICE )
-						for ( auto c : m->children )
-						{
-							uint32 flags = parent_flags;
-							if ( c != pick ) flags |= FMF_FAIL_CHOICE;
-							flatten( result, c, rng, tr, parent_id, map, gen_flags, flags, selected );
-						}
-					else
-						flatten( result, pick, rng, tr, parent_id, map, gen_flags, parent_flags, selected );
-				}
+				}
+				else if ( m->choice == model_node_choice::PATTERN_CHECKER )
+				{
+					pick = m->children[( control.x + control.y ) % m->children.size()];
+				}
+
+				if ( pick == nullptr ) return;
+				if ( gen_flags & FF_GENERATE_CHOICE )
+					for ( auto c : m->children )
+					{
+						uint32 flags = parent_flags;
+						if ( c != pick ) flags |= FMF_FAIL_CHOICE;
+						flatten( result, c, rng, control, tr, parent_id, map, gen_flags, flags, selected );
+					}
+				else
+					flatten( result, pick, rng, control, tr, parent_id, map, gen_flags, parent_flags, selected );
 			}
 			else
 				for ( auto c : m->children )
 				{
-					flatten( result, c, rng, tr, parent_id, map, gen_flags, parent_flags, selected );
+					flatten( result, c, rng, control, tr, parent_id, map, gen_flags, parent_flags, selected );
 				}
 		}
Index: trunk/src/engine/default_resource_manager.cc
===================================================================
--- trunk/src/engine/default_resource_manager.cc	(revision 509)
+++ trunk/src/engine/default_resource_manager.cc	(revision 510)
@@ -61,4 +61,8 @@
 	m_lua->register_enum( "EASING_SINE",    static_cast<int>( easing_type::SINE ) );
 
+	m_lua->register_enum( "CHOICE_ALL", static_cast<int>( model_node_choice::ALL ) );
+	m_lua->register_enum( "CHOICE_WEIGHTED", static_cast<int>( model_node_choice::WEIGHTED ) );
+	m_lua->register_enum( "CHOICE_PATTERN_CHECKER", static_cast<int>( model_node_choice::PATTERN_CHECKER ) );
+
 	m_materials->initialize( lua );
 	m_programs->initialize( lua );
Index: trunk/src/engine/model_manager.cc
===================================================================
--- trunk/src/engine/model_manager.cc	(revision 509)
+++ trunk/src/engine/model_manager.cc	(revision 510)
@@ -104,5 +104,5 @@
 
 	node->force     = table.get_boolean( "force", false );
-	node->choice    = table.get_boolean( "choice", false );
+	node->choice    = model_node_choice( table.get_unsigned( "choice", false ) );
 	node->chance    = table.get_float( "chance", 1.0f );
 	node->weight    = table.get_unsigned( "weight", 1 );
