Game Development Community

Modifying the playerdatablock dynamically

by Stefan Lundmark · in Torque Game Engine · 09/17/2004 (10:19 am) · 12 replies

Background to my question
In TGE, I want to make a playerobject open to dynamic modifications from script. Much like done in Tribes, where you can walk into a terminal and change "class", and thus your HP and speed.

I have heard that this simply is not possible with stock TGE, so that brings me to my question. What is the most simple way to do it? I know three ways I can think of.

Kill player, create a new one
When the player walks into the terminal, the object is killed and instantly recreated but with the new datablock instead. Each player has one datablock named after the nickname of the player. And each time the player returns, this is the datablock that is used for the same player.

The problem here is that I haven't heard a way that you can write the datablock file to the disk, in Torque when a new player is created, and how to refresh it while ingame if the player respawns.

Making each value in the datablock tied to a global string
Sounds a bit dirty but it's another thought. As soon as a new player is joining the datablock reads from a number of strings and creates the player based on these.

Like this:
cameraMaxDist					= $maxdist;

Before the player is created, the string is set.
Will this be a problem when spawning more than one player at the same time? Ie. if two players join almost at the same time, will the other player get the same stats as the first one because the string is global?

----------------------------------------------------------------

I can't really think of any other way. And sorry if I'm confusing, don't know the proper terms and words for all this. Any assistance is appreciated here.

#1
09/17/2004 (10:48 am)
Hmmm, well not sure if I am understanding completely here but maybe this would be a partial thought that might help changing some datablock values dynamically. I haven't tested using this function but i have changed datablock values for my project and it so far has worked following similar proceedure.

function changeClass(%client,%newClass)
{
   // %client is the servers ID for the client who is changing and %newClass is the new datablock to use
   %client.player.dataBlock = %newClass;  // I am not sure this will work straight up but can try it
   %client.player.dataBlock.maxDamage = %newClass.maxDamage;  // This should work fine as I have altered several values like this for experience changes
}

Again, not sure if this helps out, but thought I would toss it out just in case. Good luck, and happy coding
#2
09/17/2004 (10:54 am)
@Mark Roberts:

I think this is what I was looking for, actually. I will try it tonight, thanks Mark.
One question though; Will this modify the already existing player (on the given %client) or do I need to respawn it to make the changes take effect?
#3
09/17/2004 (11:03 am)
Should take effect immediately. although I haven't fone a ton with this so far my limited tests have been pretty good with it updating immediately to the server and on ghosting out to any clients that need the data. One thing to try if having issues, use %client.dump(); or %client.player.dump(); and make sure things are looking good once inside the function you are working with. It will save a ton of time debugging if not sure what all options are available. I usually make it a habit now (after way too many hours beating my head guessing) of dumping all variables in a function when I first go in to modify or create anything. =)
#4
09/17/2004 (11:15 am)
Stefan

Dynamically changing a datablock will, AND will not work. Some things can be changed that will take effect immediately and some things cannot be changed once the block has been formed. I recently had a maddening experience where nothing was making sense and it was all because I assumed that all values were updated when a block has changed.

It sounds like what you are trying to do is the equvilent of changing armors in Tribes. If so, I can tell you how they did that, if not, then I'm not sure what it is you are wanting to do.
#5
09/17/2004 (11:37 am)
I think Mark Roberts code will change all of the player's in the game using the same datablock. The way I went around this was to change the c++ code to make maxDamage unique for each Player on the server. And, since i needed the maxDamage value on the client, to only send the value to the client when the value changed.
#6
09/17/2004 (11:48 am)
@Gonzo T. Clown:

Ouch. Could you elaborate a bit on what of these values you were trying to change? On another note: killing the player and respawning it should force the game to check the actual values again, right? This might work as well, as long as it is not visible to the player.

I will try and experiment with this, instead of asking so much questions, I guess :)
What am I trying to achieve? I'm trying to make items and stuff like that, which will apply to your stats when picked up. Like a powerup that makes you 20 damage tougher, or makes you a bit faster - etc etc.

@Blake LaPierre:

Are you sure? He's calling the %client, so it shouldn't affect the others.
#7
09/17/2004 (12:00 pm)
The functionality to do this is already built into Torque. Everything you need to do can be accomplished in script. You want to take a look two things:

setDataBlock()
and
onNewDataBlock

What you want to do is create multiple version of the datablocks. In Tribes for instance they had three different player datablocks to represent the three different classes of armors: light, medium, and heavy.

Any time you want to change an object from one datablock to another you use:
%obj.setDataBlock( MyNewDataBlock );

Whenever an object is created, or its datablock changes eventually it calls onNewDataBlock and eventually has a callback into script. For any values that are 'dynamic' you'll want to update those values in this function. For instance in Tribes games stuff like energy level, energy recharge rate, name, or even skin.
#8
09/17/2004 (1:00 pm)
@Robert
This was what i needed for my game Great !
#9
09/17/2004 (1:30 pm)
@Robert Blanchet Jr.: That will work. But not if you pick up two powerups.

You pick up a "Armor boost". MaxDamage is increased by 5.
You then pick up a "Speed boost" and your speed increases, but at the same time your previous boost will be ignored and reset.
#10
09/17/2004 (4:52 pm)
That's a good point Stefan, glad you caught that. Also, to elaborate about what I was saying earlier, one thing I was having trouble with was mass. I have some kind of issue where if my mass is to high, everything moves in slow motion. So I was trying to lower it slowly to find where the break point was, and nothing was happening. I knew I had it below the point where the slow motion should stop, but it wasn't. When I quit the map, and then came back, everything was fine. Ran a few tests, and sure enough, I cannot alter the mass of an object once it has spawned. Now, about using Robert's setDataBlock function doesn't seem to do it either. I made this function to test settings with and it works the same as before, some things I can change, some I cant.


function changeblock(%client)
{
	
	exec("Server/Scripts/Vehicles/flyer.cs");

	%player = %client.player;
	%vehicle = %player.vehicle;

	%vehicle.setDataBlock("Flyer");
	
}

Just out of curiosity, why do you need to reset the datablock for powerups? Is the application of the bonus not sufficient to cause the desired increase?
#11
10/04/2004 (4:11 pm)
Just wanted to post a followup to this post if anyone is looking at it in the future for reference;

function changeClass(%client,%newClass)
{
%client.player.dataBlock = %newClass;
%client.player.dataBlock.maxDamage = %newClass.maxDamage;
}
The above method sure does modify all the players using the same datablock as the client which you have assigned. This is not a problem in singleplayer games, but in multiplayer games it is.

%obj.setDataBlock( MyNewDataBlock );
This one will work, but only if you have predefined classes, not if you have dynamically changing ones.

All in all. None of these suited me and I've yet to ask Blake LaPierre for advice about his method, so I went with my own. When a user modifies his character, the game creates a new .cs with his name, and inside it his own unique datablock.

I don't like this method, it's just against my way of working.. but it's the only way I could come up with myself.
#12
12/28/2005 (9:41 am)
I'm trying to do make this datablock change in my car using this setDatablock funtion. The car datablock does change, but the car wheels disapear. What should I do to prevent this from hapenning?
Btw, I'm using the starter.racing example car.