Part 2 got Ken's idle stance rendering in Marvel vs. Capcom — one animation chain out of 245. This part takes it to six, which sounds incremental and is really three separate problems: knowing which chain an input drives, finding out the engine doesn't choose the way you'd assume, and finding out why a correctly-seated frame can still never appear on screen.

You cannot seat what you cannot name
The project I inherited had a CHAIN_MAP.md with 245 rows, every one marked UNVERIFIED_LIVE.
That isn't a map. So before seating anything I built one by measurement: a harness that holds
each movement input in a real match and logs every (anim, list) pair the engine actually
enters, with how long it held.
The first run was nearly useless. The CPU opponent interrupts constantly, so hit-reaction chains appeared under every action and outscored the real ones. The fix was blunt: hold the opponent out of range every frame.
With the noise gone the structure fell out immediately: movement chains cluster in
$1199xx–$11A5xx, and the chains that had been contaminating everything cluster in
$11B6xx–$11C2xx and are hit reactions. That separation is why differencing against a
neutral baseline works at all.
The engine picks by facing, not by direction
Two of my traces disagreed about which chain was "walk forward" and which was "walk back". Not noise — they genuinely produced different answers.
The engine selects by forward or backward relative to which way the character is facing, not by which direction key is held. My traces had the opponent on opposite sides, so "press right" meant forward in one and backward in the other. Both were correct for their run.
Any directional row from a trace is only meaningful together with where the opponent was. Merge two traces naively and you get a map that is confidently, silently mirrored. The clean trace pins facing by holding the opponent to one side, which is what makes its labels authoritative.
The one longword that decided everything
With six chains identified I seated a Ken frame on each and repointed the first record. Then only three of six rendered.
The obvious explanation is that the missing three are transient — records the engine passes
through too fast to catch. That story dies on the numbers: jump_up captured at 5.3% dwell
while walk_fwd missed at 8.7%. Whatever separated them, it wasn't how long the chain was
live.
The answer was one longword. Each animation record is 16 bytes, so a record's +16 is the next
record's first field. Dumping that field across all six:
crouch $11A402 +16 = 0011A402 <- pointer, back to itself
jump_up $119D9A +16 = 00119D8A <- pointer
idle $119846 +16 = 00000003 <- an ordinary record
walk_fwd $11A4C2 +16 = 00008002 <- an ordinary record
walk_back $1199DA +16 = 00000006 <- an ordinary recordWhen that field is a ROM pointer, the chain loops. Crouch and jump_up loop back onto their own first record natively — and those were exactly the states that showed up. The others run straight past the single frame I seated, back into Gambit's art.
Part 2's standing build worked for precisely this reason, and I hadn't understood why at the time: it wrote a self-loop. Writing one for each chain that doesn't already have one took it from three to six in a single rebuild:
SHOT idle anim=119846 list=507E00
SHOT walk_fwd anim=11A4C2 list=507ECE
SHOT walk_back anim=1199DA list=507F84
SHOT crouch anim=11A402 list=508046
SHOT jump_up anim=119D9A list=5080F0
SHOT jump_fwd anim=119F42 list=508152
CAPTURED 6 statesEvery line there is gated: the harness only shoots when the live animation pointer equals the
chain that state was seated on, and asserts P1's fighter id is $0A every frame. A shot cannot
be a Gambit frame taken by accident.

The palette got worse, and that's the interesting part
Every Ken frame draws through Gambit's single 16-entry palette row. So the fifteen colours have to be fitted across all six frames at once, not per frame — quantizing each independently would give each an optimal palette the others then have to live with.
That's a real regression in fidelity, and it gets worse with every state added. It's the first hard constraint this project has hit that more care won't solve — it needs either a second palette row or a smarter shared quantization, and that decision is coming.
Bounds
- One frame per state, not animation. Each state holds a single pose; walking looks like gliding. Animating them means walking each chain's records and seating a frame per record.
- The self-loops are destructive. Looping a chain on its first record overwrites the next record's first field. For a single-frame seat that's the intended trade; real animation needs those records preserved and repointed instead.
- 20 chain rows are still
CANDIDATE. They survive the baseline filter in one run only. I'm not promoting them on one witness — that's the mistake the original map made 245 times. - Nothing about identity, sound, or attacks has been touched.
Next
Attacks and specials — hadouken and shoryuken — which is where a chain stops being a list of pictures and starts having entry conditions. Then his 3rd Strike voice and SFX.
Six chains down. He walks, crouches, and jumps, all in his own art.