A longer storm can be data rather than a longer sequence of special-case instructions. We will replace the three meteors that new_game starts with a prepared course of one hundred meteors, released one at a time.
The event table lives after the sprite data in assets.inc, at meteor_events. At this stage each event has three bytes: X, speed, delay until the next event. WAVES equ 100 names the number of events. The event index is the new byte wave; it counts individual spawns, not a whole row of meteors.
Source · view and edit
Companion file: assets.inc
The include line reads this editable data when you assemble. Keep it beside your source for a local build.
Edit the source, then assemble.
Edits are saved in this browser. Keep a downloaded copy of work you want to keep.
Focus the Spectrum screen to use the keyboard, or hold these buttons. Assemble again for a fresh machine.
Run the program to inspect it. Editing source does not change the running machine.
wave- —
active_count- —
phase- —
pool_overflow- —
Read the active object records
These rows read the twenty-slot pool. Empty slots are omitted. The display samples RAM while the program runs, so values can change between observations.
| Slot | X | Y | Kind / active | Speed |
|---|
The X positions and speeds vary, but the table is fixed. Retry gives the same course. A host-side generator prepared the scattered values; the Spectrum is not choosing new random numbers during each run. Repeatability lets a player learn a route and lets us reproduce a failure.
Count down, then read a record
A second new byte, wave_timer, counts course steps until the next event. In new_game, ld a,20 and ld (wave_timer),a take the place of the three spawns. The main loop calls the new waves routine once per update, after the hull check. It returns at once when wave has reached WAVES. Otherwise it decrements the timer, and when that reaches zero it calculates the event address as meteor_events + wave*3, reads the three fields, and loads the next delay into the timer. Then it increments wave and jumps to spawn, whose RET returns straight to the main loop.
waves:
ld a,(wave)
cp WAVES
ret z
ld a,(wave_timer)
dec a
ld (wave_timer),a
ret nz
ld a,(wave)
ld e,a
ld d,0
ld hl,meteor_events
add hl,de
add hl,de
add hl,de
ld a,(hl)
ld (spawn_x),a
inc hl
ld a,(hl)
ld (spawn_speed),a
inc hl
ld a,(hl)
ld (wave_timer),a
ld a,(wave)
inc a
ld (wave),a
jp spawnThe multiplication here is three additions of the index to HL. It is short because the event record is only three bytes. When we later add drift and kind, the event stride must change with the data layout.
A delay belongs to the event just read: it says how long to wait after this spawn before reading the next. The initial twenty-step wait comes from new_game, before any event has been read.
Do not finish while the last meteor is falling
Reaching WAVES means there are no more events to read. It does not mean the screen is clear. The completion check in the main loop now asks both questions: has wave reached WAVES, and is active_count zero? Either answer “no” branches to the new label race_continue and the next update.
call waves
call count_objects
ld a,(wave)
cp WAVES
jr nz,race_continue
ld a,(active_count)
or a
jr nz,race_continue
jp won
race_continue:
jp main_loopWatch the final spawn on a successful route: wave reaches 100 while active_count remains positive. The game keeps updating those objects until they leave. Contact is checked before the completion decision, so a fatal hit does not become a win just because the table is exhausted.
The final event's speed is 2 and it spawns at y=24. Can the game finish on that spawn's step?
Show the explanation
No. The new meteor is active and still near the top. At that speed it needs seventy-five movement updates to reach retirement at y=174. Event exhaustion and object exhaustion describe different things.
For a shorter experiment, set WAVES equ 3 without deleting the longer table. The program reads only the first three entries. The third, X=42 at speed 4, is read on update 36, but CLEAR SPACE waits until update 74, when that meteor passes y=174. Steer through them and check that it waits for the last object. Restore 100 to play the full meteor-only course. Do not increase WAVES beyond the number of complete records: the routine trusts that bound.
Sources
The maintained Meteor Storm source linked through this page supplies the game rules and data layout. Its experiments run original Z80 instructions on an emulated 48K PAL Spectrum; the game rules are design choices, not hardware properties.
Run it here
This unit's program, built for you.
- Program
- meteor-storm.tap
- Machine
- ZX Spectrum 48K (PAL)