what's a good way to update object positions on the client
i''m working on a client/server based multiplayer game where the server handles all the physics and movement of objects and needs to notify the clients when the objects change. my main problem is that i want to update the objects at least 15 times a second without overloading a 56k connection. heres the contents of my update packet
BYTE bPacketType // tells what to do with the packet
short objectID // id of the object to update
Vector position // 3 floats defining the x,y,z coords
Vector bodyDir // normalized vector defining the direction the player is facing
float bodyRollAngle
Vector aimDir // normalized vector defining the direction the player is aiming
my question is how can i compress this data down to use fewer bytes or eliminate the need to send it with every update. only sending when the player changes isn''t really a good option here since the players will be updating on the server 45 times a second and its likely that it''ll all need to be sent each time anyway.
i had an idea that i could compress the unit vectors by using WORD vec[3] where the value of each element would be (WORD)(bodyDir.x * 65535) and that would eliminate 12 bytes between bodyDir and aimDir... any ideas on how i could squeeze a few more bytes outta this sucka?
you can implement some kindof delta compression. basically rather than sending the data from the packet, you send the difference (ie what has changed) since the last packet; and only send key packets ocasionally. You will have to look into this method to make sure you find a very efficient implementation of this. I know that half-life uses this method (maybe quake engines too?). Also, this method might not be suitable for your situation, it depends a lot on the data being sent.
[edited by - FearedPixel on July 2, 2002 8:54:18 PM]
[edited by - FearedPixel on July 2, 2002 8:54:18 PM]
Hey Fragmo,
You could update less frequently, say 10 times a second instead of 15. Also, if your server loops 45 times a second, it is truely doubtful that players will have the reflex (or network response time) to make changes to their various directions often enough to require the full update every time. Since the position is the only variable that will change frequently without user input or collision, you can update position FAR less often than 1/15 of a second. You can implement some client side prediction of the location, then maybe once a second give a hard update of the exact position. Then you send packets to the server with updates on the players directional changes, to which you only send an acknowledgement of success or failure of the operation. This way you aren''t constantly flooding their connection with full updates.
Then there is compression... but probably not necessary if you change your update model a bit.
Hope this helps. Good luck.
You could update less frequently, say 10 times a second instead of 15. Also, if your server loops 45 times a second, it is truely doubtful that players will have the reflex (or network response time) to make changes to their various directions often enough to require the full update every time. Since the position is the only variable that will change frequently without user input or collision, you can update position FAR less often than 1/15 of a second. You can implement some client side prediction of the location, then maybe once a second give a hard update of the exact position. Then you send packets to the server with updates on the players directional changes, to which you only send an acknowledgement of success or failure of the operation. This way you aren''t constantly flooding their connection with full updates.
Then there is compression... but probably not necessary if you change your update model a bit.
Hope this helps. Good luck.
July 02, 2002 08:02 PM
If you could get a copy of the July 2002 issue of Game Developer, that has a run down on Vector compression. Actually, you should sign up for the magazine regularly because the last 3 issues(at least) had some sort of bit packing and compression for sending data via tcp/ip.
-James
http://www.gdmag.com/
-James
http://www.gdmag.com/
thanks for the replies guys,
fingh: i''m implementing a FPS so i''d prefer not to drop the update rate below 15. players with good connections would ideally get 45 updates a second, which may be overkill, but i need to implement the client side rendering before i''ll know for sure. i don''t think client side prediction would work too well for position. i just have these visions of players running along their last known course during a laggy interval and then popping up somewhere completely different. *bleck* however, that might work for the bodyDir and aimDir since those are less important. compression sounds good too, delta or vector... decisions, decisions...
fingh: i''m implementing a FPS so i''d prefer not to drop the update rate below 15. players with good connections would ideally get 45 updates a second, which may be overkill, but i need to implement the client side rendering before i''ll know for sure. i don''t think client side prediction would work too well for position. i just have these visions of players running along their last known course during a laggy interval and then popping up somewhere completely different. *bleck* however, that might work for the bodyDir and aimDir since those are less important. compression sounds good too, delta or vector... decisions, decisions...
Client prediction or not, with a lag you will have that popping somewhere else either way.
what you need is to send the position in say 10 Frames and interpolate the actual position from the last known position and the position you know they will be in 10 frames.
this way they will not pop, only move very fast after a lag, and maybe run through a wall...
hey! but they don''t pop!
what you need is to send the position in say 10 Frames and interpolate the actual position from the last known position and the position you know they will be in 10 frames.
this way they will not pop, only move very fast after a lag, and maybe run through a wall...
hey! but they don''t pop!
-----The scheduled downtime is omitted cause of technical problems.
lol Omnibrain. well it looks like i''ll have to either use client prediction and live with the possible side effects or not support dial up connections. oh well. does anyone know how fast games like half-life refresh player positions?
Hi!! why don''t you just calculate all on your clients and send different packets to the server when position or rotaition of a client player cances ?? This would only use
Packed ID byte
Player ID byte
Postion (vector) or Rotation (3 angeles)
Packed ID byte
Player ID byte
Postion (vector) or Rotation (3 angeles)
if your players move linear then u can use vectors and only update them every time a user changes direction or speed, together with a relative compression you can get down real low in bandwith.. (this works with acceleration also but is more complicated..)
It could look like this:
Player A presses [up] (ie he starts to move forward)
Server X recieves Player A Move Forward in Directon xyz
Server Sends a Confirmation to Player A (so that the client knows that it is ok to move forward)
Now the Server and Player A independantly update Player A''s position according to a given vector, that means they do not send any data to each other although Player A''s position is changing, until..
Player A releases [up] (ie stops moving forward)
Server X recieves Player A Stops at Position xyz
Server Sends a Confirmation to Player A (so that it is ok to stop at position xyz)
Server stops moving Player A
Now this is only the bare bones. Of course the server could store the last Direction vector so that the Player can send relative values and thus saving more bandwith..
The main plan of this is that the Client syncronizes its data with the Server and then only sends the key commands as given by the user. The server then calculates all positions etc. Then for safety the Client and Server could resync their data twice every second or so...
hifive!
/soul8o8
It could look like this:
Player A presses [up] (ie he starts to move forward)
Server X recieves Player A Move Forward in Directon xyz
Server Sends a Confirmation to Player A (so that the client knows that it is ok to move forward)
Now the Server and Player A independantly update Player A''s position according to a given vector, that means they do not send any data to each other although Player A''s position is changing, until..
Player A releases [up] (ie stops moving forward)
Server X recieves Player A Stops at Position xyz
Server Sends a Confirmation to Player A (so that it is ok to stop at position xyz)
Server stops moving Player A
Now this is only the bare bones. Of course the server could store the last Direction vector so that the Player can send relative values and thus saving more bandwith..
The main plan of this is that the Client syncronizes its data with the Server and then only sends the key commands as given by the user. The server then calculates all positions etc. Then for safety the Client and Server could resync their data twice every second or so...
hifive!
/soul8o8
Don''t send floats, at least for directions. If you use one byte instead you get accuracy almost down to one degree which is very likely good enough for your visuals. (oops, just saw you were already considering going to WORDs - consider going all the way to BYTEs as well.)
What is in your bodyDir vector? Hopefully not an xyz vector. Pitch and roll alone would probably be good enough. You can throw in yaw if your engine supports it and you think it will make a difference in the visuals. Similiarly aimDir just needs vertical and horizontal angle rather than an xyz vector.
You might be able to normalize your position data to three or even two bytes per component as well. You need to consider how a big a unit is in the worldspace you''ve defined.
-Mike
What is in your bodyDir vector? Hopefully not an xyz vector. Pitch and roll alone would probably be good enough. You can throw in yaw if your engine supports it and you think it will make a difference in the visuals. Similiarly aimDir just needs vertical and horizontal angle rather than an xyz vector.
You might be able to normalize your position data to three or even two bytes per component as well. You need to consider how a big a unit is in the worldspace you''ve defined.
-Mike
-Mike
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement