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.