blind-review-data/StarCraftMotion_sample
StarCraftMotion StarCraftMotion is a large-scale benchmark for agent simulation under adversarial and partial observability scenarios (built from StarCraft replays). Each example is a fixed-length scenario window (145 frames at 16 FPS, ~9 seconds) containing all unit states, dynamic map layers, and per-player economy time series. The released split is adversarial: scenarios are subsampled to overweight interaction-heavy windows (mutual-visibility and inter-player transitions)… See the full description on the dataset page: https://huggingface.co/datasets/blind-review-data/StarCraftMotion_sample.
016
1---2license: cc-by-nc-4.03pretty_name: StarCraftMotion4language:5- en6size_categories:7- 100K<n<1M8task_categories:9- time-series-forecasting10- other11tags:12- starcraft13- multi-agent14- agent-simulation15- partial-observability16- benchmark17configs:18- config_name: default19 data_files:20 - split: train21 path: train/*.parquet22 - split: validation23 path: validation/*.parquet24 - split: test25 path: test/*.parquet26---27 28# StarCraftMotion29 30StarCraftMotion is a large-scale benchmark for agent simulation31under adversarial and partial observability scenarios (built from StarCraft replays). Each example is a fixed-length scenario window (`145` frames at `16 FPS`, ~9 seconds) containing all unit 32states, dynamic map layers, and per-player economy time series.33 34The released split is **adversarial**: scenarios are subsampled to35overweight interaction-heavy windows (mutual-visibility and inter-player36transitions), making it a stress test for multi-agent prediction under37partial observability.38 39- **Total scenarios:** 469,18740- **Train / Val / Test:** 362,075 / 45,121 / 61,99141- **Source replays:** 64,327 replay-level HDF5 files (Blizzard `3.16.1-Pack_1-fix`)42- **Maps (ID):** Abyssal_Reef_LE, Acolyte_LE, Ascension_to_Aiur_LE, Interloper_LE, Mech_Depot_LE43- **Maps (OOD, test only):** Catallena_LE_(Void), Odyssey_LE44- **Splits are replay-level** — windows from the same replay never cross splits.45 46## Why parquet, and how to read47 48Each row is one scenario. All per-frame / per-unit array columns are49stored as **typed Arrow `large_list` arrays** (e.g. `LIST<float16>`,50`LIST<bool>`). `n_timesteps = 145` and `n_units` varies per scenario (stored per row).51The dynamic map layers (`map_creep`, `map_fow_p1`, `map_fow_p2`) are52sampled every 16 frames, giving `map_T = 10` snapshots per scenario.53Spatial dimensions `map_H` and `map_W` are stored as explicit scalar54columns per row (map-dependent; e.g. Abyssal_Reef_LE is 176 × 200).55 56```python57import numpy as np58from datasets import load_dataset59 60ds = load_dataset("blind-review-data/StarCraftMotion", split="train", streaming=True)61row = next(iter(ds))62 63T, N = row["n_timesteps"], row["n_units"]64map_T, map_H, map_W = row["map_T"], row["map_H"], row["map_W"]65 66coord = np.asarray(row["coordinate"], dtype=np.float16).reshape(T, N, 3)67alive = np.asarray(row["is_alive"], dtype=bool ).reshape(T, N)68owner = np.asarray(row["unit_owner"], dtype=np.uint8 ).reshape(N)69utype = np.asarray(row["unit_type"], dtype=np.uint32).reshape(T, N)70creep = np.asarray(row["map_creep"], dtype=bool ).reshape(map_T, map_H, map_W)71```72 73### Schema74 75#### Scalar fields76 77| Field | Type | Description |78|---------------|--------|--------------------------------------------------------------|79| `split` | string | `train`, `val`, or `test` |80| `map_name` | string | Map name (spaces replaced with `_`) |81| `replay_hash` | string | Hash of the parent SC2Replay file |82| `segment_idx` | int32 | Index of this 145-frame window inside the parent replay |83| `n_timesteps` | int32 | Number of frames per row (constant `145` in this release) |84| `n_units` | int32 | Number of unique unit rows in this scenario (variable) |85| `map_T` | int32 | Number of map snapshots per row (constant `10` in this release) |86| `map_H` | int32 | Map grid height in cells (map-dependent) |87| `map_W` | int32 | Map grid width in cells (map-dependent) |88 89#### Map data — shape `(map_T, map_H, map_W)` where `map_T = 10`90 91`map_H` and `map_W` are map-specific (each StarCraft II ladder map has92its own native grid). All three layers below share the same shape per93scenario.94 95| Field | dtype |96|---------------|-------|97| `map_creep` | bool |98| `map_fow_p1` | bool |99| `map_fow_p2` | bool |100 101#### Player economy — shape `(145, 2)`, column 0 = Player 1, column 1 = Player 2102 103| Field | dtype |104|-------------|--------|105| `food_cap` | uint8 |106| `food_used` | uint8 |107| `minerals` | uint16 |108| `vespene` | uint16 |109 110#### Per-unit constants — shape `(n_units,)`111 112| Field | dtype | Description |113|--------------|--------|----------------------------------------------|114| `unit_owner` | uint8 | 1 = P1, 2 = P2, 16 = neutral |115| `unit_tag` | uint64 | Raw SC2 engine tag (unique per unit instance)|116 117#### Per-frame, per-unit — shape `(145, n_units)` unless noted118 119| Field | dtype | Shape | Description |120|-------------------|---------|----------------------|-------------------------------------------------|121| `coordinate` | float16 | (145, n_units, 3) | Native (x, y, z) map coordinates |122| `target_pos` | float16 | (145, n_units, 2) | Order target ground position |123| `health` | float16 | | |124| `health_max` | float16 | | |125| `shield` | float16 | | Protoss shield |126| `energy` | float16 | | |127| `heading` | float16 | | Facing direction in radians (0 to 2π) |128| `radius` | float16 | | Unit collision radius |129| `build_progress` | float16 | | 0.0–1.0 |130| `unit_type` | uint32 | | Raw SC2 unit type ID |131| `ability_id` | uint32 | | First order's ability ID |132| `target_id` | uint32 | | Target's row index (`0xFFFFFFFF` = no target) |133| `mineral_contents`| uint16 | | Remaining minerals (mineral fields) |134| `vespene_contents`| uint16 | | Remaining vespene (geysers) |135| `is_alive` | bool | | |136| `is_burrowed` | bool | | Zerg burrowed |137| `is_carried` | bool | | Inside a transport |138| `is_flying` | bool | | Air unit / lifted building |139| `visible_status` | uint8 | | Combined P1/P2 visibility (see below) |140 141`visible_status = p1_state * 3 + p2_state`, with each state in142`{0 = unseen, 1 = snapshot, 2 = visible}`. Examples: `8` = visible to both,143`6` = visible to P1 only, `2` = visible to P2 only.144 145### Action labels146 147The `ability_id` column stores the **raw SC2 ability ID as `uint32`**148(e.g. `MOVE = 16`, `ATTACK_ATTACK = 23`, `HARVEST_GATHER_DRONE = 1183`,149`ability_id == 0` means the unit has no active order). It is **not**150class-indexed.151 152For action prediction tasks we provide an 11-class coarse mapping in the153source repository at154[`sc2sensor/utils/coarse_action_mapping.py`].155 156| Label | Name | Description |157|------:|-----------|------------------------------------------------------------|158| 0 | NO_OP | `ability_id == 0`; unit idle |159| 1 | MOVE | move, patrol, hold position, stop, smart (right-click) |160| 2 | ATTACK | attack, attack-move, attack building |161| 3 | HARVEST | gather resources, return cargo |162| 4 | TRAIN | produce units from buildings / larvae / warp-in |163| 5 | BUILD | construct structures, add-ons, creep tumors |164| 6 | RESEARCH | upgrades and tech research |165| 7 | MORPH | unit/structure transformation (siege, archon, lair, etc.) |166| 8 | EFFECT | combat abilities, spells, auto-cast effects |167| 9 | TRANSPORT | load, unload, lift off, land |168| 10 | BURROW | burrow down / burrow up (Zerg) |169| 255 | UNKNOWN | unmapped or cosmetic |170 171Sources for the mapping:172- Blizzard `s2client-api` `ABILITY_ID` enum:173 https://blizzard.github.io/s2client-api/sc2__typeenums_8h.html174- Blizzard `s2client-proto` `stableid.json`:175 https://github.com/Blizzard/s2client-proto/blob/master/stableid.json176 177Coverage on the released split is 100% of all action occurrences178(every `ability_id` either matches a Blizzard enum prefix, is one of 10179explicit `stableid.json` overrides, or is `0` / falls into `UNKNOWN`).180 181#### Applying the mapping182 183```python184import numpy as np185from sc2sensor.utils.coarse_action_mapping import ABILITY_ID_TO_COARSE_ACTION186 187T, N = row["n_timesteps"], row["n_units"]188ability_id = np.frombuffer(row["ability_id"], dtype=np.uint32).reshape(T, N)189 190# Vectorized lookup via a dense uint8 table.191max_id = max(ABILITY_ID_TO_COARSE_ACTION) + 1192lut = np.full(max_id, 255, dtype=np.uint8)193for aid, label in ABILITY_ID_TO_COARSE_ACTION.items():194 lut[aid] = label195 196coarse = np.where(ability_id < max_id, lut[np.clip(ability_id, 0, max_id - 1)], 255)197```198 199## Pipeline summary200 2011. **Replay extraction** (`extract_replay_level.py`): three SC2 engine passes202 (omniscient + per-player FOW) into one HDF5 per replay, preserving native203 coordinates, raw SC2 unit/ability IDs, and per-player visibility.2042. **Scenario windowing** (`split_scenarios.py`): chunk into `145`-frame205 windows at `16 FPS` (1 s history + current + 8 s future).206 Drops replays with `duration < 120 s` or either player at `APM < 1`.2073. **Replay-level split** (`create_dataset_split.py`): 80/10/10 train/val/test208 over ID maps; OOD maps go to test only. Keeps `10%` of each replay's209 windows.2104. **Adversarial weighting**: window sampling weight is211 `log(1 + mutual_unit_sum) + log(1 + transition_cnt)`; zero-score windows212 are excluded.213 214## Dataset statistics215 216### Player-unit counts (units with `owner != 16`)217 218| Split | Mean | Std | Min | P25 | Median | P75 | Max |219|-------|-------:|-------:|----:|----:|-------:|----:|----:|220| Train | 204.56 | 113.06 | 11 | 109 | 189 | 284 | 921 |221| Val | 203.56 | 112.51 | 18 | 109 | 188 | 282 | 689 |222| Test | 202.78 | 111.70 | 13 | 107 | 189 | 281 | 779 |223 224### Race matchups225 226| Split | PvP | PvT | PvZ | TvT | TvZ | ZvZ |227|-------|-------:|-------:|-------:|-------:|--------:|-------:|228| Train | 23,322 | 82,819 | 66,139 | 54,819 | 104,780 | 30,196 |229| Val | 3,037 | 9,978 | 8,514 | 6,853 | 13,326 | 3,413 |230| Test | 4,112 | 13,927 | 10,883 | 9,536 | 18,531 | 5,002 |231 232### Mutual visibility (units with `visible_status == 8` and `is_alive`)233 234| Split | Mean mutually-visible units / frame |235|-------|------------------------------------:|236| Train | 23.56 |237| Val | 23.40 |238| Test | 23.43 |239 240## Intended use241 242- Multi-agent simulation under adversarial partial observability.243- Benchmarks for fog-of-war handling, ID vs OOD-map244 generalization, and interaction-heavy scenes.245 246## Limitations and ethical considerations247 248- **Replay provenance:** raw replays come from Blizzard's249 `3.16.1-Pack_1-fix` distribution. Per-replay curation, demographics of250 players, and any prior filtering performed by Blizzard are not documented.251- **MMR caveat:** raw MMR values include sentinel-like negatives (down to252 `-36400`) for some replays. League-tier bucketing should be recomputed253 rather than relied upon naively.254- **Single game version:** all replays are SC2 build 3.16.1; balance and255 meta-game differ from current ladder versions.256- **No personally identifying content** is included beyond what Blizzard257 publishes in replay packs. Player names are not surfaced as columns.258- **Game-balance / strategic bias:** the corpus is whatever Blizzard259 released in the pack and is not a uniform sample of competitive play.260 261## License262 263The released parquet artifacts are licensed under264[**Creative Commons Attribution-NonCommercial 4.0 International (CC-BY-NC-4.0)**](https://spdx.org/licenses/CC-BY-NC-4.0.html)265(SPDX: `CC-BY-NC-4.0`).266 267The released parquet files are **derivative ML features** (float16 unit268trajectories, fog-of-war and creep masks, per-player economy time series,269and raw SC2 unit/ability identifiers) extracted from StarCraft II270replays. The dataset does **not** redistribute raw `.SC2Replay` files,271SC2 game maps, or any portion of the StarCraft II Software. Use of the272underlying StarCraft II replays and the SC2 engine is separately273governed by Blizzard's274[AI and Machine Learning License](https://blzdistsc2-a.akamaihd.net/AI_AND_MACHINE_LEARNING_LICENSE.html);275that license explicitly permits use of derived ML data for personal or276internal research and development.277 278 279## Citation280 281Underlying replays:282 283```bibtex284@misc{blizzard_sc2_replaypacks,285 title = {StarCraft II Replay Packs (3.16.1-Pack\_1-fix)},286 author = {{Blizzard Entertainment}},287 howpublished = {\url{https://blzdistsc2-a.akamaihd.net/ReplayPacks/3.16.1-Pack_1-fix.zip}}288}289```290 291## Acknowledgments292 293Built on top of DeepMind's `pysc2` and Blizzard's StarCraft II AI/ML294infrastructure.295 