Monitoring Client Position Changes on Server
by Welias D. Willie II · in Torque Game Engine · 08/30/2005 (6:57 pm) · 34 replies
Okay I posted this in the public forum because I thought I could do it all in script...
http://www.garagegames.com/mg/forums/result.thread.php?qt=34003
Stephen Zepp suggested I do this in source code, I am best at scripting but have made many small changes to the source.
I will re-post here to see what source suggestions could help with my problem.
http://www.garagegames.com/mg/forums/result.thread.php?qt=34003
Stephen Zepp suggested I do this in source code, I am best at scripting but have made many small changes to the source.
I will re-post here to see what source suggestions could help with my problem.
About the author
#22
08/31/2005 (10:15 am)
Show us what your script function looks like...after that we'll probably need to start adding in some debugging lines (we'll save using a step-through debugger until later, better to learn echo line debugging first!) to the code to see what is being called when.
#23
Nothing in script could be going wrong as far as I can see.
I am at the office right now, I will jump back into the engine code in a couple of hours.
I prefer echo line debugging
08/31/2005 (10:30 am)
Basically the script function is this: function GameConnection::onChangeCellArea(%this, %lastx, %lasty)
{
// just echo to see if this function is called
echo("**** onChangeCellArea Called with %lastx:" SPC %lastx SPC "and %lasty:" SPC %lasty);
}Nothing in script could be going wrong as far as I can see.
I am at the office right now, I will jump back into the engine code in a couple of hours.
I prefer echo line debugging
#24
For debugging, you can put the following type of line to dump info to the console from code:
Con::printf("This is my debug line");
If you search on the web (or a C++ book/reference), you can find more detailed information of how printf (of which Con::printf is our implementation) to display the values of variables, etc. Something like:
08/31/2005 (10:44 am)
It's possible that you simply aren't ever reaching the method call for checkCellArea(). You might try putting it at the bottom (very bottom, just before the last } ) of updateMove, instead of updatePosition, and see if that happens.For debugging, you can put the following type of line to dump info to the console from code:
Con::printf("This is my debug line");
If you search on the web (or a C++ book/reference), you can find more detailed information of how printf (of which Con::printf is our implementation) to display the values of variables, etc. Something like:
Point3F ourCurPos = getPosition();
Con::printf("Just before call to checkCellArea, cur position is (%f,%f), last position is (%f,%f)!", ourCurPos.x, ourCurPos.y, mLastX, mLastY);can be spammy, but useful.
#25
execute the server in dedicated mode and while watching the console (no clients joining the game) I see basically this:
checkCellArea Position is (0.000000, 5.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 4.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 3.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 2.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 1.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 0.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -1.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -2.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -3.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -4.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -5.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -4.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -3.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -2.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -1.000000), last position is (5.000000, 0.000000)!
and continues repeating the count up and down... it is almost as if the server has a virtual player that roams around in those coordinates.
By the way, I moved the call to checkCellArea(); to the bottom of updateMove() as you suggested, haven't tested to see if that corrected the problem. I am thinking there is a problem with the math at this point. why is the last position always 5,0 when if you read the code snippet above, mlastx and mlasty should already be set to the exact same as int(x/100) and int(y/100).... it doesn't appear as mlastX and mlastY are retaining their values.
08/31/2005 (4:05 pm)
This is interesting...void Player::checkCellArea()
{
// Checks to see if the player has moved to a new Cell Area...
Point3F pos;
getTransform().getColumn(3, &pos);
if (int(pos.x/100) != mlastX || int(pos.y/100) != mlastY)
{
mlastX = int(pos.x/100);
mlastY = int(pos.y/100);
Con::executef(this,3,"onChangeCellArea",scriptThis(), mlastX, mlastY);
Con::printf("checkCellArea Position is (%f,%f), last position is (%f,%f)!", int(pos.x/100), int(pos.y/100), mlastX, mlastY);
}
}execute the server in dedicated mode and while watching the console (no clients joining the game) I see basically this:
checkCellArea Position is (0.000000, 5.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 4.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 3.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 2.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 1.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, 0.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -1.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -2.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -3.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -4.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -5.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -4.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -3.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -2.000000), last position is (5.000000, 0.000000)!
checkCellArea Position is (0.000000, -1.000000), last position is (5.000000, 0.000000)!
and continues repeating the count up and down... it is almost as if the server has a virtual player that roams around in those coordinates.
By the way, I moved the call to checkCellArea(); to the bottom of updateMove() as you suggested, haven't tested to see if that corrected the problem. I am thinking there is a problem with the math at this point. why is the last position always 5,0 when if you read the code snippet above, mlastx and mlasty should already be set to the exact same as int(x/100) and int(y/100).... it doesn't appear as mlastX and mlastY are retaining their values.
#26
with the proper info in player.h and this code:
everything is reporting proper numbers to the console. The problem now is, for some reason I have to use (%d,%d) instead of (%f,%f) in the printf for the numbers to return properly, %f,%f just returns zeros.
I still can't get the Con::executef() to work.
08/31/2005 (5:17 pm)
Ok the latest is... I had lastx and lasty defined twice in player.h, as well I had them defined as F32 when they should have been short int so that the math would work easily. Once I corrected the definitions in player.h the positions, are now being saved, as far as I can tell, within the engine as mlastx and mlasty. Of course the trick will be to see if I can get this to actually pass those values to script.with the proper info in player.h and this code:
void Player::checkCellArea()
{
// Checks to see if the player has moved to a new Cell Area...
Point3F pos;
getTransform().getColumn(3, &pos);
if ((short int(pos.x/100)) != mlastX || (short int(pos.y/100)) != mlastY)
{
Con::printf("checkCellArea Position is (%d,%d), last position is (%d,%d)", (short int(pos.x/100)), (short int(pos.y/100)), mlastX, mlastY);
Con::executef(this,3,"onChangeCellArea",scriptThis(), mlastX, mlastY);
mlastX = (short int(pos.x/100));
mlastY = (short int(pos.y/100));
}
}everything is reporting proper numbers to the console. The problem now is, for some reason I have to use (%d,%d) instead of (%f,%f) in the printf for the numbers to return properly, %f,%f just returns zeros.
I still can't get the Con::executef() to work.
#27
08/31/2005 (7:11 pm)
I can't control the data types. I am getting floating numbers when I specify short int, or I am just going crazy. I need to take a class on C++.
#28
You don't happen to be running the standard mission w/ the bot, are you?
:)
09/03/2005 (11:12 pm)
Quote:
and continues repeating the count up and down... it is almost as if the server has a virtual player that roams around in those coordinates.
You don't happen to be running the standard mission w/ the bot, are you?
:)
#29
However, I still have an issue with:
It seems the above code is not actually calling onChangeCellArea in script. Here is my function in script:
Note: I have this function in \game\server\scripts\game.cs
09/04/2005 (6:34 am)
I am embarrassed! Sometimes it is the simplest things.However, I still have an issue with:
Con::executef(this,3,"onChangeCellArea",scriptThis(), mlastX, mlastY);
It seems the above code is not actually calling onChangeCellArea in script. Here is my function in script:
function GameConnection::onChangeCellArea(%this, %lastx, %lasty)
{
// just echo to see if this function is called
echo("**** onChangeCellArea Called with %lastx:" SPC %lastx SPC "and %lasty:" SPC
%lasty);
}Note: I have this function in \game\server\scripts\game.cs
#30
to:
09/04/2005 (7:19 am)
Change:Con::executef(this,3,"onChangeCellArea",scriptThis(), mlastX, mlastY);
to:
Con::executef(this,4,"onChangeCellArea",scriptThis(), mlastX, mlastY);
#31
However, I tried it again to verify and it still does nothing.
09/04/2005 (7:41 am)
I had already tried:Con::executef(this,4,"onChangeCellArea",scriptThis(), mlastX, mlastY);
However, I tried it again to verify and it still does nothing.
#32
09/04/2005 (9:14 am)
Well, the correct syntax is still with 4 in it :) As the function is considered a argument too.
#33
Look at updatePos() in player.cc.
You'll find this:
So add a little else statement there, and depending on whether you want the server or the client to know that the position has changed make sure you add isServerObject or isClientObject appropriately. For example, if I want to notify the server in script that the player's position has changed I would do this:
EDIT: I just noticed that you wanted to see if the player moved a certain amount of distance - not if he/she just moved. So I need to explain something a little extra. Since the client has to interpolate every tick and updatePos is called on both Server and Client, we can still use the interpolation data to see how much a client has moved per tick. That is, we can see how much he's moved on the server in a 32 ms timeslot. At this point in the code, delta.pos contains the original position, start contains the NEW position (confusing - I know). So with a little edit...
And in your player.cs (or wherever you store your player methods)
Add this:
I haven't tested this - but I think it might work ;).
- Eric
09/04/2005 (9:17 am)
IMHO I think you guys are complicating things a little too much.Look at updatePos() in player.cc.
You'll find this:
if (count == sMoveRetryCount)
{
// Failed to move
start = initialPosition;
mVelocity.set(0,0,0);
}So add a little else statement there, and depending on whether you want the server or the client to know that the position has changed make sure you add isServerObject or isClientObject appropriately. For example, if I want to notify the server in script that the player's position has changed I would do this:
EDIT: I just noticed that you wanted to see if the player moved a certain amount of distance - not if he/she just moved. So I need to explain something a little extra. Since the client has to interpolate every tick and updatePos is called on both Server and Client, we can still use the interpolation data to see how much a client has moved per tick. That is, we can see how much he's moved on the server in a 32 ms timeslot. At this point in the code, delta.pos contains the original position, start contains the NEW position (confusing - I know). So with a little edit...
if (count == sMoveRetryCount)
{
// Failed to move
start = initialPosition;
mVelocity.set(0,0,0);
}
else
{
//Notify the server we've changed position
Point3F dist = start - delta.pos;
if(dist.len() >= Yourdistancehere)
Con::executef(this, 2, "notifyPositionChange", scriptThis());
}And in your player.cs (or wherever you store your player methods)
Add this:
function Player::notifyPositionChange(%this)
{
//Do whatever you need to do here
}I haven't tested this - but I think it might work ;).
- Eric
#34
In the Con::executef(..); call, the first variable (this) is the object used to know what namespace to look in. In your case (IIRC), "this" is a Player object, and therefore your script method needs to be in the Player:: namespace.
Try changing it to Player::onChangeCellArea() and see what happens.
09/06/2005 (12:12 pm)
Punky: Your problem is a namespace error: you are trying to call the script method in the Player:: namespace, but you've defined it in the GameConnection:: namespace.In the Con::executef(..); call, the first variable (this) is the object used to know what namespace to look in. In your case (IIRC), "this" is a Player object, and therefore your script method needs to be in the Player:: namespace.
Try changing it to Player::onChangeCellArea() and see what happens.
Torque Owner Stefan Lundmark