Skip to content

Arcade action: shoot 'em ups, platformers, beat 'em ups, fighting ​

Games where things come at the player every frame and the player steers, jumps, fires and dodges. They are streams with controls: the game drives and the player reacts. The game runs its rules inside one frame loop at a fixed rate.

Reference games ​

GameYear, platformWhy it is a good example
Tyrian 20001999, DOSVertical shooter in Borland Pascal; level event scripts, per-frame demos, an AdLib music driver (case study)
Commander Keen 41991, DOSSmooth-scrolling platformer on EGA; tile maps, sprite actors with state tables
Prince of Persia1989, DOSPlatformer with rotoscoped animation tables and exact frame timing
Jazz Jackrabbit1994, DOSFast platformer with a custom mode-X engine
Super Mario Bros.1985, NESSub-pixel physics in fixed point; well documented by speedrunners
Street Fighter II1991, arcadeFrame data, hit boxes, input buffers for special moves
Double Dragon1987, arcadeBeat 'em up: lanes, enemy waves, simple AI states

Projects to learn from ​

ProjectGameApproach
OmnispeakCommander Keen 4-6reimplementation from disassembly
SDLPoPPrince of Persiareimplementation based on a disassembly
OpenTyrianTyrian 2.1source port (the original Pascal source was released, then converted to C)
OpenClawCaptain Clawreimplementation
OpenTitusTitus the Fox, Moktarreimplementation
sm64 (n64decomp)Super Mario 64matching decompilation
MAMEthousands of arcade gamesemulation of the hardware; its drivers document each board

The rule set ​

What must be exact. The order of the steps in a frame; positions in the game's own units (often fixed point, sub-pixels); collision boxes and the order of collision tests; animation frame counts; every random draw. Speedrunners and players notice a one-frame difference.

Where the rules live. In code, in the frame loop and the actor update functions. Levels are data: tile maps, enemy placement, and often an event script (a list of "at position n, do x" records) that starts waves, changes speed and ends the level. Weapon and enemy stats are usually tables. Read the tables and the event format before porting the code that uses them.

Inputs. Keys, joystick and mouse, read once a frame in most games. A demo is the input of each frame plus the starting seed. Fighting games buffer the last few frames of input to detect special moves. Port the buffer length and the matching rules exactly.

Interface. The HUD (score, lives, energy bars) is drawn by the frame, usually straight to video memory. Menus, shops and the title screen are separate loops. Fonts are the game's own bitmaps. Port each screen from its code.

Time and determinism. A fixed rate set by a timer interrupt or the display's refresh (70 Hz on VGA mode 13h; 60 Hz on NTSC consoles; 50 Hz on PAL). If the game waits for the vertical retrace, the refresh rate sets its speed. On consoles and arcade boards, a port may need to copy the slowdown (fewer updates when the screen is busy).

How to verify. Play the game's own demos in the original and in the port, and compare every frame's state and screen. Fuzz the frame's fragments from real states (random enemies, shots, positions) to reach branches the demos never reach. Check collision code with many random pairs of boxes.

Pitfalls.

  • An actor list processed in slot order, with new actors taking the first free slot: the slot order changes who is drawn on top and who is hit first.
  • Hit tests against the previous frame's positions.
  • Integer division and shifts on negative positions (see ABI).
  • Palette effects (flashes, fades, colour cycling) are part of the frame and are easy to miss.
  • Music and sound effects often run on their own timer interrupt at a different rate from the frame.

Connections ​

Code: Apache 2.0. Content: CC0 1.0. No game material: bring your own copy.