A nom parser for the Starcraft 2 Protocol Replay format.
The rust code for the protocols versions available were generated using:
```bash mkdir src/versions/protocol89720/ RUSTLOGSPANEVENTS=full RUSTLOG=debug cargo watch -i src/versions/protocol89720/mod.rs -x 'run -- --source ../s2protocol/json/protocol89720.json generate --output src/versions/protocol89720/mod.rs'
```
For the current parsed versions, it seems they are compatible enough and so for now a symlink is created for version specific to version 87702. Even tho the structs are called the same, the bit/byte sizes may be different.
In order for this to work, the repo from Blizzard must be cloned at ../s2protocol
.
The goal is to learn how to parse binary files format with nom
and to learn
how the Starcraft 2 Replay file is so incredibly small for the amount of
information it packs.
From the available data, generative art can be created, for example by using - rerun : See the repo swarmy - lyon (PoC in progress in cooper) - yew cooper - bevyengine/bevy can be used to see: - An Enhanced Replay Minimap - Additional statistics.
To consume events, they are currently loaded in memory in a HashMap:
GameLoop
-> Vec<EventTypes>
rust
let include_stats = false;
let mut replay = SC2ReplayState::new(file_path, SC2ReplayFilters::default(), include_stats).unwrap();
// at this point, all events frcom the MPQ file at `file_path` have been loaded to memory.
// To progress through the game loop, the `replay` state machine transduces from one gameloop to the next one.
// This means it recycles variables, sets position, maintains active units, etc.
// For each transduce step, an SC2EventType is returned and the unit IDs that have been changed.
// These "units" properties can be looked up in the `replay` state machine further.
// In this example, the `add_tracker_event` and the `add_game_event` also are sent a reference to the SC2ReplayState
// For a working example, see the swarmy repo referenced above.
while let Some((event, updated_units)) = replay.transduce() {
match event {
SC2EventType::Tracker {
tracker_loop,
event,
} => add_tracker_event(&self, tracker_loop, &event, updated_units)?, // Some code accessing the Tracker Events
SC2EventType::Game {
game_loop,
user_id,
event,
} => add_game_event(&self, game_loop, user_id, &event, updated_units)?,
}
}
Currently we load all events in memory, Perhaps we can try to read batches on events by keeping MPQ nom parser &[u8] reference. For example, we could read different sections, and return events in different sections in a batch of evenst through a game loop.
We can check that, if some module is exactly the same everywhere, we only create it once and re-use it everywhere. This because the compilation time is getting out of hand.
replay.gamemetadata.json
replay.initData
replay.attributes.events