Game Development Community

Creating datablock with name from variable

by CEMA, Monash University · in Torque Game Engine · 05/08/2006 (12:04 am) · 7 replies

Is there any good reason that this code does not produce a syntax error:
datablock ProjectileData(MagicMissile) {
      projectileShapeName = "path/to/valid/dtsfile.dts";
   };

but this code does?:
$myName = "MagicMissile";
   datablock ProjectileData($myName) {
      projectileShapeName = "path/to/valid/dtsfile.dts";
   };

The only difference between the two is that the latter evaluates a variable to get the name of the datablock that is created. I don't really understand why this would be a problem for Torquescript.

#1
05/08/2006 (12:12 am)
Because datablocks are compiled DATA. Not compiled CODE.

You cant run any code inside a datablock.

do this:

$myName = "MagicMissile";
eval("datablock ProjectileData($myName) { " @
"projectileShapeName = \"path/to/valid/dtsfile.dts\";" @
"};");

=)
#2
05/08/2006 (12:35 am)
I must respectfully disagree that datablocks are "data", not "code." This looks like code to me:

$path = "gds/data/shapes/agents/agent1.dts";
   datablock ProjectileData(MagicMissile) {
      projectileShapeName = $path;
      foobar = 1 + 1;
   };

I didn't think of using eval, though. Thanks.
#3
05/08/2006 (4:43 am)
Ahh, but putting the foobar = 1 + 1; inside a datablock statement won't work, either.

The actual reason it doesn't work the way you originally thought is because of the way the tokens are parsed--substitution doesn't take place within the name of a datablock automatically, but you can use the eval statement as above to work around this.
#4
05/08/2006 (6:36 am)
Using eval you can build some clever functions for dynamically building datablocks. It's useful when you have to create LOTS of datablocks for things like items, shapeImages, sounds and such.
#5
05/08/2006 (6:45 pm)
Stephen,
Putting the 1 + 1 as the initial value of a field (in this case the field `foobar') does in fact work. From my console.log:
==>datablock ProjectileData(MagicMissile) { projectileShapeName = "gds/data/shapes/agents/agent1.dts"; foobar = 1 + 1; };
==>echo(MagicMissile.foobar);
2
Expressions with variables work fine too. (I would guess that any expression works, therefore.)

Manoel,
I am indeed making multiple datablocks. I have about 10 different projectile types in my game. Each one is identical apart from the projectileShapeName field. The code I would like to write is:
datablock (MyProjectile0) {
  // Lots of fields in here describing my datablock
};

// create the rest of the datablocks...
// Note: This code does not work or even compile - datablock name must be a literal.
for (%i = 1; %i < $numMaterials; %i++) {
  %dbName = "MyProjectile" @ %i;
  datablock (%dbName : MyProjectile0) { projectileShapeName = "myShape" @ %i @ ".dts"; };
  $myProjectileDatas[%i] = %dbName;  // Store the name for later use
}

I ended up using eval because the problem with names as expressions. If a name could be given as a variable, I wouldn't have to use eval to "dynamically" create a datablock - in fact any datablock could be created "dynamically" without resorting to eval if only the name could be an expression. I would like to avoid eval because run-time code generation is an extreme measure IMHO.

Edit: Changed second code block slightly

Nick Sandow
#6
05/09/2006 (7:57 am)
Interesting...let me rephrase then: datablock "blocks" are not guaranteed to perform scripting tasks other than persistent field assignments exactly the same as normal code blocks.

Regarding the "runtime code generation", that's actually quite a standard technique in many scripting languages, not just in Torque/game dev--it's just the nature of scripting languages (specifically script based ones).
#7
05/09/2006 (8:38 am)
Thanks for arguing with me.

Datablocks are DATA. The assignments _may_ be parsed, but I wouldnt recommend it as it isnt garanteed (Have you tried setting a variable not made in script?).

SIDENOTE: Data refers to how something is STORED. Variables are data, but they can be assigned with expressions. The name of a datablock has to be constant because it is SET DATA, i.e. It is not a constant string/expression. (This is probably so you cant put silly things like symbols.)

GG.COM FORUMS DELETED THE NEXT BIT!!!! Grrr!

Also NOTE: Datablocks are part of TorqueScript SYNTAX. They are cheaper to eval than to create manually.

datablock (MyProjectile0) {
  // Lots of fields in here describing my datablock
};

// create the rest of the datablocks...
// Note: This code does not work or even compile - datablock name must be a literal.
for (%i = 1; %i < $numMaterials; %i++) {
  %dbName = "MyProjectile" @ %i;
  eval("datablock (" @ %dbName @ " : MyProjectile0) { " @
 "projectileShapeName = \"" @ "myShape" @ %i @ ".dts" @ "\"; };");
  $myProjectileDatas[%i] = %dbName;  // Store the name for later use
}

There are no cons to eval() anyway.... As TorqueScript is dynamic anyways.