Index: cpp/frams/genetics/fL/fL_general.cpp
===================================================================
--- cpp/frams/genetics/fL/fL_general.cpp	(revision 973)
+++ cpp/frams/genetics/fL/fL_general.cpp	(revision 1273)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2020  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -9,9 +9,9 @@
 #include <iterator>
 
-const char *fL_part_names[FL_PART_PROPS_COUNT] = { "dn", "fr", "ing", "as" };
-const char *fL_part_fullnames[FL_PART_PROPS_COUNT] = { "details", "friction", "ingestion", "assimilation" };
-
-const char *fL_joint_names[FL_JOINT_PROPS_COUNT] = { "stif", "rotstif", "stam" };
-const char *fL_joint_fullnames[FL_JOINT_PROPS_COUNT] = { "stiffness", "rotation stiffness", "stamina" };
+const char *fL_part_names[FL_PART_PROPS_COUNT] = { "fr" }; // "dn", "ing", "as" };
+const char *fL_part_fullnames[FL_PART_PROPS_COUNT] = { "friction" }; // "density", "ingestion", "assimilation" };
+
+const char *fL_joint_names[FL_JOINT_PROPS_COUNT] = { "rotstif" }; //"stif", , "stam" }; //see the comment to fH_joint_names in fH_general.cpp
+const char *fL_joint_fullnames[FL_JOINT_PROPS_COUNT] = { "rotation stiffness" }; //"stiffness", "stamina" };
 
 #define FIELDSTRUCT fL_Word
@@ -502,10 +502,9 @@
 	fL_Word *stick = new fL_Word(true);
 	stick->name = "S";
-	stick->npar = 8;
+	stick->npar = FL_PART_PROPS_COUNT + FL_JOINT_PROPS_COUNT + 1; //MacKo 2023-07: was hardcoded "8" but crashed when the number of props in Part and Joint was decreased; I think it should be like it is now (4+3+1 - or another value depending on prop counts)
 	for (int i = 0; i < FL_PART_PROPS_COUNT; i++)
 	{
 		stick->mut.addProperty(NULL, fL_part_names[i], "s", fL_part_fullnames[i], fL_part_fullnames[i], PARAM_CANOMITNAME, 0, -1);
 	}
-
 	for (int i = 0; i < FL_JOINT_PROPS_COUNT; i++)
 	{
@@ -1096,6 +1095,5 @@
 					{
 						delete newpart;
-						logMessage("fL_Builder", "developModel", LOG_ERROR,
-							"Error parsing word parameter");
+						logMessage("fL_Builder", "developModel", LOG_ERROR, "Error parsing word parameter");
 						return 1;
 					}
@@ -1123,6 +1121,5 @@
 						if (word->parevals[FL_PART_PROPS_COUNT + i]->evaluateRPN(jointprop) != 0)
 						{
-							logMessage("fL_Builder", "developModel", LOG_ERROR,
-								"Error parsing word parameter");
+							logMessage("fL_Builder", "developModel", LOG_ERROR, "Error parsing word parameter");
 							delete newjoint;
 							return 1;
@@ -1153,4 +1150,34 @@
 				}
 				model->addNeuro(neu);
+
+
+				// MacKo 2023-07: embody (i.e., attach to body) sensors and effectors.
+				// Ad hoc modification; should be reconsidered as it was added without reminding and understanding of the entire logic of the phenotype development and assumptions, and may not be "the best performing" or "the most reasonable" approach. Without this embodiment, genotypes with sensors and effectors not attached to body had warnings (such neurons "could not be initialized") so such genotypes were not accepted when creatwarnfail==1; even with creatwarnfail==0, non-embodied sensor and effector neurons were useless.
+				//printf("Neuron: -------------- %s\n", details.c_str());
+				switch (neu->getClass()->getPreferredLocation())
+				{
+				case NeuroClass::PrefLocation::PREFER_PART: //attach to currstate.currpart
+					if (currstate.currpart != NULL)
+						neu->attachToPart(currstate.currpart);
+					break;
+				case NeuroClass::PrefLocation::PREFER_JOINT: //attach to the last joint incident with currstate.currpart
+					if (currstate.currpart != NULL)
+					{
+						Joint *j = NULL;
+						for (int i = 0; i < model->getJointCount(); i++)
+						{
+							Joint *jj = model->getJoint(i);
+							if (jj->part1 == currstate.currpart || jj->part2 == currstate.currpart)
+								j = jj;
+						}
+						if (j != NULL)
+							neu->attachToJoint(j);
+					}
+					break;
+				default:
+					break;
+				}
+
+
 				if (using_mapping) neu->addMapping(IRange(word->begin, word->end));
 				if (neu->getClass()->getPreferredInputs() != 0)
@@ -1251,5 +1278,5 @@
 			{
 				connsbuffer[i].second->addInput(connsbuffer[i].second, weight);
-				if (using_mapping) neu->addMapping(
+				if (using_mapping) connsbuffer[i].second->addMapping( //MacKo 2023-07: changed 'neu' (which is NULL here so crashed) to connsbuffer[i].second (no guarantee this is a proper fix, only inspired by the analogy to the difference in both branches of "if" in the line above)
 					IRange((*connsbuffer[i].first)->begin,
 						(*connsbuffer[i].first)->end));
