Tiles, OAM, and animation
Fighter art starts as four authored sheets on a shared 32×40 canvas. The generator slices 8×8 cells, removes transparent cells, deduplicates identical tiles, and also recognizes flipped variants. It emits compact visible-cell commands plus semantic frame and timing tables. The runtime does not scan a mostly transparent canvas during battle.
Generated source data
Animation timeline viewer
Choose a fighter and action, then scrub the authored frame timeline. Poses and frame durations come from generated fighter metadata; attack windows come from the matching character specification.
Orange means collision is active for a melee action. Projectile specials launch on accepted input; their visual timeline is not projectile startup.

- W, then K: the bullet travels straight.
- He keeps the curl while airborne.
Frame choice has a priority order
Section titled “Frame choice has a priority order”draw_fighter() selects exactly one semantic pose. Hurt overrides everything. Rizer’s airborne curl overrides action poses while airborne. Otherwise special precedes jab; airborne non-Rizer fighters choose rise, apex, or fall from vertical velocity; grounded motion uses the authored walk cadence; idle alternates at its authored rate.
The viewer reads cadence from the four character.toml sources. It is a guide to generated tables, rather than a frame-exact preview of the PPU: hardware flips, OAM priority, game-frame phase, and character position are resolved by the ROM.
OAM is prepared for the next vblank
Section titled “OAM is prepared for the next vblank”NES sprite memory stores four bytes per entry: Y, tile, attributes, X. The runtime fills a RAM OAM buffer from packed cells, hides unused entries below the visible scanlines, then triggers DMA during vblank. Rendering follows simulation, so the next displayed frame matches the state that the test export reports.
The project budget is explicit: 244 deduplicated fighter tiles plus eight effect tiles leave four slots in the 256-tile sprite pattern table. Effects draw before fighters; Simon’s whip adds extension sprites only during active jab frames. draw_character_icon() recovers horizontal flip through attribute bits rather than storing another tile.
Screenshots verify presentation alongside state
Section titled “Screenshots verify presentation alongside state”The emulator suite reads rendered frame IDs at $06FE, then waits an additional game tick before saving a screenshot so the corresponding OAM buffer has reached the PPU. Fighter scenarios cover idle, movement, jump, jab, special, hurt, and recovery; Rizer includes all four curl poses. See fighter_tas.lua.
The source generator and the verification boundary are covered next in testing.