Crates.io Workflow Status

s2protocol-rs 1.1.9

A nom parser for the Starcraft 2 Protocol Replay format.

Generating protocol-specific code:

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'

Add the new module to src/versions/mod.rs

Run rust format on the new src/versions/protocol87702/mod.rs file

cargo check, cargo build, etc

Additionally some code to transform from Protocol-Specific to Protocol-Agnostic was added, TODO: Add to generator.rs

```

version compatibility.

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.

JSON Sources

Blizzard/s2protocol repo

Motivation

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.

Consuming events

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)?, } }

Current issues

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.

TODO

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.

Status