DEM Format

From Valve Developer Community
Revision as of 16:28, 22 December 2011 by DaFox (talk | contribs) (Demo Header)

Jump to: navigation, search

DEM, short for demo is the Source demo file format. Used in conjunction with the Source recorder to record demos.

Note:it is not possible to edit what happens in a Source demo after the recording, it basically stores the packets right off the wire and we don't know the packet format

For the purpose of this we will be referring to each collection of events as a frame. This may or may not add up to the number of frames given by the header.

Demo Header

Type Field Value
String Header 8 characters, should be "HL2DEMO"+NULL
Int Demo Protocol Demo protocol version, should be '3'
Int Network Protocol Network protocol version number
String Server name 260 characters long
String Client name 260 characters long
String Map name 260 characters long
String Game directory 260 characters long
Float Playback time The length of the demo, in seconds
Int Ticks The number of ticks in the demo
Int Frames The number of frames in the demo
Int Sign on length  ?


Each frame begins with 0 or more of these commands: These are described in hl2sdk\utils\demofile\demoformat.h / hl2sdk-ob\public\demofile\demoformat.h / hl2sdk-l4d\public\demofile\demoformat.h

Network Protocols 7 and 8

Type Value
dem_signon 1
dem_packet 2
dem_synctick 3
dem_consolecmd 4
dem_usercmd 5
dem_datatables 6
dem_stop 7
dem_lastcommand dem_stop

Network Protocols 14 and 15

Type Value
dem_stringtables 8
dem_lastcommand dem_stringtables

Network Protocols 36 and Higher

Type Value
dem_customdata 8
dem_stringtables 9
dem_lastcommand dem_stringtables

Depending on the command that was received, a different action needs to be taken.


This is a signal that the demo is over, and there is no more data to be parsed.

dem_consolecmd, dem_datatables, dem_usercmd, dem_stringtables

Read a standard data packet, deal with it as necessary.

dem_synctick, dem_signon, dem_packet


Standard Data "Packet"

Any time there is more than one byte to be read in, a standard format is used.

This begins with an integer that has the number of bytes in this packet.

Example code to handle this:

int ReadData(char **buffer)
	int len;
	fread (&len,sizeof(int),1,fDemo);
	if (len > 0)
		*buffer = new char[len];
	return len;

Frame Format

Frame {
       int ServerFrame;
       int ClientFrame; //ServerFrame and ClientFrame delta probably correspond to client ping.
       int SubPacketSize;
       *buffer = new char[SubPacketSize]; // State update message?
       Packet pkt = (rest of frame as data exists) // All demo commands are strung together in this area, structure below
       JunkData data = (unknown) // ex: 0x8f 5a b5 04 94 e6 7c 24 00 00 00 00 00 ... (40 bytes of 0x00 after the 0x24)
                                 // This could either be the end of the frame or the start of the next frame.
Packet {
       char CmdType;
       int Unknown;
       int TickCount; //This only sporadically appears.
       int SizeOfPacket;
       *buffer = new char[SizeOfPacket];