Game Development 11 min read

Doom 3 Network Architecture: Client/Server Model, Snapshots, and Compression Techniques

The article explains Doom 3's deterministic client‑server network architecture, describing how player inputs are sent to the server, how compressed state snapshots are returned at 10‑20 Hz, and the UDP‑based reliable/unreliable messaging and compression methods used to keep the game synchronized.

Architecture Digest
Architecture Digest
Architecture Digest
Doom 3 Network Architecture: Client/Server Model, Snapshots, and Compression Techniques

Doom 3 uses a deterministic client‑server architecture where the client samples player input and sends it to the server, which replies with compressed state snapshots inside the Potentially Visible Set (PVS). The game logic updates at a fixed 60 fps regardless of rendering performance.

C/S Architecture Diagram

The server sends state snapshots at 10‑20 Hz. Because each snapshot represents a moment in the past, the client rewinds to that point, applies the snapshot, and then re‑predicts forward to the current time using both its own and other players' inputs.

Prediction Example

Unlike Quake 3, Doom 3 renders the game state without visual lag, so the client does not need large local prediction buffers. Both server and client run the same code for entity updates, simplifying single‑player and multiplayer development.

Communication Layer

Doom 3 implements a lightweight UDP‑based protocol that carries both reliable and unreliable messages over a single connection. Unreliable messages transport frequent input and snapshot data, while only critical events use the reliable channel, which is piggy‑backed on the unreliable stream.

Message Header

The server includes a 32‑bit game ID and an 8‑bit message type. The client includes the latest server sequence ID for ACK handling, game ID for environment validation, snapshot sequence ID for delta compression, and its own message type.

Snapshots

Each snapshot contains a sequence ID, frame ID, frame time, and client‑ahead time, followed by delta‑compressed entity states, PVS bit‑strings, non‑PVS game updates, and other players' commands.

User Commands

Commands include a debug prediction time, the frame number of the first command, and subsequent per‑frame input deltas.

Compression Techniques

Bit‑packing removes unused bits (e.g., health stored in 7 bits instead of 32) and uses half‑precision floats where appropriate.

Delta compression works at variable, entity, and PVS levels, transmitting only changes between successive snapshots.

Zero‑compression (0‑compressor) packs runs of zeros efficiently, achieving up to a 4:1 reduction; an example shows a 14:8 compression ratio.

Effectiveness

4‑bit packing: 10‑15 % size reduction

Delta compression: >90 % reduction

Zero‑compressing: 15‑50 % reduction

Potential Improvements

Initialize snapshot base from a fully‑initialized map state to avoid initial traffic.

Convert non‑critical reliable events (e.g., visual effects) to unreliable with caching.

Allow the client to maintain purely visual entities locally.

Provide finer‑grained prediction control and the ability to disable synchronization for dead entities.

Implement level‑of‑detail syncing so less important entities update at lower frequencies.

Merge multiple prediction frames for low‑importance entities to reduce CPU load.

© Content sourced from the internet; original authors retain copyright.

network architectureGame developmentcompressionClient-ServerDoom3
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.