From 2e44facdf1da5524f47272267aa0db26288be52e Mon Sep 17 00:00:00 2001 From: arudaev Date: Sun, 25 Oct 2026 12:08:45 +0100 Subject: [PATCH] test(player): the locomotion transitions as GIFs from the game's own code trace.ts runs movement.ts, jump.ts and animation.ts as player.ts wires them (flat ground, 120 Hz) through idle-walk-idle, walk-run-walk-run, idle-run-idle, idle-jump-land and run-jump-land-run; transition_gifs.py draws each at 30 fps with ground ticks that move with the world. Every clip switch moves the outline no more than the cycle's own frame step (#156). --- docs/09-ART-PIPELINE.md | 1 + .../transitions/idle-jump-land.gif | Bin 0 -> 340533 bytes .../transitions/idle-run-idle.gif | Bin 0 -> 405025 bytes .../transitions/idle-walk-idle.gif | Bin 0 -> 211739 bytes .../transitions/run-jump-land-run.gif | Bin 0 -> 516040 bytes game/verification/transitions/trace.ts | 64 +++++++++++ .../transitions/walk-run-walk-run.gif | Bin 0 -> 490858 bytes scripts/test_transition_gifs.py | 24 ++++ scripts/transition_gifs.py | 103 ++++++++++++++++++ 9 files changed, 192 insertions(+) create mode 100644 game/verification/transitions/idle-jump-land.gif create mode 100644 game/verification/transitions/idle-run-idle.gif create mode 100644 game/verification/transitions/idle-walk-idle.gif create mode 100644 game/verification/transitions/run-jump-land-run.gif create mode 100644 game/verification/transitions/trace.ts create mode 100644 game/verification/transitions/walk-run-walk-run.gif create mode 100644 scripts/test_transition_gifs.py create mode 100644 scripts/transition_gifs.py diff --git a/docs/09-ART-PIPELINE.md b/docs/09-ART-PIPELINE.md index 7b49693..170a65d 100644 --- a/docs/09-ART-PIPELINE.md +++ b/docs/09-ART-PIPELINE.md @@ -280,6 +280,7 @@ The team's open question in A14: how do generated frames move without looking li 4. **Smears instead of blends** for fast motion: one stretched smear frame on the chair swing and the knockback, as in Spider-Verse. No motion blur or warp. 5. **One grid, one palette.** Everything is crushed to the same pixel scale and 96-colour palette, and the feet are anchored to one baseline row, so frames don't wobble. 6. **Preview before approval.** Every sheet gets a looping preview at game size on its review page. A frame that pops is redrawn on its own against its neighbours as inputs. +7. **Check the switches in motion.** `python scripts/transition_gifs.py` runs the game's own movement, jump and animation code (`game/verification/transitions/trace.ts`) through idle ↔ walk ↔ run ↔ jump ↔ land and draws each transition as a GIF at 30 fps, with ground ticks every foot that move with the world. A foot that slides against the ticks slides in the game; a clip switch should move the outline no more than the cycle's own frame-to-frame step. ## The crossing (no animation budget) diff --git a/game/verification/transitions/idle-jump-land.gif b/game/verification/transitions/idle-jump-land.gif new file mode 100644 index 0000000000000000000000000000000000000000..bdd11b16bce5a2e51b1951b8bbebe6d10badcb55 GIT binary patch literal 340533 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