Repository navigation
Replay your games
ProLeak can save every game you play, official or local, and play it back later in the game: as a spectator, or from your own seat with your HUD. A recording is a single file you can keep and share.
Contents
Turn on Mods > Recordings > Start recording games, or set record: true in
ProLeak/config/proleak.yml. The setting applies from the next game, so a recording always
starts at the start of its game. If the connection drops and you rejoin the same game, the
recording goes on in the same file.
Each game becomes ProLeak/recordings/<date>-<time>-<game id>.ltd2demo. A toast ("Game saved")
says when the file is complete, or why it could not be written.
Mods > Recordings lists your newest recordings like the game's match history: the result, the
queue, the last wave and the date, then your value, workers, income, leaks, build and legion.
Each game has three buttons:
- Watch shows the game as a spectator, starting on the recorded player's lane.
- Watch as player shows it from the recorded player's seat, with their HUD.
- Delete removes the file, after asking.
The game's own match history (Profile > Match History) also gets a Watch button at the right
end of each game that has a recording.
During playback a bar beside the top bar has Pause, Play, Slower and Faster
(0.5x to 8x). Chat commands do the same: -speed 2, -pause, -resume and -leave. Once the
recording has run out, Quit appears. Seeking back is not supported yet: leave and watch
again to start over.
ProLeak plays a recording through its own local server, so watching one reports nothing to the official servers.
A recording holds what the server sent you during the game. Two things are missing from it:
- The other team's building. The server never sent it during the game. Playback fills it in from the end screen, so the other team's fighters appear at the start of each wave, as they stood for that wave. A recording cut short before the end screen leaves them out.
- In spectator view, what was sent to you alone, such as your Mastermind roll windows.
A recording plays as it is on the game version that recorded it. On another version, Watch first checks the recording:
- When ProLeak can read or convert every message, it offers Watch anyway. The game itself may behave differently on the new version, so the replay may not match the original game.
- Otherwise it says why the recording cannot be replayed.
- Every message the game server sent during the game and every message your client sent, chat included.
- The game version, the map, the queue, the players' names and account ids, and their legions.
- How the game ended, and your line of the end screen.
Your login and session ticket are never written.
Warning
Sharing a recording
Recordings hold players' names and account ids: share a file only with people you would show the game to.
A file cut short (the game crashed or closed while recording) can still be played up to its last ten complete seconds.
tools/DemoInfo
describes a file: its game, how it ended, whether its checksum holds, and its bytes by
message.
dotnet run --project tools/DemoInfo -- recordings/20261014-213005-abc123.ltd2demo
It exits with 0 for a whole file, 1 for a cut or damaged one and 2 for a file it cannot read.
With --against 26.10a it also says whether the recording plays on that game version, from the
message formats ProLeak recorded for it.
All integers are little endian; a varint is an unsigned LEB128 number and a signed varint is its zigzag form.
file := magic header chunk* index footer trailer
magic := "LTD2DEMO" u16(version, 1)
header := u32(length) JSON
chunk := 'C' u32(compressed length) u32(length) i64(first tick) deflate(records)
record := varint(kind) signed-varint(tick - previous tick) body
index := 'I' varint(count) { i64(first tick) i64(offset of the chunk's 'C') varint(records) }*
footer := 'F' u32(length) JSON
trailer := i64(offset of 'I') u32(CRC-32 of every byte before the trailer) "LTD2DEND"A record's tick is the client's estimate of the server clock in milliseconds; the first record of a chunk counts from the chunk's first tick. A chunk ends after ten seconds of game or 256 KiB of records.
| Kind | Body |
|---|---|
| 0, a server message |
u8(tag) varint(subject) varint(length) bytes: the message's payload as received |
| 1, a client message | the same, with the payload as the game encodes it |
| 2, a dev line |
varint(length) UTF-8 JSON: the decoded message, written in dev mode only |
| 3 to 15 |
varint(length) bytes, reserved: a reader skips them |
The header's keys are format, game_version, proleak_version, map, queue, slot
(the local player's index in slot_ids), slot_ids, local, dev, builder_types and
seed (null for an official game), game_files (each game assembly's SHA-256), and mode
and mode_version (the game mode a local game played, as plugin:name, and that plugin's
version; empty otherwise). The
footer's are result, waves, records, dropped, messages (each message type the
recording holds, by full name, with its format: tag, subject, fingerprint and the fields its
reader reads in order), broken (message types the game read short while recording) and
card (the recorded player's end-screen line: value, workers, income, leak_first,
leak_second, wave_unit, legion_icon, spell_icon, and opening and build: the units
of the first and the last wave, each a list of unit types with their count). A reader ignores keys it does not know.
Using ProLeak
Features
Tutorial
- Your first plugin
- Plugin basics
- Handling events
- Plugin settings
- User interface
- Players, units and game data
- Purchases, signals and pings
- Chat, camera, input and more
- Cosmetics
- Game modes
- Game updates
- Publishing plugins
Reference