🤖 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.
The site already has one Raiders of the Lost Aisle — a
Christmas Eve toy-department heist. This is a second, separately-built game
under the same title and the same isometric-engine idea, with a different
story: it's Bank Holiday Monday, the discount shelves are down to the last
few tins, and legend has it Aisle 13 — sealed off since the Great
Stocktake — still holds one final, impossibly cheap prize. Security
guard Big Dave does not share your enthusiasm for bargains.
The title card. Same joke, different aisle.
The same dimetric trick, a second time
Both games place every object at a map position (x, y, height)
and project it onto the screen with the same dimetric formula: screen X from
the difference of the two ground axes, screen Y from their
sum, minus height. Rooms here are an 8×8 (Aisle 7) and a
6×6 grid (Aisle 13, the lost one), each object a small box drawn as two
stacked rectangles — a dark "base" at ground level and a bright "top"
shifted up by its height — everything sorted back-to-front each frame
by ground position so a shopper walks convincingly behind a shelving unit
without any real 3D renderer involved.
Aisle 7 — shelving, a trolley, the checkout, and Big Dave
on patrol.
Three bugs a screenshot caught that the test suite didn't
This game has its own headless test suite (test_raiders2.py,
built the same way as the rest of this site's Z80 programs: boot it, drive
it through real control flow via z80mini.py, assert on outcomes,
render the screen to PNG). Every logic assertion passed well before the game
actually looked right. Three separate bugs only showed up once the renders
were actually opened and looked at:
The title screen was completely blank. The print
routine read glyph data from the real Spectrum ROM's character set at
$3D00 — which works fine on real hardware and in a
full emulator, but z80mini.py is a from-scratch
interpreter with no ROM image loaded at all, so every glyph read came
back as zero. No crash, no failed assertion — a bare black
screen. The fix was switching to this codebase's own bundled 8×8
font (fontdata.inc, the same one the other programs here
use), which lives in the assembled program itself and doesn't depend
on anything being loaded at a fixed ROM address.
The floor rendered as a barcode. Clearing the play
area between rooms used a hand-rolled byte-fill loop that tested for
"done" with dec bc / ld a,b / or c — which
overwrites A with the remaining countdown value. The very
first byte in each row wrote a correct zero; every byte after that
wrote whatever was left of the countdown instead, producing a
decaying stripe pattern of stale pixel garbage under the next room's
freshly-drawn floor. This is the same bug class flagged elsewhere in
this codebase — a routine silently clobbering A as
a side effect of something that looks unrelated — just a fresh
instance of it. The fix doesn't route the fill value through
A at all: ld (hl),0 writes the constant
directly, leaving A free for the loop's own bookkeeping.
The guard could ambush the player the instant protection
ended. Not a rendering bug, but one only the full automated
playthrough surfaced: getting caught grants a brief invulnerability
window, but if the guard converged onto the player's exact tile
during that window (it keeps moving throughout) and was still
standing there the moment it expired, the very next frame caught the
player again with no time to react. The fix holds the grace timer at
1 rather than letting it lapse while the guard is still camped on the
player's own tile, so the countdown only actually runs once there's
genuinely space to escape into.
Aisle 13. Quiet, dusty, unguarded — the tin's right
there.
Caught, and paid in full
Getting caught sends the shopper back to Aisle 7's entrance, drops the tin
if they were carrying it, and starts that grace period. Reach the checkout
with the tin in hand and the till rings up a win.
Big Dave, doing his one job.Paid in full.
Play it, or read the other one
raiders2.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.
raiders2.asm
— the full commented source. Build it yourself:
pasmo --tapbas raiders2.asm raiders2.tap
test_raiders2.py
— the headless test suite, including the guard-catch and
invulnerability checks described above.
Or read the original Raiders
of the Lost Aisle, the Christmas Eve toy-department version this
one shares its engine idea with.
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.
Every Spectrum program you've ever typed says OUT 254 or IN 254. The ULA doesn't actually check for 254 — it barely checks anything at all. A tiny program proves it, live, on screen.
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.