oct 2026 2 min read Rive · Luau · Gleam

rebuilding a NES battle game in one Rive file

the 2 player battle game hidden in Super Mario Bros. 3, rebuilt in Rive with RML and Luau. every rule and physics number comes from the disassembly.

mario battle fullscreen at 1080p, the stage inside a world map border
fullscreen at 1080p, never stretched out of shape

as kids, my friend and i played the Super Mario Bros. 3 battle mode.

so i rebuilt it. one .riv file, made with the Rive CLI. RML markup for the stage, the HUD and every component. Luau scripts for the simulation.

the rom decides

every rule and physics number is transcribed from the game’s disassembly. there’s one exception, the turn-around deceleration, and it’s listed in the docs.

the sim uses integer physics in sixteenths of a pixel, like the rom. so the jump takes 33 frames to its apex and reads 71 px. enemies walk at 0.375 px per frame, until they get up faster.

a round of mario battle

the lobby's host game form

a round, and the lobby where you host a game

one artboard per entity

the game is a 256x240 artboard. each entity gets its own component (the player, Spiny, Fighter Fly, Sidestepper, the POW, the fireballs), with one animation per pose and a small state machine driven by its view model.

scene/game.rml        the 256x240 artboard
scene/components/     one artboard per entity
scene/stages/         the art and a tile map per stage
scripts/game.luau     a fixed 60 step loop

playing online

online rooms play with rollback. your press shows after 2 frames (33 ms). the browser guesses what the others pressed, the same as last frame. when the real buttons come back different, it restores that frame and replays up to now.

from Larnaca to the server in Paris, lockstep showed my press after 83 ms. with rollback it’s 33 ms, whatever the distance.

you can play it with friends at mario-battle.fly.dev.

a fan project, non commercial. Mario, the characters, sprites, sounds and music belong to Nintendo.

← all notes questions? hello@loiclaudet.com