Index: cpp/frams/genetics/f4/f4_general.cpp
===================================================================
--- cpp/frams/genetics/f4/f4_general.cpp	(revision 1238)
+++ cpp/frams/genetics/f4/f4_general.cpp	(revision 1239)
@@ -19,5 +19,4 @@
 
 #define BREAK_WHEN_REP_COUNTER_NULL //see comments where it is used
-#define EXTRA_STEP_CELL_DEVELOPMENT //see comments where it is used
 #define TREAT_BAD_CONNECTIONS_AS_INVALID_GENO //see comments where it is used
 
@@ -41,6 +40,5 @@
 	org = NULL;
 	genot = NULL;
-	gcur = NULL;
-	active = true;
+	gcur = old_gcur = NULL;
 	repeat.clear();
 	//genoRange.clear(); -- implicit
@@ -89,6 +87,5 @@
 	org = nO;
 	genot = ngeno;
-	gcur = ngcur;
-	active = true;
+	gcur = old_gcur = ngcur;
 	repeat.clear();
 	//genoRange.clear(); -- implicit
@@ -268,5 +265,4 @@
 					}
 					repeat.clear();
-					active = false;  // stop
 					// eat up rest
 					int remaining_nodes = gcur->count() - 1;
@@ -421,13 +417,9 @@
 			{
 				// wait for other neurons to develop
-				// if there are others still active
-
-				int active_count = 0;
-				for (int i = 0; i < org->cell_count; i++)
-					if (org->C[i]->active) active_count++;
-				active = false; // next time when we reach wait_conn, we will not count ourselves as active (if we were the last active cell, we got a chance to continue development for one development step only)
-				if (active_count > 0)
-					// there is at least one active (including ourselves), halt, try again
+
+				if (!org->development_stagnation) // other cells are developing, the situation is changing, we may continue waiting...
 					return;  // error code not set -> halt this development and yield to other cells to develop
+
+				//no cells are developing and we are waiting, but there is no chance other cells will create neurons we are waiting for, so we are forced to move on.
 
 #ifdef TREAT_BAD_CONNECTIONS_AS_INVALID_GENO // MacKo 2023-04: there were so many invalid connections accumulating in the genotype (and stopping processing of the chain of gcur->child) that it looks like treating them as errors is better... in 2000's, Framsticks neurons were flexible when it comes to inputs and outputs (for example, when asked, muscles would provide an output too, and neurons that ignored inputs would still accept them when connected) so f4 could create connections pretty randomly, but after 2000's we attempt to respect neurons' getPreferredInputs() and getPreferredOutput() so the network of connections has more constraints.
@@ -443,6 +435,7 @@
 					//so this condition and checking for "#" is a simple way to be kind to some, but not all, bad connections, and not raise errors. Perhaps too kind and we open the door for too many cases with invalid connections.
 					//Maybe it would be better to perform this check before addConnection(), seeing that for example we process the last iteration of the repetition counter? But how would we know that the (needed here) input neuron will not be developed later by other dividing cells...
-					active = true; //not sure if needed, but let this cell have the chance to continue for as long as many children in the tree are left
+
 					gcur = gcur->child;
+					org->development_stagnation = false; //do not force other potentially waiting cells to hurry and act in this development cycle (which would be the last cycle if development_stagnation stayed true); we just acted and because of this the situation may change, so they can wait until another development_stagnation is detected
 					return;  // error code not set -> halt this development and yield to other cells to develop
 				}
@@ -541,5 +534,4 @@
 		}
 	}
-	active = false;  // done
 }
 
@@ -650,4 +642,5 @@
 	C[0] = new f4_Cell(this, 0, genome, genome, NULL, 0, GeneProps::standard_values);
 	cell_count = 1;
+	development_stagnation = false;
 }
 
@@ -670,17 +663,27 @@
 	int old_cell_count = cell_count; //cell_count may change in the loop as new cells may be appended because cells may be dividing
 	for (int i = 0; i < old_cell_count; i++)
-	{
-		C[i]->oneStep(); //keeps calling independently of C[i]->active
+		C[i]->old_gcur = C[i]->gcur;
+
+	for (int i = 0; i < old_cell_count; i++)
+	{
+		C[i]->oneStep();
 		if (errorcode != GENOPER_OK)
-		{
-			// error
-			C[i]->active = false;  // stop
-			return false;
-		}
-	}
-	for (int i = 0; i < cell_count; i++) //we check all cells, including newly created ones
-		if (C[i]->active)
-			return true; //at least one cell is still active. TODO maybe the development should stop NOT because of the "active" field (there is this strange "yielding" state too), but by observing the progress of all cells and continuing the development while (errorcode==GENOPER_OK AND (gcur of at least one cell changed OR cell_count changed)) ?
-	return false;
+			return false; // error -> end development
+	}
+
+	if (cell_count != old_cell_count) //the number of cells changed - something is going on!
+		return true; //so continue development!
+
+	for (int i = 0; i < old_cell_count; i++)
+		if (C[i]->old_gcur != C[i]->gcur) // genotype execution pointer changed - something is going on!
+			return true; //so continue development!
+
+	if (development_stagnation)
+		return false; //the same number of cells, no progress in development in any cell -> stagnation, end development
+	else
+	{
+		development_stagnation = true; //signal (force) f4_Cell's that wait for neural connection development to make a step, because all cells stagnated and waiting cells cannot hope for new neurons to be created
+		return true;
+	}
 }
 
@@ -690,6 +693,5 @@
 	const bool PRINT_CELLS_DEVELOPMENT = false; //print the state of cells
 	errorcode = GENOPER_OK;
-
-	for (int i = 0; i < cell_count; i++)  C[i]->active = true;
+	development_stagnation = false; //will be detected by oneStep()
 
 	if (PRINT_CELLS_DEVELOPMENT) f4_Node::print_tree(C[0]->genot, 0);
@@ -699,11 +701,4 @@
 	while (oneStep()) if (PRINT_CELLS_DEVELOPMENT) print_cells("Development step");
 	if (PRINT_CELLS_DEVELOPMENT) print_cells("After last development step");
-
-#ifdef EXTRA_STEP_CELL_DEVELOPMENT
-	if (errorcode == GENOPER_OK)
-	{
-		oneStep(); if (PRINT_CELLS_DEVELOPMENT) print_cells("After extra step"); //for these "halted" (yielding) cells (they have active==false) that wait for other cells to develop. Without this step, the last, recently halted one(s) may miss the "retrying" step if all active==true cells became active==false in the last step.
-	}
-#endif
 
 	if (errorcode != GENOPER_OK) return errorcode;
@@ -762,5 +757,5 @@
 		default: type = std::to_string(c->type);
 		}
-		const char *status = c->active ? "active" : (c->gcur != NULL ? "yielding" : ""); //yielding = not active but waiting for other cells
+		const char *status = c->gcur == c->old_gcur ? (c->gcur != NULL ? "no progress" : "") : (c->gcur != NULL ? "progress" : "finished"); //progress or no progress means the cell is yielding = not finished but decided to halt development and wait for other cells. New cells may be created in case of "no progress" status.
 		printf("%2d(%-8s)  nr=%d \t type=%-15s \t genot=%s \t gcurrent=%s", i, status, c->nr, type.c_str(), c->genot->name.c_str(), c->gcur ? c->gcur->name.c_str() : "null");
 		if (c->gcur && c->gcur->name == "[")
@@ -1409,5 +1404,5 @@
 			static
 #else
-			thread_local 
+			thread_local
 #endif
 				vector<int> modifs_counts(strlen(all_modifiers_no_comma)); ///<an array with a known constant size storing counters of each modifier symbol from all_modifiers_no_comma, created once to avoid reallocation every time when modifier genes are simplified during parsing. Initialization of required size; it will never be resized.
Index: cpp/frams/genetics/f4/f4_general.h
===================================================================
--- cpp/frams/genetics/f4/f4_general.h	(revision 1238)
+++ cpp/frams/genetics/f4/f4_general.h	(revision 1239)
@@ -190,5 +190,5 @@
 	f4_Node *genot; 	           ///<genotype tree
 	f4_Node *gcur;                 ///<current genotype execution pointer
-	bool active;                   ///<determines whether development is still active; even if false, the cell may "yield" - may be halted (but still having its onStep() called) due to neural connections waiting for other cells to potentially develop neurons
+	f4_Node *old_gcur;             ///<used externally by f4_Cells::oneStep() to track changes of gcur, i.e., to detect progress in cell development
 	repeat_stack repeat;           ///<stack holding repetition nodes and counters
 	int recProcessedFlag;          ///<used during recursive traverse
@@ -329,4 +329,5 @@
 	f4_Cell *C[F4_MAX_CELLS];  ///<Array of all cells of an organism
 	int     cell_count;        ///<Number of cells in an organism
+	bool    development_stagnation; ///< simulate() and oneStep() use it to force f4_Cell's waiting to develop their neural connections to progress, indicating that all cells have not had progress during the last step
 
 private:
