🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Delta algorithms

Started by
3 comments, last by Prefect 22 years, 6 months ago
When I''m transferring state information from the server to the client, I''ve got a huge list of entities to transfer. In order to limit the amount of data, I''ve first of all reduced all fields in the structures to the minimum number of bits, and the data is bit-packed. However, I also want to introduce a simple delta from baseline data or older frames which have been acknowledged by the client already. Now the question is, how would I encode the delta in detail? Basically, I''ve come up with two different ideas: a) Prepend a bit-field before every entity which has got a set bit for every field included in the packet, while unset fields are taken from the baseline. The bit-field would be >50 bits for some types. b) Use some kind of run-length, i.e. have a message layout like: xx fields present in the packet yy fields left out because they stay the same zz fields present etc... What do you think is the better approach? Or is there an altogether different method? Unfortunately, Gamedev has really few articles about networking, and I couldn''t really find anything helpful via search engines either... cu, Prefect One line of sourcecode says more than a thousand words.
Widelands - laid back, free software strategy
Advertisement
One method would be to do the following:

you have an object such as
(example only)

class Var
{
char dirty;
char type;
unsigned char data[];
};

class fullObject
{
int numVars;
std::list variables;
};

Say you have a list of these fullObjects that represent entities in your game. When you send normal FULL updates, you pack the DATA portion of the object into a bit stream, similar to what you described. You know the order of the data members on the receiveing end, so this is a no-brainer to reconstruct the object.
During a network frame (typically ~100ms), you mark changed objects as ''dirty''. When you update the object during your send cycle, you check dirty flags for data members of the object. You then send the index of changed members (such as variable two (fullObject.z) within the structure, no, this is NOT an array) and the DATA value. Compressing your deltas is also an excellent way to save bandwidth.
This is a pretty simple explanation, and most likely any more detail would require someone to divulge proprietary info.

Hope it helps.
Unless I''m misunderstanding what you are trying to accomplish, you might want to take a peek at the Quake 2 network protocol (via the recently released code.) If it is anything like the Quake 1 protocol it uses a delta scheme which you might find useful.



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Actually, I did get some of my inspiration from the Quake source, though that''s not flexible enough for me.

Sending the field indices sounds reasonable enough. There''s still the issue with fields that change a lot together. For example, if I''ve got another player to transmit, his origin.x, .y, and angles.x, .y are likely to change every frame. So I was thinking about something like: field #2 plus the following 4 fields have changed. That''s more or less the same though.

About compressing the packets... the problem here is that I don''t have a stream of data, and normal compressing algorithms always work on streams of data. I''d need some kind of generic algorithm that does not rely on previous packets. I doubt that such an algorithm could be efficient enough to be worth it (of course I haven''t tried it, so I can''t be sure).

cu,
Prefect
Widelands - laid back, free software strategy
Which is fine, compression can help, but isn''t always feasible.

gl,

fingh

This topic is closed to new replies.

Advertisement