Updating some Torque fields has no affect?!
by CSUMB (#0032) · in Torque Game Engine · 02/17/2005 (9:24 pm) · 13 replies
Hi,
I've been playing around with the Torque Scripting language for a
a couple of weeks. I have a question/observation.
What is the relationship of datablock fields and instances of objects?
Can fields in the datablocks be changed in the object?
For example,:
In the tutorial.base example, when I create the
datablock PlayerDataBlock(PlayerShape)
{
. . . .
runSurfaceAngle = 20;
. . . .
}
I can set the default of the fields, for example, above, the runSurfaceAngle
field = 20. (i.e. the angle that the player can run up)
Later, I will declare a new Player -- that uses a PlayerShape datablock,
so it is initialized with the runSurfaceAngle field (20) above. However,
if I try to dynamically change this "runSurfaceAngle" field somewhere in
the script, nothing happens, the game engine ignores the fact that
runSurfaceAngle has changed --- so I can't allow my player to run
up angles greater than 20 degrees.
What can I do? Are some fields static in the engine and cannot be
changed? if so, how do I know how to tell which fields are static
and which fields are dynamic? I'm quite confused about this.
Help is greatly appreciated.
-Michael
I've been playing around with the Torque Scripting language for a
a couple of weeks. I have a question/observation.
What is the relationship of datablock fields and instances of objects?
Can fields in the datablocks be changed in the object?
For example,:
In the tutorial.base example, when I create the
datablock PlayerDataBlock(PlayerShape)
{
. . . .
runSurfaceAngle = 20;
. . . .
}
I can set the default of the fields, for example, above, the runSurfaceAngle
field = 20. (i.e. the angle that the player can run up)
Later, I will declare a new Player -- that uses a PlayerShape datablock,
so it is initialized with the runSurfaceAngle field (20) above. However,
if I try to dynamically change this "runSurfaceAngle" field somewhere in
the script, nothing happens, the game engine ignores the fact that
runSurfaceAngle has changed --- so I can't allow my player to run
up angles greater than 20 degrees.
What can I do? Are some fields static in the engine and cannot be
changed? if so, how do I know how to tell which fields are static
and which fields are dynamic? I'm quite confused about this.
Help is greatly appreciated.
-Michael
About the author
#2
It is really strange. I couldn't imagine someone designing a game
engine where the variables are all static at startup.
I read some other forums and tried something like this:
if (%col.getClassName() == "Player")
{
%h = %this; //%this is a Player Datablock
%h.runSurfaceAngle = 90;
%col.setDataBlock( %h );
}
So I tried to "reset" %col (players) datablock to 90, via a calling
a new datablock. No luck!
02/18/2005 (9:30 am)
Thanks Jeremy,It is really strange. I couldn't imagine someone designing a game
engine where the variables are all static at startup.
I read some other forums and tried something like this:
if (%col.getClassName() == "Player")
{
%h = %this; //%this is a Player Datablock
%h.runSurfaceAngle = 90;
%col.setDataBlock( %h );
}
So I tried to "reset" %col (players) datablock to 90, via a calling
a new datablock. No luck!
#3
datablock PlayerData( goingUpPlayer : PlayerShape )
{
runSurfaceAngle = 90;
};
// somewhere else
%obj.setDataBlock( "goingUpPlayer" ); // now he will have the values
of runSurfaceAngle.
Strange way to do it, but it works.
02/18/2005 (9:34 am)
OK, I see that I can make another datablock and change it like this:datablock PlayerData( goingUpPlayer : PlayerShape )
{
runSurfaceAngle = 90;
};
// somewhere else
%obj.setDataBlock( "goingUpPlayer" ); // now he will have the values
of runSurfaceAngle.
Strange way to do it, but it works.
#4
Since a very large majority of common data actually is static, it makes sense to use a datablock as a common reference point for a class of objects--you only have to transmit it once across the net for each client, and each object using that datablock uses that datablock--they are shared. In other words, any time you change a value in a datablock (and it can be done, just isn't intended to be done commonly), it will change for every single object that references the datablock.
If you have fields that actually do require dyamic and/or object dependent values, add them to the object itself, not he datablock, and then do the appropriate things for network transmission (initPersistentFields, pack/unpack, initializion in the constructor/onAdd() as appropriate).
02/18/2005 (9:43 am)
The concept of a datablock is a bit unusual to many people (I know it was for me), but it is designed specifically to be static--because when it comes down to it, behaviour of a class of objects is mostly the same across the entire property set of the objects.Since a very large majority of common data actually is static, it makes sense to use a datablock as a common reference point for a class of objects--you only have to transmit it once across the net for each client, and each object using that datablock uses that datablock--they are shared. In other words, any time you change a value in a datablock (and it can be done, just isn't intended to be done commonly), it will change for every single object that references the datablock.
If you have fields that actually do require dyamic and/or object dependent values, add them to the object itself, not he datablock, and then do the appropriate things for network transmission (initPersistentFields, pack/unpack, initializion in the constructor/onAdd() as appropriate).
#5
Or does this kind of thing exclusively require digging into the C++ source code? I'm not afraid of doing that, but it seems cumbersome and extreme when there's a nice scripting engine available.
02/18/2005 (9:46 am)
Couldn't you add a dynamic field to the player object (in script) and keep the information there?Or does this kind of thing exclusively require digging into the C++ source code? I'm not afraid of doing that, but it seems cumbersome and extreme when there's a nice scripting engine available.
#6
I have no trouble adding dynamic fields, the problem is with
fields defined in the datablocks -- and I definitely see the
benefits in the static datablocks.
Stephen, did you see my post before yours? I am able to change
an objects static datablock to another _static_ datablock (See code below).
My understanding is that only the "%obj" instance that sets
updates %obj.setDataBlock( "goingUpPlayer" ) will be affected by this
change?
Is this more in-line with how Torque intends me to update
a object's fields? This works well for me, it is just that I can
forsee that in some cases I will need to create a lot of datablocks
to achieve a desired task -- which could be done more easy if I just
dynamically changed the datablock's field.
I'm not trying to judge if it is wrong or right -- doesn't matter really --
( if I want to change it I could write my own game engine I guess), I
just want to make sure I'm doing this correctly and thinking about it
the right way before I undergo a lot of coding.
Best -Michael
--------------------------------------------------------------------------------------
datablock PlayerData( goingUpPlayer : PlayerShape )
{
runSurfaceAngle = 90;
};
// somewhere else
%obj.setDataBlock( "goingUpPlayer" ); // now he will have the values
02/18/2005 (12:10 pm)
Hi Stephen and Jason,I have no trouble adding dynamic fields, the problem is with
fields defined in the datablocks -- and I definitely see the
benefits in the static datablocks.
Stephen, did you see my post before yours? I am able to change
an objects static datablock to another _static_ datablock (See code below).
My understanding is that only the "%obj" instance that sets
updates %obj.setDataBlock( "goingUpPlayer" ) will be affected by this
change?
Is this more in-line with how Torque intends me to update
a object's fields? This works well for me, it is just that I can
forsee that in some cases I will need to create a lot of datablocks
to achieve a desired task -- which could be done more easy if I just
dynamically changed the datablock's field.
I'm not trying to judge if it is wrong or right -- doesn't matter really --
( if I want to change it I could write my own game engine I guess), I
just want to make sure I'm doing this correctly and thinking about it
the right way before I undergo a lot of coding.
Best -Michael
--------------------------------------------------------------------------------------
datablock PlayerData( goingUpPlayer : PlayerShape )
{
runSurfaceAngle = 90;
};
// somewhere else
%obj.setDataBlock( "goingUpPlayer" ); // now he will have the values
#7
The main problem with doing things in script is that there is no clean way to transmit script variables across a net connection except for cmdToServer/cmdToClient. When it is a coded object variable (c++), it's all handled automatically (if of course you put it into pack/unpack).
Finally yes, %obj.setDataBlock() should work fine, but make sure that you are doing that server side, and IIRC you may need to confirm that change is propagated to the client(s) before trusting that it works as intended.
BTW, there is at least one other thread on the forums recently regarding this topic...something along the lines of "swapping datablocks on the fly".
02/18/2005 (2:42 pm)
What I was getting at is if you have a field like this that is going to change often, don't use it as a datablock reference--make the variable in the player object itself, instead of the datablock. That makes much more sense then messing with tons of datablock swaps just to be able to modify a value for a particular player.The main problem with doing things in script is that there is no clean way to transmit script variables across a net connection except for cmdToServer/cmdToClient. When it is a coded object variable (c++), it's all handled automatically (if of course you put it into pack/unpack).
Finally yes, %obj.setDataBlock() should work fine, but make sure that you are doing that server side, and IIRC you may need to confirm that change is propagated to the client(s) before trusting that it works as intended.
BTW, there is at least one other thread on the forums recently regarding this topic...something along the lines of "swapping datablocks on the fly".
#8
sorry if i seem really thick here . . . still trying to get this figured out.
You mean, if I _don't_ declare this variable in the datablock, then
it will be dynamic when I actually create the object?
I guess I'm a little confused, because this varialbe is already being
used in the tutorial.base, I _assumed_ it is a field already associated with
the datablock PlayerData, and must be defined otherwise it will be
assigned whatever the default value of in the game engine is.
So, if I understand what you are saying, if I simple remove this item
from the PlayerShape datablock, and then make sure to define it when
I create a Player (or AIPlayer), the I'll be able to dynamically change
the "runSurfaceAngle" variable?
I really do appreciate your help. . .
I did read the thread "swapping datablocks on the fly" that is how
a learned the trick above, but I still found it a bit of a hack.
02/18/2005 (6:03 pm)
Stephen,sorry if i seem really thick here . . . still trying to get this figured out.
You mean, if I _don't_ declare this variable in the datablock, then
it will be dynamic when I actually create the object?
I guess I'm a little confused, because this varialbe is already being
used in the tutorial.base, I _assumed_ it is a field already associated with
the datablock PlayerData, and must be defined otherwise it will be
assigned whatever the default value of in the game engine is.
So, if I understand what you are saying, if I simple remove this item
from the PlayerShape datablock, and then make sure to define it when
I create a Player (or AIPlayer), the I'll be able to dynamically change
the "runSurfaceAngle" variable?
I really do appreciate your help. . .
I did read the thread "swapping datablocks on the fly" that is how
a learned the trick above, but I still found it a bit of a hack.
#10
This is a public forum, so I cannot give example code here, but if you look at player.h for example, you'll see two major definitions: one for struct PlayerData: public ShapeBaseData and one for class Player: public ShapeBase. Variables declared in the former (and referenced via playerObject->mDataBlock->xxxx ) are datablock variables, and ones declared in the latter (and referenced via playerObject->xxxx) are player variables--which are unique to each instance of the object.
My suggestion is that you use the first area for static values that "define" your player's attributes (from physics to animations, and all points in between), and use the second for variables that have values unique to each player object, and are known/expected to be fully dynamic. An obvious example is the mFalling boolean. Each player object needs it's own variable space to track this state since it's so dynamic...so it's in the Player object definition, not the datablock definition.
02/18/2005 (6:26 pm)
No, what I am saying is that there are two places to define a variable for a player: in the player's datablock (which is normally static, and shared amongst -all- objects that use that datablock), and in the player itself. Both of these are in code, not script.This is a public forum, so I cannot give example code here, but if you look at player.h for example, you'll see two major definitions: one for struct PlayerData: public ShapeBaseData and one for class Player: public ShapeBase. Variables declared in the former (and referenced via playerObject->mDataBlock->xxxx ) are datablock variables, and ones declared in the latter (and referenced via playerObject->xxxx) are player variables--which are unique to each instance of the object.
My suggestion is that you use the first area for static values that "define" your player's attributes (from physics to animations, and all points in between), and use the second for variables that have values unique to each player object, and are known/expected to be fully dynamic. An obvious example is the mFalling boolean. Each player object needs it's own variable space to track this state since it's so dynamic...so it's in the Player object definition, not the datablock definition.
#11
Thanks again for your answer. I guess I didn't make it clear, I _only_ want to
work within the Script. The "player.h" is part of the standard unmodified
Torque engine and that is what I am working with. I don't plan on making
any changes to the actual engine's source code, my goal is to implement
everything in the scripting portion.
I have a much better understanding now of what Torque is using datablocks for, it makes a lot of sense. I did take a look at the source code and
see what you are talking about.
So, if I am in the Scripting language only, do you think the approach I
am doing now is reasonable -- defining multiple datablocks and swapping
them? Or is there a better way to do this in the Scripting portion of the
game engine?
02/18/2005 (7:06 pm)
Hi Stephen,Thanks again for your answer. I guess I didn't make it clear, I _only_ want to
work within the Script. The "player.h" is part of the standard unmodified
Torque engine and that is what I am working with. I don't plan on making
any changes to the actual engine's source code, my goal is to implement
everything in the scripting portion.
I have a much better understanding now of what Torque is using datablocks for, it makes a lot of sense. I did take a look at the source code and
see what you are talking about.
So, if I am in the Scripting language only, do you think the approach I
am doing now is reasonable -- defining multiple datablocks and swapping
them? Or is there a better way to do this in the Scripting portion of the
game engine?
#12
You could mimic what the networking code does, and use cmdToServer/cmdToClient to set and update script variables, but this will become very cumbersome very quickly.
02/18/2005 (7:15 pm)
Given your (self-imposed) restrictions, this is probably your best route.You could mimic what the networking code does, and use cmdToServer/cmdToClient to set and update script variables, but this will become very cumbersome very quickly.
#13
the idea of using static datablocks, this will force me to clearly define
all the states I'd like my character to be able to have.
I'll check out the cmdToServer/cmdToClient.
I really appreciate your prompt replies, saved me a lot of headaches.
02/18/2005 (7:30 pm)
Thanks, I am imposing the restriction. Actually, I'm starting to likethe idea of using static datablocks, this will force me to clearly define
all the states I'd like my character to be able to have.
I'll check out the cmdToServer/cmdToClient.
I really appreciate your prompt replies, saved me a lot of headaches.
Torque Owner Jeremy Alessi