CoolFace
Datasetpublic

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.

sourceHugging Facecc-by-nc-4.0updated 5mo agoView on Hugging Face
0likes16downloads
README.md295 linesDownload Raw Back to root
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