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?
About the author
#22
11/12/2008 (8:19 am)
Yeah Duncan... there is all that. It seems to me that it may just work better if it sent the transform of the objects "down the pipe" to the client each tick, computing the sim on the server, and doing the normal interpolation on the client side... and avoided all this other "nonsense" which just ends up making TGE's frame-rate suffer. The "prediction" feature is destined to fail for human-controlled objects, and especially high-speed vehicles where their motion changes extremely quickly. If the prediction is guaranteed to produce the wrong results a good portion of the time (causing warping), then it's not helping in the solution. The main reason TGE works okay with FPS type games is because most FPS objects are slow-moving and many have a simple trajectory-based motion, and often the human input is somewhat slow in changing the player's movement (i.e. also very predictable). However, if you play a game of Fallen Empires: Legions (which I bring up because I've played it recently, and it's somewhat of a "flagship" of TGEA currently, and it's very similar to Tribes 1/2 that dates back to the dawn of the TGE code), you can see that even with only simple player characters and simple trajectory-based motion and shooting, the "simulation" isn't very accurate and it can often be unplayable (i.e. the "game", which is to shoot other characters, becomes erratic such that you can't really hit anything because you're aiming at an inconsistent simulation of the other players). Sure, TGE has a lot of optimization/refinement in it's networking design that can be pretty good in general, but it misses the mark in some fundamental ways for things which are not FPS-like (and even for FPS-like games). Having TGE do the calculations twice for every object every frame/tick is just silly... running both client and server on the same machine leads to twice the CPU load, half the frame rate, while still suffering from network warping/jitter for even a single-player game. That's just "the way TGE works" unfortunately.
#23
That said, something on the server or client is having a major disagreements, particularly about rotation speed. It's turning perfectly smoothly for about a second, and then warping back about 90% of it's rotation. This is not simple interpolation error, this is a full disagreement between the two as to what is supposed to be happening. I've gone through all the processTick() code, that was a dead end, it was unchanged and actually works. It must be something in my code.
Only thing I'd like to know is if creating a bot via AIConnect() versus just creating a new AISpaceVehicle makes a difference. That code is pretty deep, so it's a bit hard test, but I'll try later tonight.
11/12/2008 (8:56 am)
Aside from any "disagreements" that exist about the merits of the engine, I think I've got something novel going on that I can't figure out. My vehicles are neither particularly fast moving or not following trajectories. The game has only 4-10 netobjects at any given time depending on the number of AIs it generates (currently), so it's not crowded. I'm running 100+ fps, and the processor load is low. The only things I've changed in making a stock flying vehicle into a Space Vehicle have been updateMove and updateForces, and both of those are more variations on the existing theme than additions..That said, something on the server or client is having a major disagreements, particularly about rotation speed. It's turning perfectly smoothly for about a second, and then warping back about 90% of it's rotation. This is not simple interpolation error, this is a full disagreement between the two as to what is supposed to be happening. I've gone through all the processTick() code, that was a dead end, it was unchanged and actually works. It must be something in my code.
Only thing I'd like to know is if creating a bot via AIConnect() versus just creating a new AISpaceVehicle makes a difference. That code is pretty deep, so it's a bit hard test, but I'll try later tonight.
#24
11/12/2008 (9:18 am)
I *think* you need your new object to be derived from GameConnection in order for it to receive moves correctly in the client/server scheme.
#25
The main question in my mind is how or IF the client receives moves from getAIMove(). From the code above, with its check for isServerObject, I don't think the client is generating aiMoves on it's own. Are they sent down the wire from the server? Does the client call updateMove()?
11/12/2008 (9:28 am)
Eddie, you almost read my mind. I think I had an epiphany in the car on the way to work right after I wrote my last post. The timing of everything is too wrong to be interpolation errors. But the timing is just about right for my auto-level code to kick in. In updateMove(), I update a timer, and then in updateForces, if that timer has reached 0, I kick in a new force to auto-level the pitch of the ship. That timer takes about a second to work- just about the same time as the ships jerk! Coincidence, probably not. I'm still trying to work out the pathways, though. I have some logic in updateMove() for handling timers and detecting if you've let up on the turn button (instant stop), but those variables are not sent over the wire, so that could be the source of my problems.The main question in my mind is how or IF the client receives moves from getAIMove(). From the code above, with its check for isServerObject, I don't think the client is generating aiMoves on it's own. Are they sent down the wire from the server? Does the client call updateMove()?
#26
11/12/2008 (12:05 pm)
AFAICT, the "mDelta" has the move in it... and that's definitely transferred from the server to the client... and both the client and the server use updateMove() as part of the object's simulation. It appears that the server sets mDelta.move based on what getAIMove() returns, and getAIMove() is only called in the server.
#27
That said, something on the server or client is having a major disagreements, particularly about rotation speed. It's turning perfectly smoothly for about a second, and then warping back about 90% of it's rotation. This is not simple interpolation error, this is a full disagreement between the two as to what is supposed to be happening. I've gone through all the processTick() code, that was a dead end, it was unchanged and actually works. It must be something in my code.
Only thing I'd like to know is if creating a bot via AIConnect() versus just creating a new AISpaceVehicle makes a difference. That code is pretty deep, so it's a bit hard test, but I'll try later tonight.
11/16/2008 (3:30 pm)
Aside from any "disagreements" that exist about the merits of the engine, I think I've got something novel going on that I can't figure out. My vehicles are neither particularly fast moving or not following trajectories. The game has only 4-10 netobjects at any given time depending on the number of AIs it generates (currently), so it's not crowded. I'm running 100+ fps, and the processor load is low. The only things I've changed in making a stock flying vehicle into a Space Vehicle have been updateMove and updateForces, and both of those are more variations on the existing theme than additions..That said, something on the server or client is having a major disagreements, particularly about rotation speed. It's turning perfectly smoothly for about a second, and then warping back about 90% of it's rotation. This is not simple interpolation error, this is a full disagreement between the two as to what is supposed to be happening. I've gone through all the processTick() code, that was a dead end, it was unchanged and actually works. It must be something in my code.
Only thing I'd like to know is if creating a bot via AIConnect() versus just creating a new AISpaceVehicle makes a difference. That code is pretty deep, so it's a bit hard test, but I'll try later tonight.
#28
02/03/2009 (11:52 am)
Charlie: Have you discovered anything that helps alleviate this problem?
#29
02/03/2009 (11:53 am)
I think this thread got a big "zorched" in the site update... Charlie's previous post got duplicated. I wonder if some of the most recent posts got lost...
#30
02/03/2009 (12:03 pm)
Yeah, I think my follow up (and yours) did get zapped. Basically, I got this working OK, by A. turning up the transfer rate for data, and B. found a bug in my code. I was setting a few flags as part of updateMove() which were being checked in updateForces(), for things like "firstMoveAfterEventX", which updateForces would use to apply damping and other limits to the rigid body. Somehow, (and I don't remember exactly why at this point), there was some interference popping up between updateMove() and updateForces(), that was causing these flags to be set correctly on the Client and not on the Server, or vice versa, resulting in major graphical flaws. IIRC, it seemed like updateMove was not in sync on the client and the server, by about 1 step. Unfortunately, due to the way my physics work, being out of step would totally reset these flags and mess everything up. I don't think I ever quite figured out the exact nature of the interference pattern, I just recoded the physics to make these flags unnecessary.
#31
02/03/2009 (1:54 pm)
Hey Charlie - if you're interested in chatting about this via email, you can contact me directly (the email address is on my profile page).
Torque Owner Duncan Gray
But that would just be masking the real problem which is why I never took that route. I reduced my integration value to about 2 and really worked on making the physics as efficient as possible. There are many areas of vehicle physics code that get recalculated on every frame using data which is static from the data block. Move those calculations to the onAdd section and store the result for use in the per frame calculations.
Unfortunately the code does the physics calculations for both client and server, collision for both client and server, wheel cast rays for client and server. In fact wheel cast rays are done 3 times per wheel per frame. One for server and two for client. So even on a local connection you get all calculations duplicated, triplicated for wheel castrays and if you got your integration set to 4 then you get 8 physics calculations per frame, each physics calculation calling a cast ray on each wheel so thats 3*8*4(wheels)=96 castrays per vehicle per frame.
The more you reduce that time the closer the client and server will be at calculating the correct vehicle position and the smoother the appearance will be. The stock code does not do that for you.