Index: cpp/frams/param/mutableparam.cpp
===================================================================
--- cpp/frams/param/mutableparam.cpp	(revision 464)
+++ cpp/frams/param/mutableparam.cpp	(revision 478)
@@ -171,6 +171,6 @@
 ParamEntry *pe=new ParamEntry();
 pe->fun1=0; pe->fun2=0;
-pe->group=(short)group;
-pe->flags=(short)(flags | MUTPARAM_ALLOCENTRY);
+pe->group=(paInt)group;
+pe->flags=(paInt)(flags | MUTPARAM_ALLOCENTRY);
 pe->offset=(intptr_t)data;
 pe->id=strdup(id);
Index: cpp/frams/param/param.cpp
===================================================================
--- cpp/frams/param/param.cpp	(revision 464)
+++ cpp/frams/param/param.cpp	(revision 478)
@@ -602,5 +602,5 @@
 			if (v.type == TObj)
 			{
-				logPrintf("ParamInterface", "set", LOG_WARN, "Getting integer value from object reference (%s)", v.getString().c_str());
+				logPrintf("ParamInterface", "set", LOG_ERROR, "Setting int '%s.%s' from object reference (%s)", getName(), id(i), v.getString().c_str());
 				return 0;
 			}
@@ -614,5 +614,5 @@
 			if (v.type == TObj)
 			{
-				logPrintf("ParamInterface", "set", LOG_WARN, "Getting floating point value from object reference (%s)", v.getString().c_str());
+				logPrintf("ParamInterface", "set", LOG_ERROR, "Setting float '%s.%s' from object reference (%s)", getName(), id(i), v.getString().c_str());
 				return 0;
 			}
@@ -621,5 +621,10 @@
 		}
 	case 's': { SString t = v.getString(); return setString(i, t); }
-	case 'o': return setObject(i, v.getObject());
+	case 'o':
+		if ((v.type!=TUnknown)&&(v.type!=TObj))
+			logPrintf("ParamInterface", "set", LOG_ERROR, "Setting object '%s.%s' from %s", getName(), id(i), v.typeAndValue().c_str());
+		else
+			return setObject(i, v.getObject());
+		break;
 	case 'x': return setExtValue(i, v);
 	default: logPrintf("ParamInterface", "set", LOG_ERROR, "'%s.%s' is not a field", getName(), id(i));
@@ -645,5 +650,5 @@
 			if ((after == NULL) || (*after))
 			{
-				logPrintf("ParamInterface", "set", LOG_WARN, "serialization format mismatch in %s.%s", (getName() ? getName() : "<Unknown>"), id(i));
+				logPrintf("ParamInterface", "set", LOG_ERROR, "serialization format mismatch in %s.%s", (getName() ? getName() : "<Unknown>"), id(i));
 				e.setEmpty();
 			}
@@ -956,4 +961,20 @@
 	ParamEntry *pe = entry(i);
 	if (pe->flags&PARAM_READONLY) return PSET_RONLY;
+	if (pe->flags&PARAM_OBJECTSET)
+		{
+		ExtObject o=getObject(i);
+		Param tmp;
+		ParamInterface* oif=o.getParamInterface(tmp);
+		int ass;
+		if (oif && ((ass=oif->findId("assign"))>=0))
+			{
+			ExtValue arg=x;
+			oif->call(ass,&arg,&v);
+			}
+		else
+			logPrintf("SimpleAbstractParam", "setObject", LOG_ERROR,
+				  "'%s.%s' is PARAM_OBJECTSET but no 'assign()' in %s", getName(), pe->id, o.interfaceName());
+		return PSET_CHANGED;
+		}
 	ExtObject xcopy = x; //only needed for messageOnExceedRange(): retain original, requested value of x because it may be changed below
 	if (pe->fun2)
Index: cpp/frams/param/param.h
===================================================================
--- cpp/frams/param/param.h	(revision 464)
+++ cpp/frams/param/param.h	(revision 478)
@@ -33,4 +33,5 @@
 #define PARAM_DEPRECATED  8192  //< this member is deprecated
 #define PARAM_LINECOMMENT 16384 //< Param::load() adds "@line ..." comment when loading multiline (internal use)
+#define PARAM_OBJECTSET 32768   //< setting this field is handled by the object's assign(...) function and cannot change the object reference
 
 typedef int32_t paInt;
@@ -216,5 +217,5 @@
 {
 	const char *id;
-	short group, flags;
+	paInt group, flags;
 	const char *name, *type;
 	intptr_t offset;
@@ -227,5 +228,5 @@
 {
 public:
-	ParamEntryConstructor(const char *_id, short _group = 0, short _flags = 0, const char *_name = 0, const char *_type = 0, intptr_t _offset = 0, void *_fun1 = 0, void *_fun2 = 0, const char *_help = 0)
+	ParamEntryConstructor(const char *_id, paInt _group = 0, paInt _flags = 0, const char *_name = 0, const char *_type = 0, intptr_t _offset = 0, void *_fun1 = 0, void *_fun2 = 0, const char *_help = 0)
 	{
 		id = _id; group = _group; flags = _flags; name = _name; type = _type; offset = _offset; fun1 = _fun1; fun2 = _fun2; help = _help;
Index: cpp/frams/param/paramobj.cpp
===================================================================
--- cpp/frams/param/paramobj.cpp	(revision 464)
+++ cpp/frams/param/paramobj.cpp	(revision 478)
@@ -41,6 +41,6 @@
 	if (addnew) count++;
 	t = tab = (ParamEntry*)malloc(sizeof(ParamEntry)*(count + gcount + 1));
-	t->group = (short)gcount;
-	t->flags = (short)count;
+	t->group = (paInt)gcount;
+	t->flags = (paInt)count;
 	t->name = maybedup(dupentries, rename ? rename : pi->getName());
 	t->type = maybedup(dupentries, pi->getDescription());
@@ -82,6 +82,6 @@
 					offset += sizeof(ExtValue);
 					}
-				t->group = (short)(stripgroups ? 0 : pi->group(i));
-				t->flags = (short)pi->flags(i);
+				t->group = (paInt)(stripgroups ? 0 : pi->group(i));
+				t->flags = (paInt)pi->flags(i);
 				if (readonly_into_userreadonly && (t->flags & PARAM_READONLY))
 					t->flags=(t->flags & ~PARAM_READONLY) | PARAM_USERREADONLY;
Index: cpp/frams/param/paramtabobj.cpp
===================================================================
--- cpp/frams/param/paramtabobj.cpp	(revision 464)
+++ cpp/frams/param/paramtabobj.cpp	(revision 478)
@@ -25,5 +25,5 @@
 memmove(tab+siz-count,p,sizeof(ParamEntry)*count);
 memset(tab+siz,0,sizeof(ParamEntry));
-if (siz>0) tab[0].flags=(short)(siz-tab[0].group);
+if (siz>0) tab[0].flags=(paInt)(siz-tab[0].group);
 return siz-1;
 }
@@ -34,5 +34,5 @@
 resize(siz-count);
 memset(tab+siz,0,sizeof(ParamEntry));
-if (siz>0) tab[0].flags=(short)(siz-tab[0].group);
+if (siz>0) tab[0].flags=(paInt)(siz-tab[0].group);
 }
 
