A Supreme Commander: Forged Alliance replay parser based on https://github.com/FAForever/faf-scfa-replay-parser.
This project aims to provide a fast parser for the Supreme Commander Forged Alliance (SCFA) replay data format. These replay files are relatively small by today's standards, however, performance still matters when you need to parse a large number of replays.
This repository includes the parser implementation as a Rust crate, as well as command line utility and Python3 bindings.
The easiest way to use the parser is through the Python module. Note that pre-compiled binaries are only distributed for Linux. If you need to compile for a different operating system, the Building section may be helpful.
Install using pip:
$ pip install faf-replay-parser
Parse replays through the Parser
class:
```python
from datetime import timedelta
from fafreplay import Parser, commands
parser = Parser(
# Skip all commands except the ones defined here
commands=[
commands.Advance, # For the tick counter
commands.VerifyChecksum, # For desync detection
],
# Throw away commands right after we parse them. Setting this to True
will
# significantly increase the parse time.
save_commands=False
)
bytes
objectwith open("12345.scfareplay", "rb") as f: data = f.read()
bytes
replay = parser.parse(data) print("Game time:", timedelta(milliseconds=replay["body"]["sim"]["tick"]*100)) if replay["body"]["sim"]["desync_ticks"]: print("Replay desynced!") ```
Or use the high performance functions for special cases:
```python from fafreplay import bodyoffset, bodyticks
offset = bodyoffset(data) headerdata, body_data = data[:offset], data[offset:]
ticks = bodyticks(bodydata) print("Game time:", timedelta(milliseconds=ticks*100)) ```
Disclaimer: The cli is a work in progress, and some parts of it may currently print out excess amounts of debug information.
You can get the cli by cloning this repository and building it with:
$ cargo build --release --bin fafreplay --features cli
This will produce an executable in target/release/
. Copy this to some location
in your $PATH
, for instance ~/.local/bin/
.
Alternatively, a Linux binary is available in the GitLab CI build artifacts of every tagged release.
The cli currently performs 3 main functions. Printing a summary of the replay
(mostly header information), inspecting the contents of the command stream, and
converting fafreplay
files into scfareplay
files.
Shows an overview of the replay contents. Additional information about the map, players, game options and more can be enabled as well.
``` $ fafreplay info 6176549.fafreplay processing replay: 6176549.fafreplay Supreme Commander v1.50.3698 Replay v1.9
Seton's Clutch (00:48:11) Dozens of battles have been fought over the years across Seton's Clutch. A patient searcher could find the remains of thousands of units resting beneath the earth and under the waves.
Team 1 civilian (AI) 5
Team 2 [PLD] EricaPwnz (1200) Aeon Vmcsnekke (1600) UEF [AoS] Strogo (2100) UEF [JEW] Licious (1600) Seraphim
Team 3 [SNF] PlodoNoob (1800) Cybran Mizer (1400) Seraphim [SC] HerzogGorky (1400) Cybran [JEW] Robogear (2100) UEF ```
Displays commands as they appear in the replay file. By default this only shows the most common commands.
``` $ fafreplay commands 9000556.scfareplay --limit 10 processing replay: 9000556.fafreplay Supreme Commander v1.50.3701 Replay v1.9
0 ├── SetCommandSource { id: 0 } 1 ├── VerifyChecksum { digest: [168, 55, 122, 87, 70, 60, 17, 145, 224, 174, 52, 71, 2, 143, 109, 2], tick: 0 } 2 ├── Advance { ticks: 1 } 3 ├── Advance { ticks: 1 } 4 ├── Advance { ticks: 1 } 5 ├── Advance { ticks: 1 } 6 ├── Advance { ticks: 1 } 7 ├── Advance { ticks: 1 } 8 ├── Advance { ticks: 1 } 9 ├── Advance { ticks: 1 }
Total commands parsed: 10 ```
Converts a .fafreplay file into a .scfareplay file.
$ fafreplay unpack 9000556.fafreplay
Extracting...
Done
Writing 9000556.scfareplay
Wrote 12314246 bytes
To build the command line utility:
$ cargo build --release --features cli
To build the Python extension module:
$ cargo +nightly build --lib --features python --release
For developing the python bindings it may be useful to simlink the compiled library to the root project directory.
$ ln -s target/release/libfafreplay.so ./fafreplay.so
Python will then be able to find the module fafreplay
when the interpreter is
run from the project root.
Looking for a parser in a different language? Check out these other replay parser implementations: