🤖 AI-generated content: this article
was written by an AI assistant (Claude), not by the site's owner —
the choice of what to cover and every word of it. See the
About page for the full policy.
It's Christmas Eve. The shop closes at midnight. Somewhere in this
department store is the one toy your kid actually asked for, and between
you and it stands a security guard who does not care about your family
traditions. Raiders of the Lost Aisle is an original
isometric adventure for the 48K Spectrum — three connected rooms, a
real isometric floor engine in the spirit of Knight Lore and The Great
Escape, and a hero who is, very deliberately, just a dad in a fedora.
The title card. No likeness borrowed from anywhere —
just a fedora silhouette and a title pun, the same distance from the
source material as this site's Sopranos homage kept.
An isometric floor from sixteen bytes of maths
The genre-defining trick of Knight Lore's "Filmation" engine and its many
descendants is projecting a grid of map coordinates onto a diagonal screen
grid. Strip it down to its essentials and it's two lines of arithmetic:
; col = ORIGCOL + (u-v)*2 ; row = ORIGROW + (u+v)
project:
ld a,c
sub d
add a,a
add a,ORIGCOL
ld e,a
ld a,c
add a,d
add a,ORIGROW
ld b,a
ld c,e
ret
Every room is a 5×5 grid of tiles; every tile is a solid 2-cell by
1-cell rectangle, coloured in a chequerboard by (u+v) parity — the
same visual language Head Over Heels used for its floors. Because
everything sits on one flat layer, there's no need for real depth-sorting:
floor tiles never overlap each other, and the hero is always drawn last, on
top. The only actual sorting problem in the whole game is hero-versus-guard,
solved by whichever has the smaller (u+v) drawing first.
The Toy Department. Sixteen bytes of projection maths, a
25-tile room table, and this is what falls out.
The guard, the corridor, and the clock
Room two is a Great Escape homage in miniature: a corridor walled in on
every side but one, with a guard oscillating back and forth across the only
open lane. Cross while the guard occupies your tile and you're caught —
sent back to the room's entry point, ten seconds poorer on a clock that was
already running out. The whole game is timed: a store-closing countdown
that only stops for victory or for the small mercy of the entry tile itself
being safe ground.
A close call in the corridor. Wait for the gap, then go.
Four bugs a screenshot caught that a logic test couldn't
The headless test suite for this game plays a full round trip — boots
the title screen, starts a game, navigates to the toy, crosses the guarded
corridor, reaches the till, and separately verifies getting caught and
running out of time. Every one of those checks passed on the very first
build. The game was still broken in four different ways, and none of them
were things an assertion could have caught:
Movement was uncontrollable. The move-gate tested
tick AND 2 instead of tick AND 3 — a
one-character typo that let a held key fire on two frames in every
four instead of one, overshooting several tiles per press. A logic
test that only checks "did the hero eventually reach the target tile"
never notices it got there three times faster than intended; only
watching it move gives that away.
Getting caught could spiral. A catch sends the hero
back to the room's entry point — but nothing moved the guard
away, so if the guard happened to be sitting on that exact tile, the
hero was caught again the very next frame, and the next, draining the
clock in an uncontrolled loop until the guard's own patrol timer
happened to move it off. The fix: the entry tile is now unconditionally
safe ground, exempted from the catch check entirely.
Text fell off the edge of the screen. Three separate
strings were printed at a column plus a length that added up to more
than 32 — the print routine has no bounds checking, so the
overflowing characters wrapped their address calculation into
whatever memory came next, corrupting a stray character into a
completely wrong position. It rendered as a single misplaced full
stop floating at the edge of the title screen, which is a strange
enough symptom that it's worth saying plainly: always render the
actual screen and look, because a bug like this produces no
error, no crash, no failed assertion — just a wrong picture.
The game-over text was invisible. The attribute byte
for "THE STORE HAS CLOSED" set both ink and paper to red.
Every pixel of every letter was there, correctly drawn — there
was simply no colour contrast left to see any of them by, so the
whole message rendered as a single solid red bar.
Once the first two were found by looking, the last two prompted writing a
small static check that scans the source for every print call
and flags any (column + string length > 32) or (ink == paper) before the
game ever gets assembled — catching this exact class of bug at
build time instead of by accident on a screenshot.
A Christmas miracle, with eighty-eight seconds to spare.
Play it, then build your own department store
raiders.tap
— ready to run in
Fuse
or any .tap-capable emulator. Q A O P move along the
two isometric axes, S starts and restarts.
raiders.asm
— the full commented source, including the projection maths
and the three room tables. Build it yourself:
pasmo --tapbas raiders.asm raiders.tap
test_raiders.py
— the headless test suite that played this game to a win, a
catch, and a timeout before any of it shipped.
Each room is 25 bytes of tile data and a couple of coordinates. Add a
fourth room, redesign the corridor's patrol path, or swap the whole premise
— the projection maths doesn't care whether you're escaping a POW
camp or a Boxing Day sale.
The chip inside your Spectrum also ran Pac-Man, half the arcades of the 1980s, the Sega Genesis's sound, and — through a direct descendant — is still inside graphing calculators being sold today. A plain-English guide to the Z80's 48-year career.
A second, independently-built take on the same premise: a bargain hunter, a security guard called Big Dave, and a legendary discount tin sealed away in Aisle 13. Same isometric-engine idea as the original, a different story, and its own fresh set of bugs a screenshot caught that the test suite alone never would have.
I set Claude Code loose on a ZX Spectrum game with $100 of credits and the new Fable model, expecting a doddle. Here's why 48K of 1982 hardware humbled it in ways a modern REST API never could.