Test Suite
Visual debugging tools for multiplayer games.
The test suite runs multiple game instances side-by-side in a single browser tab, with simulated network conditions. It detects desyncs, inspects state differences, and verifies determinism — all without needing multiple devices or real network connections.
Opening the Test Suite
The test suite is available at:
https://libs.letsinspire.com/easy_multiplayer/dev/test-suite/pacman.html
It launches two game instances by default. Each runs in its own iframe with a simulated peer ID.
Features
Hash Timeline
A visual strip at the top shows the state hash for every synced frame. Blue ticks mean the instances agree. Red ticks mean a desync was detected. Click any red tick to jump to the details.
Desync Log
When a desync is detected, an expandable entry appears in the log showing:
- The frame number where hashes diverged
- Which instances disagreed
- A deep diff of the full state, down to individual fields — e.g.
componentStates[0].pacmen[0].position.x: 0.5 vs 0.55
Only fully-synced frames (all inputs confirmed) are compared. Unconfirmed frame differences are expected and don't trigger desync warnings.
Double-Tick Determinism Check
Enable the "Double-tick check" checkbox. When active, every tick is executed twice from the same state:
- Capture pre-tick state
- Run the tick normally, capture the result hash
- Restore pre-tick state, run the tick again, capture the second hash
- Compare: if hashes differ, the code is non-deterministic
Failures appear as orange entries in the desync log with a full field-level diff showing exactly which state field changed between the two runs.
Math.random(), Date.now(), or any state that isn't properly captured by ExportState/ImportState. It's the fastest way to verify your game's determinism.
Add/Remove Players
Click "Add Player" to dynamically add a new game instance at any time. Each instance has an "X" button to remove it. This tests mid-game joins and disconnects.
Pause on Desync
Enable "Pause on desync" to automatically freeze all instances when a hash mismatch or determinism failure is detected. This lets you inspect the exact frame where things went wrong.
Network Simulation
The Delay and Jitter sliders control simulated network latency:
- Delay — base latency in milliseconds added to every message
- Jitter — random additional delay (0 to jitter value) added on top of the base delay
Set both to 0 for deterministic testing. Increase them to stress-test rollback behavior.
Understanding the Stats
Each instance shows live stats:
| Stat | Meaning |
|---|---|
| Frame | Current frame number |
| Rollbacks | Total rollbacks performed |
| History | Number of state snapshots in the history buffer |
| Synced | Number of fully confirmed frames |
| Hash | Current state hash |
| Synced Hash | Most recent confirmed hash (used for desync comparison) |
Using with Your Own Game
The test suite is currently set up for the Pac-Man demo. To test your own game:
- Copy
test-suite/pacman-instance.htmlas a template - Replace the game setup with your own game initialization
- Ensure your game exposes
getStats()andgetFullState()on the window - Update
test-suite/pacman.htmlto load your instance file
Unit Tests
The library also includes unit tests (using Vitest) for the core netcode and input query system:
# Run all tests
npx vitest run
# Run specific test file
npx vitest run tests/input-query-system.test.js
Tests cover: query recording, rollback avoidance, legacy fallback behavior, edge cases, and core rollback mechanics.