File size: 10,671 Bytes
a6b0487 a30bee7 a6b0487 a30bee7 a6b0487 a30bee7 49c4c05 a30bee7 49c4c05 b2caa16 49c4c05 b2caa16 a30bee7 a6b0487 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 a6b0487 a30bee7 49c4c05 a30bee7 a6b0487 a30bee7 a6b0487 a30bee7 a6b0487 49c4c05 a30bee7 a6b0487 a30bee7 a6b0487 a30bee7 97ccaa3 49c4c05 a30bee7 49c4c05 a30bee7 a6b0487 49c4c05 a6b0487 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 a6b0487 a30bee7 a6b0487 a30bee7 a6b0487 a30bee7 49c4c05 a30bee7 a6b0487 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 49c4c05 a30bee7 a6b0487 49c4c05 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | ---
license: mit
tags:
- behavior-cloning
- imitation-learning
- super-smash-bros-melee
- reinforcement-learning
- gaming
library_name: pytorch
---
# MIMIC: Melee Imitation Model for Input Cloning
Behavior-cloned Super Smash Bros. Melee bots trained on human Slippi
replays. Eight character-specific ~20M-parameter transformers that take
a 180-frame window of game state and output controller inputs (main
stick, c-stick, shoulder, buttons) at 60 Hz. Each model plays over
Slippi Online Direct Connect through Dolphin + libmelee.
- **Repo**: https://github.com/erickfm/MIMIC
- **Training data**:
[erickfm/melee-ranked-replays](https://huggingface.co/datasets/erickfm/melee-ranked-replays)
β ranked Slippi replays (master/diamond/platinum tier) per character.
- **Base architecture**: Shaw-relative-position causal transformer
(d_model=512, 6 layers, 8 heads, seq_len=180). Bootstrapped from
[HAL](https://github.com/ericyuegu/hal) (Eric Gu) and since diverged.
- **Defining MIMIC changes over HAL**: 7-class button head with a
distinct TRIG class for airdodge/wavedash (HAL's 5-class head can't
represent airdodge and thus can't wavedash); v2 shard alignment that
fixes a subtle post-frame-gamestate leak in the training targets
(see `research-notes-2026-04-11c`); the digital-L-press fix in
`decode_and_press` (research notes 2026-04-13) without which no
7-class BC bot wavedashes.
## Current checkpoints (retrained on 2026-04-20 baseline)
Retrained on the post-schema-drop (13 numeric cols), new-transforms
(`tanh_scale` / `linear_max` / `log_max` for velocity / hitlag /
hitstun) basis. See `research-notes-2026-04-20.md` in the MIMIC repo
for methodology + results analysis.
| Character | Run | Train games | Val loss | Step |
|---|---|---|---|---|
| **Fox** | `fox-20260420-baseline` | 31,030 | 0.7144 | 32768 |
| **Falco** | `falco-20260420-baseline` | 20,882 | 0.7487 | 31392 |
| **Marth** | `marth-20260420-baseline` | 11,759 | 0.6664 | 31065 |
| **Sheik** | `sheik-20260420-baseline` | 51,751 | 0.6566 | 26160 |
| **Captain Falcon** | `cptfalcon-20260420-baseline` | 17,557 | 0.7368 | watchdog |
| **Luigi** | `luigi-20260420-baseline` | 2,290 | 0.7460 | watchdog |
**Peach**, **Jigglypuff**, and **Ice Climbers** remain on pre-2026-04-20
schemas:
- `peach-20260420-baseline` (val 0.6322) was trained on the 22-col
schema before the schema drop β loadable via its pickled config.
- `puff` and `ice_climbers` missed the 2026-04-20 retrain cycle due
to a download-script bug; their existing HF checkpoints are on the
old schema. **These two are incompatible with the current 13-col
inference code path.** Will be retrained in a follow-on cycle.
## Repo layout
```
MIMIC/
βββ README.md # this file
βββ fox/
β βββ model.pt # raw PyTorch checkpoint
β βββ config.json # ModelConfig (copied from ckpt["config"])
β βββ metadata.json # provenance (step, val metrics, notes)
β βββ mimic_norm.json # per-feature transforms + params
β βββ controller_combos.json # 7-class button combo spec
β βββ cat_maps.json
β βββ stick_clusters.json
β βββ norm_stats.json # per-column mean/std (z-score fallback)
βββ falco/ (same layout)
βββ marth/ (same layout)
βββ sheik/ (same layout)
βββ cptfalcon/ (same layout)
βββ luigi/ (same layout)
βββ puff/ (same layout)
βββ ice_climbers/(same layout)
βββ peach/ (same layout, pre-drop schema β retrain pending)
```
Each character directory is self-contained β the JSONs are the exact
metadata used during training, copied verbatim from the data dir so
any inference script can load them without touching the MIMIC repo.
## Usage
```bash
git clone https://github.com/erickfm/MIMIC.git
cd MIMIC
bash setup.sh # installs Dolphin, deps, ISO
# Download all characters
python3 -c "
from huggingface_hub import snapshot_download
snapshot_download('erickfm/MIMIC', local_dir='./hf_checkpoints')
"
```
Run a character against a level-9 CPU:
```bash
python3 tools/play_vs_cpu.py \
--checkpoint hf_checkpoints/marth/model.pt \
--dolphin-path ./emulator/squashfs-root/usr/bin/dolphin-emu \
--iso-path ./melee.iso \
--data-dir hf_checkpoints/marth \
--character MARTH --cpu-character FOX --cpu-level 9 \
--stage FINAL_DESTINATION
```
Or play a bot over Slippi Online Direct Connect:
```bash
python3 tools/play_netplay.py \
--checkpoint hf_checkpoints/sheik/model.pt \
--dolphin-path ./emulator/squashfs-root/usr/bin/dolphin-emu \
--iso-path ./melee.iso \
--data-dir hf_checkpoints/sheik \
--character SHEIK \
--connect-code YOUR#123
```
The MIMIC repo also includes a Discord bot frontend
(`tools/discord_bot.py`) that queues direct-connect matches per user.
See [docs/discord-bot-setup.md](https://github.com/erickfm/MIMIC/blob/main/docs/discord-bot-setup.md).
## Architecture
```
Slippi frame βββΊ MimicFlatEncoder (Linear 184β512) βββΊ 512-d per-frame vector
β
180-frame window βββΊ + Shaw Relative-Position attention βββββ
β
6Γ Pre-Norm Causal Transformer Blocks (512-d, 8 heads, d_ff=2048, GELU, LN)
β
Autoregressive Output Heads (with detach)
β
ββββββββββββββββΌββββββββββββββββ¬βββββββββββββ
shoulder(3) c_stick(9) main_stick(37) buttons(7)
```
### 7-class button head
| Class | Meaning |
|---|---|
| 0 | A |
| 1 | B |
| 2 | Z |
| 3 | JUMP (X or Y) |
| 4 | TRIG (digital L or R) |
| 5 | A_TRIG (shield grab) |
| 6 | NONE |
HAL's original 5-class head (A / B / Jump / Z / None) has no TRIG class
and structurally can't execute airdodge, which means HAL-lineage bots
can't wavedash. MIMIC's 7-class encoding plus a fix for
`decode_and_press` (which was silently dropping the digital L press
until 2026-04-13) is what enables the wavedashing in the replays.
### Input features (per frame, per player)
Numeric (13):
pos_x, pos_y, percent, stock, jumps_left,
speed_air_x_self, speed_ground_x_self,
speed_x_attack, speed_y_attack, speed_y_self,
hitlag_left, hitstun_left,
shield_strength
Flags (5):
on_ground, off_stage, facing, invulnerable, moonwalkwarning
Per-feature normalization is defined in each character's
`mimic_norm.json`. The active transforms are:
| transform | formula | used for |
|---|---|---|
| `normalize` | `2(x-min)/(max-min) - 1` β [-1, +1] | percent, stock, jumps_left, facing, invulnerable, on_ground |
| `standardize` | `(x - mean) / std` | pos_x, pos_y |
| `invert_normalize` | `2(max-x)/(max-min) - 1` | shield_strength (so "shield broken" is +1) |
| `tanh_scale` | `tanh(x / scale)` | 5 velocities (scale=5 for self, scale=10 for attack) |
| `linear_max` | `x / max` | hitlag_left (max=20) |
| `log_max` | `log1p(clamp(x,0,max)) / log1p(max)` | hitstun_left (max=120) |
Plus categorical embeddings: stage(4d), 2Γ character(12d),
2Γ action(32d). Plus the previous-frame controller state as a 56-dim
one-hot (37 stick + 9 c-stick + 7 button + 3 shoulder).
Total input per frame: **184 dimensions** β projected to 512.
Earlier builds (pre-2026-04-20) used a 22-col numeric schema that
included `invuln_left` and 8 ECB corners. Those columns turned out to
be structurally zero for our .slp parse path β libmelee never
populates them β so they were dropped from the schema. See research
notes 2026-04-20 for the audit. Checkpoints trained pre-drop
(`peach-20260420-baseline`) still load via their own pickled config
but use the 202-dim projection path.
## Training
- Model preset: `mimic` (20M params)
- Optimizer: AdamW, LR 3e-4, weight decay 0.01, **no warmup**
- LR schedule: `CosineAnnealingLR` to `eta_min=1e-6`
- Gradient clip: 1.0
- Dropout: 0.2
- Sequence length: **180 frames** (~3 seconds)
- Batch size: 256 per-GPU Γ 2 RTX 5090s Γ grad-accum 1 = **eff-batch 512**
- Mixed precision: BF16 AMP with FP32 upcast for relpos attention
(prevents BF16 overflow in the manual Q@Kα΅ + S_rel computation)
- Max samples: 16.78M (β 32,768 steps at eff-batch 512)
- Watchdog: patience=12 evals on val-plateau β some chars finish early
- Reaction delay: 0. v2 shards have `target[i] = buttons[i+1]`, so
`rd=0` matches inference β do NOT use `--reaction-delay 1` or
`--controller-offset` with v2 shards.
- `--self-inputs` is required even on v2 shards. Runs without it
drop the controller-history input entirely and land at val loss ~2.3.
Typical wall-clock per char on 2ΓRTX 5090: 10-15 min download/extract
+ 20 min parallel `norm_stats` bootstrap + 45-120 min sharding
(depending on char, cptfalcon and sheik are the longest) + ~50 min
training = 2-4 hours.
## Known limitations
1. **Character-locked.** Each model only plays the character it was
trained on. No matchup generalization. Multi-character training
with a character embedding is a natural next step but not done.
2. **Small-dataset overfitting on Luigi / Ice Climbers.** Luigi has
~2K training games; IC around 5K. Their `_bestloss.pt` is
early-stopped β either by the patience=12 watchdog during this
cycle or by inspection in prior cycles. Play quality varies.
3. **Edge guarding and recovery weaknesses.** Bots don't consistently
go for off-stage edge guards or execute high-skill recovery
mixups. The training data has these in it, but BC bots under-sample
long-tail strategic decisions.
4. **No Matchmaking / Ranked.** The Discord bot only joins explicit
Direct Connect lobbies. Do NOT adapt it for Slippi Online Unranked
or Ranked β libmelee's README explicitly forbids bots on those
ladders, and Slippi has not yet opened a "bot account" opt-in
system.
## Acknowledgments
- **Eric Gu** for [HAL](https://github.com/ericyuegu/hal), the
reference implementation MIMIC is based on. HAL's architecture,
tokenization, and training pipeline are the foundation.
- **Vlad Firoiu and collaborators** for
[libmelee](https://github.com/altf4/libmelee), the Python interface
to Dolphin + Slippi.
- **Project Slippi** for the Slippi Dolphin fork, replay format, and
Direct Connect rollback netplay. https://slippi.gg
## License
MIT β see the MIMIC repo's `LICENSE` file.
|