Demo Files
Jan 12, 2022Sauerbraten offers a way to record and replay matches (as do many other games, especially first-person shooters). In Sauer, these replays are called demos and stored as .dmo files. Demos are usually recorded by the server, showing the server’s view of game events and timing, but there are client mods that allow you to record your own POV as well.
/recorddemo
& /stopdemo
By default, vanilla servers do not record demos, unless enabled for the next match (see below). However, most popular servers are configured to record demos automatically. Server operators can set autorecorddemo 1
in server-init.cfg to do so.
For servers that do not automatically record demos, privileged users can enable recording of the next game using /recorddemo 1
. To disable recording for the next match, use /recorddemo 0
. To stop recording the current match, there is /stopdemo
. The privilege required to use these commands depends on the server; by default, only admins are allowed to use them, and server operators can enable the commands for master and auth by setting restrictdemos 0
in their server-init.cfg.
/getdemo
& /listdemos
Servers will announce at the start of the game if they are recording the game. When you play e.g. forge and see “recording demo”, you know you can wait until the game is over and the next map is loaded (could be reissen), and then call /getdemo [F]
to download and save the replay of the game that ended last, i.e. the match on forge. The filename (F
) is optional, but useful; if not provided, the current date and time will be used.
You can use /listdemos
to get an overview of the demos the server will let you download. (Usually, only the last 5 or so matches are kept for you to download.) Use /getdemo N [F]
where N is the number of a demo listed by /listdemos
to fetch that particular game’s replay.
/demo
& /seekdemo
To watch the match recorded in a demo file, you use the /demo
command. It will automatically go through the files you downloaded using /getdemo
if you press TAB after typing /demo
and SPACE. While the game runs, you are a spectator with the special client number “-1”. Use /gamespeed N
to make the game run slower or faster (N
is in percent, so 100 is normal speed, 50 is half speed, 1000 is super fast).
There is also /seekdemo -MM:SS
to skip forward to when there were MM
minutes and SS
seconds remaining. (/seekdemo MM:SS
works as well and will seek to when MM
minutes and SS
seconds had been played, but that’s decidedly less useful.)
Client-side Demo recording
Since demo files are basically just captures of the network packets sent a server (see below), it’s not too difficult to record a player’s POV of the game by recording the network packets arriving at the client instead. (Some network packets that originate at a client, like N_SHOT, aren’t echoed from the server to the source client, and so have to be injected individually, but it works.) Thomas’ wc-ng as well as p1xbraten have client-side demo recording built in.
wc-ng
wc-ng has the commands /recordclientdemo
and /stopclientdemo
. They work very similar to the commands to manage server-side demo recording:
/recordclientdemo F
: schedules a recording of the next match (F
is the file name to record to)/stopclientdemo
: stops an ongoing recording of the current match
wc-ng also embeds some game meta data into client-side demo recordings and let’s you search your demo files for player names for example. Documentation is a bit scarce, but you can find out more in WC_README.html. As far as I know, it’s not possible in wc-ng to start recording immediately (even though the code for it seems to be there).
p1xbraten
In p1xbraten, I also added the /recordclientdemo
and /stopclientdemo
commands. /stopclientdemo
works just like in wc-ng, but /recordclientdemo
is a bit different:
/recordclientdemo 0|1|2
: 1 schedules, 0 cancels demo recording for the next match; 2 starts recording a demo immediately/stopclientdemo
command: stops an ongoing recording
p1xbraten uses the current date, time, map and mode to name client-side demos automatically.
.dmo file format
The Sauerbraten demo file format is closely related to the network protocol. All communication between the server and the client is based on many individual packets of data. Usually, replays are recorded by the server, meaning demo files are created on the server.
Demo files use compression (gzip) to reduce file size. (In fact, you can just run gunzip --suffix=dmo awsome_game.dmo
to get the raw bytes Sauerbraten will process when playing back the file.) If you decompress a .dmo file, you find at the beginning of the file the “demo header” telling Sauerbraten what to expect in the remaining bytes:
- first, it contains the magic bytes “SAUERBRATEN_DEMO” so Sauer can be sure there’s demo data contained in the gzip stream,
- then there is the demo file format version (so Sauer can inform the user (in case a newer version was used to record this file) that it will not be able to read the stream correctly),
- and finally, the network protocol version number that was used while recording is included (for the same reason as above).
After the header, the file simply contains all network packets the server would have sent to a spectator of the live match (in chronological order). Each packet is prefixed with a small header that has three fields, holding information required to replay the game correctly:
- the time when the packet was sent (relative to the start of the game)
- the channel the packet was sent on (0 or 1, read more here)
- the size of the packet (so the code know how many bytes to read before trying to parse the packet)
To replay the match, the game loop continously looks at the next packet’s timestamp and when the game clock advances to the time the packet was originally sent, it will interpret it as if it just came from a real server.