Problem local varaibles in new instances
by Tim Hutcheson · in Torque Game Engine · 04/13/2005 (2:41 pm) · 11 replies
I'm trying to modify the starter.racing game to have a 3 x 10 Starting Grid in which to spawn and restart players. In modifying the mission code, racing.mis, to create the PlayerDropPoints, I wrote the following
new SimGroup(PlayerDropPoints) {
for(%i=0; %i<3; %i++ ) {
for(%j=0; %j<10; %j++ ) {
new SpawnSphere() {
%col = -165.0 + %i*5.0;
%row = 911.136 + %j*10.0;
%elev = 194.677;
position = %col SPC %row SPC %elev;
rotation = "0 0 -1 10.4951";
scale = "1 1 1";
dataBlock = "SpawnSphereMarker";
radius = "1";
sphereWeight = "100";
indoorWeight = "100";
outdoorWeight = "100";
locked = "false";
homingCount = "0";
lockCount = "0";
};
};
};
But the script compiler doesn't seem to allow assigning to any of the local variables I was trying to use in the 'for' loop. %i=0, for example is flag as a syntax error with the ##'s surrounding the % sign. ##%##.
Is this related to restricitions on how objects are created before pcode execution begins and thus disallowed by the compiler? Anyone else use variables in scripts within "new"? I don't see any in the examples yet.
new SimGroup(PlayerDropPoints) {
for(%i=0; %i<3; %i++ ) {
for(%j=0; %j<10; %j++ ) {
new SpawnSphere() {
%col = -165.0 + %i*5.0;
%row = 911.136 + %j*10.0;
%elev = 194.677;
position = %col SPC %row SPC %elev;
rotation = "0 0 -1 10.4951";
scale = "1 1 1";
dataBlock = "SpawnSphereMarker";
radius = "1";
sphereWeight = "100";
indoorWeight = "100";
outdoorWeight = "100";
locked = "false";
homingCount = "0";
lockCount = "0";
};
};
};
But the script compiler doesn't seem to allow assigning to any of the local variables I was trying to use in the 'for' loop. %i=0, for example is flag as a syntax error with the ##'s surrounding the % sign. ##%##.
Is this related to restricitions on how objects are created before pcode execution begins and thus disallowed by the compiler? Anyone else use variables in scripts within "new"? I don't see any in the examples yet.
About the author
#2
for(...)
{
for(...)
{
%col = ....
%row = ...
%elev =...
new SpawnSphere(....)
{
position = %col + ... + %elev;
}
}
}
you'll be also wanting to save the spawnspheres handles in some kind of global array
$spawn[i][j] = new SpawnSphere(...)
04/13/2005 (7:07 pm)
Just try moving the %col, %row & %elev atributions to outside the new command.for(...)
{
for(...)
{
%col = ....
%row = ...
%elev =...
new SpawnSphere(....)
{
position = %col + ... + %elev;
}
}
}
you'll be also wanting to save the spawnspheres handles in some kind of global array
$spawn[i][j] = new SpawnSphere(...)
#3
new SimGroup(PlayerDropPoints) {
%junk = 0;
....
}
produces a similar error.
>>> Advanced script error report. Line 677.
>>> Some error context, with ## on sides of error halt:
};
};
new SimGroup(PlayerDropPoints) {
%junk ##=## 0;
};
04/13/2005 (7:53 pm)
Good idea but the error actually occurs in compiling the first "for" statement. It just dosen't seem tolike the assignment to local vars at object creation time. For example,new SimGroup(PlayerDropPoints) {
%junk = 0;
....
}
produces a similar error.
>>> Advanced script error report. Line 677.
>>> Some error context, with ## on sides of error halt:
};
};
new SimGroup(PlayerDropPoints) {
%junk ##=## 0;
};
#4
However, TorqueScript does allow the creation objects within those brackets (as long as the object associated with the brackets is a container). We see this all the time in missions and GUIs:
I'd suggest:
1. using a loop afterwards to create new object and then use add(), OR
2. using some kind of funtion or method to populate the group, again implementing a loop.
Hall Of Worlds, LLC
EdM|EGTGE
04/13/2005 (8:35 pm)
@Tim - As far as I know, TorqueScript does not allow any kind of assignment within the brackets after a new:new xyz(name) {
// No assigments allowed here.
};However, TorqueScript does allow the creation objects within those brackets (as long as the object associated with the brackets is a container). We see this all the time in missions and GUIs:
new SimGroup(rootGroup) {
new abc();
new SimGroup(subGroup) {
new xyz();
};
};I'd suggest:
1. using a loop afterwards to create new object and then use add(), OR
2. using some kind of funtion or method to populate the group, again implementing a loop.
Hall Of Worlds, LLCEdM|EGTGE
#5
scale = "1 1 1";
But then I realized that racing.mis isn't really TorqueScript, anymore is it? After all it's a .mis file, not .cs file. but then what the heck kind of file is it? Not script, not C++ -- its crypt, as in cryptic. :)
But I'll try some variation of what you suggest as I'm not getting any younger trying to make this work.
Thanks.
04/14/2005 (3:55 am)
Well it is allowing some sort of assignment to be made, as inscale = "1 1 1";
But then I realized that racing.mis isn't really TorqueScript, anymore is it? After all it's a .mis file, not .cs file. but then what the heck kind of file is it? Not script, not C++ -- its crypt, as in cryptic. :)
But I'll try some variation of what you suggest as I'm not getting any younger trying to make this work.
Thanks.
#6
what Edward and me are trying to tell you is that : You cannot create local values inside a new statement.
Doesn't work.
Your code should look like this to work :
04/14/2005 (9:04 am)
Tim,what Edward and me are trying to tell you is that : You cannot create local values inside a new statement.
new Whatever() {
%x = 1;
};Doesn't work.
Your code should look like this to work :
new SimGroup(PlayerDropPoints)
{
};
for(%i=0; %i<3; %i++ )
{
for(%j=0; %j<10; %j++ )
{
%col = -165.0 + %i*5.0;
%row = 911.136 + %j*10.0;
%elev = 194.677;
%SSphere = new SpawnSphere()
{
position = %col SPC %row SPC %elev;
rotation = "0 0 -1 10.4951";
scale = "1 1 1";
dataBlock = "SpawnSphereMarker";
radius = "1";
sphereWeight = "100";
indoorWeight = "100";
outdoorWeight = "100";
locked = "false";
homingCount = "0";
lockCount = "0";
};
PlayerDropPoints.add(%Ssphere); //check method here
};
};
#7
That puts them up at the scope of the new SimGroup(MissionGroup) block and the same problem exist at that scope, doesn't it?
04/14/2005 (9:14 am)
I hear you but the scoping seems odd. The new SpawnSpheres were inside the scope (block) of the new SimGroup(PlayerDropPoints) in the original code and now you are suggesting that they need not be. ??That puts them up at the scope of the new SimGroup(MissionGroup) block and the same problem exist at that scope, doesn't it?
#8
Any assignment of values to previously defined dataBlock fields (basically, anything in your InitPersistFields for that class).
What is not allowed inside the brackets of a new statement:
dynamic creation of TGEScript variables.
A .mis file actually is handled the same as a .cs file (it is TGEScript, it's just given a different extension since it's used for a very specific purpose).
You really shouldn't write code within the mission file unless absolutely critical--and I can't honestly think of a particular situation where it is -required-, except possibly for something like this.
04/14/2005 (9:21 am)
What is allowed inside the brackets of a new statement:Any assignment of values to previously defined dataBlock fields (basically, anything in your InitPersistFields for that class).
What is not allowed inside the brackets of a new statement:
dynamic creation of TGEScript variables.
A .mis file actually is handled the same as a .cs file (it is TGEScript, it's just given a different extension since it's used for a very specific purpose).
You really shouldn't write code within the mission file unless absolutely critical--and I can't honestly think of a particular situation where it is -required-, except possibly for something like this.
#9
And all is ok. Just getting to know the do's and don'ts of the TGE.
Thanks all.
04/14/2005 (9:24 am)
Well of course your right. I see that. And this morning I rewrote the Starting Grid code without loops to give me a set of spawnpoints in an indexed order and x,y locations that maps to the gridded (loop's) code in the game.cs.And all is ok. Just getting to know the do's and don'ts of the TGE.
Thanks all.
#10
1. scale = "1 1 1"; - Does work, but this is because you're telling TorqueScript to add that field (or initialize it since this particular field exists) with the value "1 1 1". This is the purpose of the initializing block.
2. You'll still run into the same problem if you try to make a local/global variable assignment within the MissionGroup initializer block.
Bruno has stated (more clearly) what I was in fact trying to say (Thanks Bruno).
So, seems you're stuck....or are you?
Take a look at any mission file and you'll see something like this:
//--- OBJECT WRITE BEGIN ---
new SimGroup(MissionGroup) {
// ... stuff gets added here
//--- OBJECT WRITE END ---
The part between the two delimitters is a no-mans land for editting purposes. You can edit this, but it will get wiped out the next time you save your mission file (hopefully get rearranged).
If you want to do 'dynamic coding' of the mission as it loads, you can place initializer code before the begin and 'builder' code after the END.
"What do I mean?"
Initializer Code - Any code that does NOT create a mission object. Perhaps in practice you can do this, but I suggest building all mission object after the end marker.
Builder Code - Code that dynamically adds objects to the world.
Words of Warning:
1. I don't think you can use local variables at the file-level. You should experiment and see if TGE complains. Therefore, you'll be better off using builder functions which can contain locals. Note: Try adding brackets around the area you want to use locals, I've not tried that but would love to know if it allows you to use a local at file-level.
2. You may experience some lag between the time you create an object and it actuall gets added to the world. I say may, because I've seen this when executting builder scripts post-mission load. At the time I wondered if this lag would occur if my code ran from the mission file (as it seems you are trying to do). I'd love to hear if you do experience lag, or not. By lag I mean objects suddenly popping into existence after the mission has started.
Here is a sample of code before and after just to be clear (it isn't great, but you'll get the idea):
Please give some feedback on how this works for you if you try it. You'll be helping folks who read this thread in the future. Thanks!
Hall Of Worlds, LLC
EdM|EGTGE
PS - Notice that the %count business does work, because it is local, but scoped by the for loop. However I 'think' (can't check now) that %count = 123; as a line in the file will fail.
04/14/2005 (9:39 am)
@Tim - It seems you're trying to write a dynamically generated mission file, right? i.e. A mission file that executes scripts as it loads. You are correct:1. scale = "1 1 1"; - Does work, but this is because you're telling TorqueScript to add that field (or initialize it since this particular field exists) with the value "1 1 1". This is the purpose of the initializing block.
2. You'll still run into the same problem if you try to make a local/global variable assignment within the MissionGroup initializer block.
Bruno has stated (more clearly) what I was in fact trying to say (Thanks Bruno).
So, seems you're stuck....or are you?
Take a look at any mission file and you'll see something like this:
//--- OBJECT WRITE BEGIN ---
new SimGroup(MissionGroup) {
// ... stuff gets added here
//--- OBJECT WRITE END ---
The part between the two delimitters is a no-mans land for editting purposes. You can edit this, but it will get wiped out the next time you save your mission file (hopefully get rearranged).
If you want to do 'dynamic coding' of the mission as it loads, you can place initializer code before the begin and 'builder' code after the END.
"What do I mean?"
Initializer Code - Any code that does NOT create a mission object. Perhaps in practice you can do this, but I suggest building all mission object after the end marker.
Builder Code - Code that dynamically adds objects to the world.
Words of Warning:
1. I don't think you can use local variables at the file-level. You should experiment and see if TGE complains. Therefore, you'll be better off using builder functions which can contain locals. Note: Try adding brackets around the area you want to use locals, I've not tried that but would love to know if it allows you to use a local at file-level.
2. You may experience some lag between the time you create an object and it actuall gets added to the world. I say may, because I've seen this when executting builder scripts post-mission load. At the time I wondered if this lag would occur if my code ran from the mission file (as it seems you are trying to do). I'd love to hear if you do experience lag, or not. By lag I mean objects suddenly popping into existence after the mission has started.
Here is a sample of code before and after just to be clear (it isn't great, but you'll get the idea):
$test0 = "Torque";
//--- OBJECT WRITE BEGIN ---
new SimGroup(MissionGroup) {
// ... stuff gets added here
//--- OBJECT WRITE END ---
$test1 = "Rocks";
for(%count = 0; %count < 2; %count++) {
echo("\c2Testing -> ", $test[%count]);
}Please give some feedback on how this works for you if you try it. You'll be helping folks who read this thread in the future. Thanks!
Hall Of Worlds, LLCEdM|EGTGE
PS - Notice that the %count business does work, because it is local, but scoped by the for loop. However I 'think' (can't check now) that %count = 123; as a line in the file will fail.
#11
My plan is to have a starting grid that saves the client id and limits the field to twelve players, a 3 x 4 starting grid. (Was bigger but that's only because I thought I would just code a loop in the .mis file to generate spawn points). This also lets me limit the field as players disconnect and go away, with new players picking up their unused grid position, takes care of respawns after accidents (flipping and using ctrl-r), etc.
I'll post the work as mod later on as it seems to really improve the startup conditions and the playability of the racing game in multiplayer mode.
04/14/2005 (9:55 am)
@Edward - Thanks for taking the time to write that exposition on the problem. I see ti all more clearly than last night, that's for sure. I'll try to recreate what I have done this morning by avoiding dynamic coding in the mission file, using what you have said, and post a note about it.My plan is to have a starting grid that saves the client id and limits the field to twelve players, a 3 x 4 starting grid. (Was bigger but that's only because I thought I would just code a loop in the .mis file to generate spawn points). This also lets me limit the field as players disconnect and go away, with new players picking up their unused grid position, takes care of respawns after accidents (flipping and using ctrl-r), etc.
I'll post the work as mod later on as it seems to really improve the startup conditions and the playability of the racing game in multiplayer mode.
Torque Owner Tim Hutcheson
>>> Advanced script error report. Line 677.
>>> Some error context, with ## on sides of error halt:
};
};
new SimGroup(PlayerDropPoints) {
for(##%##i=0; %i<3; %i++ ) {
for(%j=0; %j<10; %j++ ) {
new SpawnSphere() {
>>> Error report complete.