Game Development Community

Dynamic fields - use only for static data

by Alex Rice · in Torque Game Builder · 09/24/2006 (4:34 pm) · 10 replies

I thought I was being all clever by scripting stuff in my t2dSceneObject (sprites etc) like
function MyClass::onSomeEvent( %this )
{
  if(! isObject( %this.items ))
    %this.items = new SimSet();

}

#1
09/24/2006 (4:36 pm)
Oops, posted before finished ...
#2
09/24/2006 (4:39 pm)
The problem with the above code, is that TGB level builder is now so smart that through a series of F5, stop, Ctrl-S, F5, stop, Ctrl-S, to run game, test, edit, save it, the dynamic fields are going to get written to the .t2d file. Which is a recipe for disaster when the value is actually an object's numeric ID as in the %this.items example above.

Suggestion:
The TGB level builder should not write to disk these dynamic field values that represent internal dynamic values such as object ids (what I think of as pointers in torquescript).

My workaround is going to be something like:
function MyClass::onSomeEvent( %this )
{
  if(! isObject($MyClass::items ))
    $MyClass::items = new SimSet();
}
#3
09/24/2006 (6:02 pm)
If you set the "canSaveDynamicFields" to "0" (which equates to false) then you will not have that problem. I've only had this happen to me when I initialized things in an ::onAdd callback. Are you doing that? If that is the case then you don't have to worry because as soon as the object is created the onAdd callback will overwrite those values anyway. I agree that it is very annoying. To circumvent the problem try to pinpoint exactly what is causing them to get added to the level file (vs. "through a series of F5, etc.") and see if there is a different strategy to prevent it. Something I've employed is to use ::onLevelLoaded in some places instead of ::onAdd
#4
09/25/2006 (7:20 am)
Ben thanks- you are probably correct. I was using ::onAdd callbacks until I realized they were called whenever the level file was opened regardless of whether game was running.
#5
09/25/2006 (7:50 am)
I searched for canSaveDynamic fields in torsion and got 981 hits. How are you disabling the save dynamic fields feature of the level editor?

I am still running into trouble even though I'm only using ::onLevelLoaded.
#6
09/25/2006 (8:59 am)
::onAdd are called when the game isn't running because of the way they work. I initially interpreted onAdd as meaning "when added to the leve" but this is actually incorrect. On digging through the docs (and GPGT) a bit I discovered onAdd is actually called as soon as the object is created. That means it is called whether the level is running or not, and even if the object is not part of any level. For instance, I now often use onAdd with ScriptObject as sort of a pseudo constructor.

If your objects already have the fields saved in the level file then changing to onLevelLoaded will not get rid of them. You'll have to manually edit the level file.

canSaveDynamicFields is not a level editor property. It is a field of every single object. If you open your .t2d level file you'll see that ever object has something like
canSaveDynamicFields = "1";
Just change the "1" to a "0" and you won't have those problems anymore. The main drawback is you won't be able to mount things in the level editor anymore. At least you won't be able to mount objects that have that disabled. This is because the level editor assigns an id and references that id in mounts. Since the id is a dynamic field you will have problems. It's not a big deal unless you do a lot of mounting in the editor. Just be aware of it ahead of time so you don't disable dynamic field saving on mounting/mounted objects.
#7
09/25/2006 (1:10 pm)
Thanks Ben- good advice. Do you have any idea how the Level Builder decides which fields to save on-the-fly? The behaviour seems kind of erratic, but probably I just don't understand what's going on under the hood.
#8
09/25/2006 (1:46 pm)
@Ben - That's correct. More specifically, when the object is added to a scenegraph. Since the level builder uses its own scenegraph, the onAdd callback is called when you open a level in the level builder.
#9
09/25/2006 (3:57 pm)
While it may have changed in TGB (check if you get a chance Thomas!), in fact the ::onAdd() callback is part of the adding to the simulation, not even the scenegraph. Unless I'm missing it, from perusing the source code for t2DSceneGraph::addToScene(), there isn't actually a callback for that particular event.
#10
09/25/2006 (6:50 pm)
@Stephen

What you say has proven to be true with empirical tests. I use ::onAdd all the time with ScriptObject types that are never added to the scenegraph.



@Alex

From what I can tell, anything that is a field of the object that is NOT one of the properties in the engine is considered a dynamic field. For instance try this at the console:

$testObject = new t2dStaticSprite() {};
$testObject.dump();

Anything you see in the output of the dump is not a dynamic field and will only be saved in the level editor if it is changed from the default value (what you will see using this example). Anything else will be saved by the level editor as appropriate and considering your setting of that field.