cgdangelo / talent

GoldSrc demo parser written with fp-ts.
MIT License
10 stars 1 forks source link

Documentation on delta for GoldSrc demo #164

Open khanghugo opened 1 year ago

khanghugo commented 1 year ago

Great work on this.

I am trying to write my own demo writer but now I am working through delta. I hope you won't mind writing documentation on it since apparently you are the best at writing docs for GoldSrc demo as of now.

Regardless, I am still plowing through it by reading your delta decoding snippet along with this and this.

cgdangelo commented 10 months ago

Sorry for the delayed reply! Thanks for the kind words. ❤️ I'm really glad you've found the documentation helpful.

Unfortunately I have to admit that the fundamentals behind delta compression or even the bit packing/unpacking underlying it are still pretty opaque to me. I adapted hlviewer's implementation, mostly just to get something working with fp-ts ADTs. I think that project is much more readable as a reference for the decoding side:

I'll take a stab at generalizing what I do know (or what I think I know, at least 😄), but I've only had to decode them relying on the hlviewer implementation. Encoding from within a client or just trying to write the structures to file might be a little more nuanced.


Delta compression in GoldSrc

Delta encoding

Delta decoding

Client/server communication

Big guesses to follow here...

1. Server loads delta encoders from <mod>/delta.lst.

2. Client connects to server.

3. Server sends SVC_DELTADESCRIPTION messages.

4. Server sends SVC_* messages containing specific deltas.

Message When
SVC_CLIENTDATA Every frame. Has client data, weapon data from the previous frame. Message structure: SVC_CLIENTDATA.
SVC_EVENT When some specific game events happen; can be queued / dropped. Message structure: SVC_EVENT.
SVC_EVENT_RELIABLE When some specific game events happen, but can't be queued / dropped. Message structure: SVC_EVENT_RELIABLE.
SVC_SPAWNBASELINE When entity spawns for the first time? Message structure: SVC_SPAWNBASELINE.
SVC_PACKETENTITIES Initial entity state? Message structure: SVC_PACKETENTITIES.
SVC_DELTAPACKETENTITIES Every frame? Same as SVC_PACKETENTITIES but this compares to a previous frame somehow. Message structure: SVC_DELTAPACKETENTITIES.

"Reliable" terminology harkens back to Quake netcode stuff I believe: https://fabiensanglard.net/quakeSource/quakeSourceNetWork.php.

Compression algorithm

Bitpacking

There is bitwise magic afoot here, so I've never had a great understanding about this.

hlviewer is an excellent reference: https://github.com/skyrim/hlviewer.js/blob/master/src/BitReader.ts#L10-L48.

Roughly I believe it works like:

If a message is finished writing, usually it will fill up to the next byte boundary.

Reading a delta

khanghugo commented 10 months ago

Hey, thanks for the detailed reply. Since then I have found some (enough) details to understand the delta. Good enough to implement my own, and also a delta writer.

https://github.com/khanghugo/demosuperimpose-goldsrc/blob/master/src/netmsg_doer/utils.rs