Vehicles motion Jerky
by Howard Dortch · in Torque Game Engine · 04/30/2007 (7:57 am) · 31 replies
Stock torque 1.5 starter.racing create a server and have a client join. Each player sees the other player vehicle. When you watch the other player the buggy movement seems to jerk. Any way to fix this?
#2
$pref::Net::PacketRateToClient = "32";
$pref::Net::PacketRateToServer = "32";
$pref::Net::PacketSize = "450";
All better...but I doubt it could work over dialup for internet play. Hmmm not sure, actually...
05/10/2007 (11:06 pm)
Go into client/prefs.cs and set these values:$pref::Net::PacketRateToClient = "32";
$pref::Net::PacketRateToServer = "32";
$pref::Net::PacketSize = "450";
All better...but I doubt it could work over dialup for internet play. Hmmm not sure, actually...
#3
packetRateToClient = 32 is that 32 ms per packet or 32 packets per second ?
05/11/2007 (5:47 am)
I did that Lee, no change. And it brings up a questionpacketRateToClient = 32 is that 32 ms per packet or 32 packets per second ?
#4
32 means the packet rate per second sent by the server to the client - each one with 450 bytes of data to stay at the example above. Means: 32 * 450 bytes = 14400 bytes per second from server to client at a constant rate. If you need higher packet sizes than 450 you need to patch the engine (hardcoded limit).
05/11/2007 (7:00 am)
Set those prefs above in the defaults.cs and they will be in constantly. prefs.cs is runtime-generated and should not be in your game package once you deliver. 32 means the packet rate per second sent by the server to the client - each one with 450 bytes of data to stay at the example above. Means: 32 * 450 bytes = 14400 bytes per second from server to client at a constant rate. If you need higher packet sizes than 450 you need to patch the engine (hardcoded limit).
#5
Dam, long time no see Howard!! Drop me a line, can't find your email anymore.
packetRateToClient is 32 packets per second.
This value is the max rate. After going though the code a bit, it ends up assigned to mCurRate.updateDelay.
which is ised in
05/11/2007 (7:08 am)
@HowardDam, long time no see Howard!! Drop me a line, can't find your email anymore.
packetRateToClient is 32 packets per second.
pref::Net::PacketRateToClient maps to gPacketRateToClient U32 toClientUpdateDelay = 1024 / gPacketRateToClient;
This value is the max rate. After going though the code a bit, it ends up assigned to mCurRate.updateDelay.
which is ised in
void NetConnection::checkPacketSend(bool force)
U32 curTime = Platform::getVirtualMilliseconds();
U32 delay = isConnectionToServer() ? gPacketUpdateDelayToServer : mCurRate.updateDelay;
if(!force)
{
if(curTime < mLastUpdateTime + delay - mSendDelayCredit)
return;
.
.
.
#6
@Simon, so there you are... sent message via you email from here, I had a major system crash and lost your mail too.
05/11/2007 (7:46 am)
@Martin thanks will give that a go.@Simon, so there you are... sent message via you email from here, I had a major system crash and lost your mail too.
#7
05/11/2007 (11:07 am)
@Martin it is a little better that way but not as smothe move as it should be, thanks for the info.
#8
I'm getting some MAJORLY jerky motion out of my flying vehicles. This is mainly apparent when doing pitching maneuvers, and doesn't seem to happen in the Flying Starter kit that my stuff is [retroactively] based on. I have changed the Flying Vehicle AI a bit (has to work in Space, no friction), but I haven't touched the networking stuff. Even with only 4 or 5 AI ships in the system, they are "popping" like crazy. Upping these settings has helped, but I really don't think this should or is the problem. Looking at the net stat display, we're seeing the number of ghost updates go down as the number of ghosts goes up- is this supposed to be updates PER ghost, or total updates?
Anyway, the AI code works as it should- the popping is not caused directly by getAIMove (as can be seen with only a single ship or two in the system). Obviously other people have run into this, and I doubt there's a single solution; what strategies have you employed to make this work?
11/09/2008 (11:18 pm)
I'm a fan of gravedigging when the question is fundamentally the same; please correct me if this is frowned on!I'm getting some MAJORLY jerky motion out of my flying vehicles. This is mainly apparent when doing pitching maneuvers, and doesn't seem to happen in the Flying Starter kit that my stuff is [retroactively] based on. I have changed the Flying Vehicle AI a bit (has to work in Space, no friction), but I haven't touched the networking stuff. Even with only 4 or 5 AI ships in the system, they are "popping" like crazy. Upping these settings has helped, but I really don't think this should or is the problem. Looking at the net stat display, we're seeing the number of ghost updates go down as the number of ghosts goes up- is this supposed to be updates PER ghost, or total updates?
Anyway, the AI code works as it should- the popping is not caused directly by getAIMove (as can be seen with only a single ship or two in the system). Obviously other people have run into this, and I doubt there's a single solution; what strategies have you employed to make this work?
#10
11/10/2008 (8:40 am)
This is over a local connection of all things! If I have only a single vehicle in the game, the effect is minimal, but any more than that is terrible.
#11
Sorry... couldn't help it. Vehicles definitely fall prey to lag/warping in network play. This kind of thing is not so noticeable with FPS player characters, which is what the TGE network code was really designed for. But if you play Fallen Empires: Legions on InstantAction, you can see pretty quickly that even an FPS game (with no vehicles) based on the TGE network code gets laggy/warpy and pretty unplayable much of the time (especially for a game that requires precise shooting/targetting that depends on the characters' real-time momentum). But then again, most online FPS games fall prey to this same thing. Tribes 2 had vehicles - back when TGE code might have been winning actual "awards", and it's vehicles suffered from all kinds of warp/lag issues, and collision/penetration issues with the static terrain and environment objects... but we played anyway.
We had to rip out the network code for our single-player racing game because, with one player and 5 AI racers, on a local connection (i.e. single computer), the warping/lagging and collision issues make it completely unacceptable. We tweaked all network packet size/speed settings, etc., and none of it helped. Besides, the collision code in TGE isn't really designed to work with vehicle-to-vehicle collision (i.e., moving-object-to-moving-object collision) - it's designed for player-to-static-object collision and even that has it's issues that have to be fixed.
Sorry to not be of much help...
11/10/2008 (9:05 am)
Maybe it's the "Award-Winning Network Code"... LOL.Sorry... couldn't help it. Vehicles definitely fall prey to lag/warping in network play. This kind of thing is not so noticeable with FPS player characters, which is what the TGE network code was really designed for. But if you play Fallen Empires: Legions on InstantAction, you can see pretty quickly that even an FPS game (with no vehicles) based on the TGE network code gets laggy/warpy and pretty unplayable much of the time (especially for a game that requires precise shooting/targetting that depends on the characters' real-time momentum). But then again, most online FPS games fall prey to this same thing. Tribes 2 had vehicles - back when TGE code might have been winning actual "awards", and it's vehicles suffered from all kinds of warp/lag issues, and collision/penetration issues with the static terrain and environment objects... but we played anyway.
We had to rip out the network code for our single-player racing game because, with one player and 5 AI racers, on a local connection (i.e. single computer), the warping/lagging and collision issues make it completely unacceptable. We tweaked all network packet size/speed settings, etc., and none of it helped. Besides, the collision code in TGE isn't really designed to work with vehicle-to-vehicle collision (i.e., moving-object-to-moving-object collision) - it's designed for player-to-static-object collision and even that has it's issues that have to be fixed.
Sorry to not be of much help...
#12
Which makes me wonder (can't test right now)- but would the Integration settings have any effect on this? Currently I'm at the stock 6, but maybe the client and the server are getting out of sync doing the integration. I don't need incredible accuracy, I just need things to move smoothly (at least consistently in the same direction instead of jumping around like a hyperactive hamster). Anybody tried this?
I'd like to just run down my understanding of the whole ghost and update process, so that maybe I can at least identify where to look. I'll deal with run-time only:
1. You create an object on the Server.
2. It is sent to the client using InitialUpdateMask.
3. Client creates a ghost object.
4. Server runs the physics simulation (updateMove and updateForces)
5. Client does the same + renders object
6. Client displays its results.
7. Server sends client its results; client [Does extrapolation] | [sets the ghosts to match server]
8. Mismatches result in jumps.
9. This process is done even over a local connection.
Does the client do anything with getAIMove? Is that code run on both or only on the Server? Could that cause the mismatches?
11/10/2008 (9:17 am)
The darn thing of it is that looking at the vehicle network code, I don't think they are sending that much more data down the pipe vs. a player object. Vehicles have a much more involved physics simulation, but that is a CPU process, not a network one, which boils down to the same transform matrix in the end.Which makes me wonder (can't test right now)- but would the Integration settings have any effect on this? Currently I'm at the stock 6, but maybe the client and the server are getting out of sync doing the integration. I don't need incredible accuracy, I just need things to move smoothly (at least consistently in the same direction instead of jumping around like a hyperactive hamster). Anybody tried this?
I'd like to just run down my understanding of the whole ghost and update process, so that maybe I can at least identify where to look. I'll deal with run-time only:
1. You create an object on the Server.
2. It is sent to the client using InitialUpdateMask.
3. Client creates a ghost object.
4. Server runs the physics simulation (updateMove and updateForces)
5. Client does the same + renders object
6. Client displays its results.
7. Server sends client its results; client [Does extrapolation] | [sets the ghosts to match server]
8. Mismatches result in jumps.
9. This process is done even over a local connection.
Does the client do anything with getAIMove? Is that code run on both or only on the Server? Could that cause the mismatches?
#13
The client and server both do the full simulation of the objects, and then the client's estimate is effectively discarded when a packet comes in from the server to update the object to it's correct location - when the server's update differs significantly from the clients estimate, there's a visible "warp". If this happens a bit every tick, and the accuracy is constantly varying, then there is visible "jitter". For AI objects, since there are no human "input device" based moves (which can't be predicted accurately), the simulation should theoretically match up very well, assuming the client produces moves the exact same way as the server... but for some reason, it doesn't appear to work that way. Even when the sim is matching up pretty well between the client and the server, once an object is moving at significant speed, it sees other objects' collision boxes as being ahead of their render location, so collision doesn't work correctly on-screen (i.e., you drive behind another vehicle and overlap the render shapes, but get no collision until you reach a significant overlap).
There have been quite a few threads on these problems... and unfortunately, none (that I have found) have come to any significant resolution. Look for "vehicle collision" or such in the forum threads...
11/10/2008 (9:44 am)
Integration is done as part of the "per tick" code to improve the accuracy of the physics simulation. It shouldn't have much bearing on the networking, except that it can cause the simulation to take a lot of time to compute... then the simulation has to be advanced multiple ticks to "catch up". With any significant art in your missions, it's likely that the "catch up" situation will be happening quite a bit (rendering + simulation taking more than 32 milliseconds).The client and server both do the full simulation of the objects, and then the client's estimate is effectively discarded when a packet comes in from the server to update the object to it's correct location - when the server's update differs significantly from the clients estimate, there's a visible "warp". If this happens a bit every tick, and the accuracy is constantly varying, then there is visible "jitter". For AI objects, since there are no human "input device" based moves (which can't be predicted accurately), the simulation should theoretically match up very well, assuming the client produces moves the exact same way as the server... but for some reason, it doesn't appear to work that way. Even when the sim is matching up pretty well between the client and the server, once an object is moving at significant speed, it sees other objects' collision boxes as being ahead of their render location, so collision doesn't work correctly on-screen (i.e., you drive behind another vehicle and overlap the render shapes, but get no collision until you reach a significant overlap).
There have been quite a few threads on these problems... and unfortunately, none (that I have found) have come to any significant resolution. Look for "vehicle collision" or such in the forum threads...
#14
I'll keep looking, of course- maybe the sum of many smaller changes will effect some change. I know of several things that I could strip out of the networking - stuff dealing with waterblocks and lift-off and terrain and whatnot (space game), but over a local connection I just don't think that it's bandwidth starved.
What it looks like is the ships are moving around - yawing and pitching- smoothly for maybe .5 seconds and then get warped back to their starting point. It's like the server is not agreeing that they need to be turning, or it's coming up with an entirely different turn rate. My only idea is that something happened when I moved this rate from the datablock into the object itself (with a new update mask). It seems to be working just fine, but I will go back and double check this in a debugger.
11/10/2008 (9:54 am)
Thank you Eddie. I have been looking for just those sorts of threads. The one in this forum about the vehicle collision handling has helped enormously- but only for collision handling. The jitter and jerk is still there, unchanged after the updated collision handling code was put in, as it well should be!I'll keep looking, of course- maybe the sum of many smaller changes will effect some change. I know of several things that I could strip out of the networking - stuff dealing with waterblocks and lift-off and terrain and whatnot (space game), but over a local connection I just don't think that it's bandwidth starved.
What it looks like is the ships are moving around - yawing and pitching- smoothly for maybe .5 seconds and then get warped back to their starting point. It's like the server is not agreeing that they need to be turning, or it's coming up with an entirely different turn rate. My only idea is that something happened when I moved this rate from the datablock into the object itself (with a new update mask). It seems to be working just fine, but I will go back and double check this in a debugger.
#15
Please let me know what you find.
One would think. The problem with that reasoning is that the network code enforces it's own bandwidth limits that aren't related to available bandwidth or type of connection. However, even if you increase the packet size/rate, it doesn't alleviate the warp/jitter problems. Some people have said that it does, but I've even changed the C++ code to allow larger limits to be set (rather than just using the $prefs) and it still doesn't solve the problems for me, even for the simple case of one player, one AI and a local server connection.
11/10/2008 (10:15 am)
Be wary tho'... a lot of the small "fixes" in the other threads actually cause more problems than they solve. Especially some of the "fixes" related to vehicle collision...Please let me know what you find.
Quote:I know of several things that I could strip out of the networking - stuff dealing with waterblocks and lift-off and terrain and whatnot (space game), but over a local connection I just don't think that it's bandwidth starved.
One would think. The problem with that reasoning is that the network code enforces it's own bandwidth limits that aren't related to available bandwidth or type of connection. However, even if you increase the packet size/rate, it doesn't alleviate the warp/jitter problems. Some people have said that it does, but I've even changed the C++ code to allow larger limits to be set (rather than just using the $prefs) and it still doesn't solve the problems for me, even for the simple case of one player, one AI and a local server connection.
#16
Might be useful for you to test over net to help isolate the problem. I agree with what EddieRay said about "fixes" found in threads. I suspect something non-stock you've done has caused this problem.
11/10/2008 (3:45 pm)
I think you must have something else going on. The network code is actually very robust. Check my game in my profile. Some of my levels are full of vehicle bots which do not jitter at all, either locally or over the net. The collision issues, however, are a different story.Might be useful for you to test over net to help isolate the problem. I agree with what EddieRay said about "fixes" found in threads. I suspect something non-stock you've done has caused this problem.
#17
11/11/2008 (7:24 am)
IIRC, Lee, you have a lot of vehicles but they move and turn very slowly, kinda like they're flying/moving through a fish tank. Try them at a velocity of over 120 units/sec or so and you'll see a lot more pronounced jitter/warping. Do you have any vehicles under AI control or are they all player-controlled? It's been a while since I tried your game...
#18
If you're really going at a very high speed, you may need to mod the netcode. It's problematic, I think, in all high speed games.
11/11/2008 (2:25 pm)
Yeah, if you shoot one of the ai vehicles, a driveable one will spawn for you. The human ones go faster (although I'm not sure offhand of the speed). Hmm if you get in a car you can hit F for nitrous, and you can do that several times to get going really fast (far too fast to control), and I haven't seen any jitter since I opened up the net settings even with that. It's really been quite robust--thus far. Haven't had a game with lots of humans driving vehicles yet :-(If you're really going at a very high speed, you may need to mod the netcode. It's problematic, I think, in all high speed games.
#19
I DID however find something interesting. I based our code off the Flying Game Example code, but in the resource, it says that you can just create an aiFlyingVehicle via:
new aiFlyingVehicle() {
datablock = MyDatablock;
};
Whereas in the example, and in the game, we're setting up a full game connection via AIConnect(). I think the code that really matters is in processTick:
In the base Vehicle code, I'm DLing a fresh copy of the engine right now, so I can do a comparison, but what I have in place is this:
If you look closely at the top of Vehicle::processTick, you'll see that it's discarding whatever move it's being passed. I don't know if what's going on there, but I think I may have futzed with something I shouldn't there, or something else more sinister.
I'll experiment when I get home, but I think this has to be on the right track. Maybe you guys can see something I don't; I really don't think I borked my networking at the data level, though, on review the code's as clean as can be.
11/11/2008 (2:49 pm)
I'm looking through everything, and I'm looking at the stuff I did to it. I've added some extra data to everything, to support 5 different types of "life" and "energy", but I'm using the change mask flags to deal with that, it seems to be working fine, especially since it's not updating that stuff very often. I also added BUNCH of emitter node positions for engine flares of different types, but that stuff isn't actually sent over the network, so that's not it.I DID however find something interesting. I based our code off the Flying Game Example code, but in the resource, it says that you can just create an aiFlyingVehicle via:
new aiFlyingVehicle() {
datablock = MyDatablock;
};
Whereas in the example, and in the game, we're setting up a full game connection via AIConnect(). I think the code that really matters is in processTick:
void AIFlyingVehicle::processTick(const Move* move)
{
Move aiMove;
if (!move && getAIMove(&aiMove))
{
move = &aiMove;
}
Parent::processTick(move);
}In the base Vehicle code, I'm DLing a fresh copy of the engine right now, so I can do a comparison, but what I have in place is this:
void Vehicle::processTick(const Move* move)
{
Parent::processTick(move);
// if we're not being controlled by a client, let the
// AI sub-module get a chance at producing a move
Move aiMove(NullMove);
if(isServerObject() && getAIMove(&aiMove))
move = &aiMove;
// Warp to catch up to server
if (mDelta.warpCount < mDelta.warpTicks) {
mDelta.warpCount++;
// Set new pos.
mObjToWorld.getColumn(3,&mDelta.pos);
mDelta.pos += mDelta.warpOffset;
mDelta.rot[0] = mDelta.rot[1];
mDelta.rot[1].interpolate(mDelta.warpRot[0],mDelta.warpRot[1],F32(mDelta.warpCount)/mDelta.warpTicks);
setPosition(mDelta.pos,mDelta.rot[1]);
// Pos backstepping
mDelta.posVec.x = -mDelta.warpOffset.x;
mDelta.posVec.y = -mDelta.warpOffset.y;
mDelta.posVec.z = -mDelta.warpOffset.z;
}
else {
if (!move) {
if (isGhost()) {
// If we haven't run out of prediction time,
// predict using the last known move.
if (mPredictionCount-- <= 0)
return;
move = &mDelta.move;
}
else
move = &NullMove;
}
// Process input move
updateMove(move);
// Save current rigid state interpolation
mDelta.posVec = mRigid.linPosition;
mDelta.rot[0] = mRigid.angPosition;
// Update the physics based on the integration rate
S32 count = mDataBlock->integration;
updateWorkingCollisionSet(getCollisionMask());
for (U32 i = 0; i < count; i++)
updatePos(TickSec / count);
// Wrap up interpolation info
mDelta.pos = mRigid.linPosition;
mDelta.posVec -= mRigid.linPosition;
mDelta.rot[1] = mRigid.angPosition;
// Update container database
setPosition(mRigid.linPosition, mRigid.angPosition);
setMaskBits(PositionMask);
updateContainer();
}
}If you look closely at the top of Vehicle::processTick, you'll see that it's discarding whatever move it's being passed. I don't know if what's going on there, but I think I may have futzed with something I shouldn't there, or something else more sinister.
I'll experiment when I get home, but I think this has to be on the right track. Maybe you guys can see something I don't; I really don't think I borked my networking at the data level, though, on review the code's as clean as can be.
#20
Yep... for network play. But for single-player, I shouldn't see any warping/jitter at all, and collision should work perfectly (as can be). This is just not the case with TGE. The netcode is definitely causing warping/jitter even in single-player... which is why we had to rip out the netcode for our game. Suddenly, all the problems disappeared when we did so... plus a mission loads twice as fast (added bonus).
Nothing jumps out at me...
11/11/2008 (3:23 pm)
Quote:It's problematic, I think, in all high speed games.
Yep... for network play. But for single-player, I shouldn't see any warping/jitter at all, and collision should work perfectly (as can be). This is just not the case with TGE. The netcode is definitely causing warping/jitter even in single-player... which is why we had to rip out the netcode for our game. Suddenly, all the problems disappeared when we did so... plus a mission loads twice as fast (added bonus).
Quote:Maybe you guys can see something I don't
Nothing jumps out at me...
Torque 3D Owner Howard Dortch
Default Studio Name