--- title: "FIRE" id: 70781 type: "computer_media" slug: "fire" url: "http://localhost/computer_media/fire/" markdown_url: "http://localhost/computer_media/fire.md" published_at: "2026-08-23T15:08:07+00:00" modified_at: "2026-08-23T20:16:26+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/fire.png" alt: "FIRE screen" excerpt: "Navigate a firefighter through a spreading blaze while your oxygen drains — one wrong move and the flames will surround you completely." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/FIRE%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "FIRE (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/fire.png" alt: "FIRE screen" media_type_tags: "Game" --- # FIRE FIRE is a maze-building survival game where the player navigates a firefighter (“+”) around a grid while fire (“E” characters, displayed in magenta on red) spreads randomly and an oxygen meter counts down. The 21×31 string array `a$` serves as a collision map, tracking which cells are blocked by fire (represented internally as the block graphic “█”). Each move, one of four adjacent cells is randomly selected via a computed GO SUB (lines 190–220) to receive a new fire tile, gradually surrounding the player. The oxygen display uses PAPER and FLASH attributes triggered by the expression `(e<20)` to create a visual warning when oxygen drops below 20 units. *** ### Program Structure The program is organized into a main game loop with an initialization subroutine and four fire-spreading subroutines: 1. **Lines 5–10:** Title REM and global initialization (colors, variables, call to setup at line 1000). 2. **Line 20:** Per-level reset — clears the collision array `a$`, resets position, increments level `r`, replenishes oxygen `e`, and places a new target at random coordinates (`m`, `n`). 3. **Lines 30–40:** Display pass — prints the HUD (score, oxygen, level) and draws the target “E” tile four times for emphasis, then erases the player’s old position. 4. **Lines 50–180:** Main game loop — reads input, moves the player, checks win/lose conditions, decrements oxygen, then calls a random fire-spread subroutine before looping back to line 30. 5. **Lines 190–220:** Fire-spread subroutines, one per cardinal direction, each marking a cell in `a$` and printing a colored block character. 6. **Lines 1000–1060:** Setup subroutine that defines the target character `b$` as “E”. ### Collision Detection via String Array The 21×31 string array `a$(21,31)` acts as a 2D collision map. Fire-spread subroutines write the block graphic `"█"` into the relevant cell, and movement checks (lines 60–90) test adjacent cells in `a$` before allowing motion. This avoids any need for SCREEN$ reads and is efficient for a BASIC collision system. ### Computed GO SUB Line 170 picks a random direction index `rl` from 1 to 4, and line 180 dispatches with `GO SUB (rl*10)+180`, targeting lines 190, 200, 210, or 220. This is a compact dispatch table idiom that avoids a chain of IF statements. ### Key Variables | Variable | Role | | --- | --- | | `x`, `y` | Player row and column | | `e` | Oxygen level (starts at 50, +25 per level) | | `r` | Level counter | | `s` | Score (100 per target found, +1 per move) | | `m`, `n` | Column and row of the target tile | | `rl` | Random direction index (1–4) | | `a$` | 21×31 collision map string array | | `b$` | Target character (“E”), set in the setup subroutine | ### HUD and Attribute Tricks Line 30 uses the Boolean expression `(e<20)`, which evaluates to 1 (true) or 0 (false), directly inside `PAPER` and `FLASH` to activate a red flashing oxygen warning without any IF statement. `PAPER (e<20)*2` gives PAPER 2 (red) when oxygen is critical, and `FLASH (e<20)` enables flashing simultaneously. ### Fire Spread Subroutines Lines 190–220 each handle one direction. They write into `a$`, emit a short BEEP, and print a block graphic in a different INK color per direction (cyan, green, red, magenta), creating a colorful fire effect. No bounds checking is performed before writing adjacent cells, which can cause an index-out-of-range error if the player is at the edge of the screen (row 0, row 20, column 0, or column 30) when a fire tile is placed adjacent to them. ### Trapping Detection Line 130 checks all four immediate neighbors of the player in `a$` for the fire block character. If all four are blocked, the game declares the player trapped and stops. This is a simple but effective dead-end detection that matches the game’s stated lose condition. ### Bugs and Anomalies - The collision array `a$` is declared as `DIM a$(21,31)` inside line 20, which is inside the main game loop. `DIM` is legal here and reinitializes the array each level, but it is unusual placement. - The fire-spread subroutines (lines 190–220) do not guard against out-of-bounds array indices. If `x` is 1, accessing `a$(x-1,y)` (row 0) will cause an error, and similarly for the other boundaries. - Line 40 draws the target tile four times with a short delay loop between each draw (`FOR a=1 TO 3: NEXT a`), but the practical visual effect is negligible at normal Spectrum speeds — it appears to be vestigial animation code. - Line 180 uses `GO TO 30` immediately after the `GO SUB` dispatch, so it acts as a fall-through back to the display loop rather than a true subroutine call structure; the RETURN in each fire subroutine correctly returns to line 180, which then immediately jumps to 30. - The setup subroutine at line 1000 defines `b$="E"` but spans from 1000 to 1060 with only a RETURN at 1060, leaving lines 1010–1059 undefined. This is harmless but wastes line-number space. ## Source Code ``` 5 REM "FIRE" 10 INK 7: PAPER 0: BORDER 0: CLS : GO SUB 1000: LET e=50: LET r=0: LET s=0 20 DIM a$(21,31): CLS : LET c=0: LET r=r+1: LET x=10: LET y=15: LET e=e+25: LET m=INT (RND*28)+2: LET n=INT (RND*18)+2 30 PRINT AT x,y; INK 5;"+";AT 0,0; INK 7;"SCORE="; PAPER (e<20)*2; FLASH (e<20);" OXYGEN=";e; PAPER 0; FLASH 0;" level=";r;" " 40 FOR b=1 TO 4: LET a$(n,m)=b$: PRINT AT n,m; INK 5; PAPER 1;b$: FOR a=1 TO 3: NEXT a: NEXT b: PRINT AT x,y;" " 50 LET f$=INKEY$ 60 IF a$(x,y-1)<>"█" AND f$="5" AND y>2 THEN LET y=y-1 70 IF a$(x,y+1)<>"█" AND f$="8" AND y<39 THEN LET y=y+1 80 IF a$(x+1,y)<>"█" AND f$="6" AND x<20 THEN LET x=x+1 90 IF a$(x-1,y)<>"█" AND f$="7" AND x>2 THEN LET x=x-1 100 IF n=x AND m=y THEN LET s=s+100: PRINT AT 21,0;"WELL DONE !!": FOR m=10 TO 40: BEEP .01,m: NEXT m: GO TO 20 110 IF e<=0 THEN PRINT AT 21,0;"OUT OF OXYGEN : GAMEOVER": STOP 120 LET e=e-1 130 IF a$(x-1,y)="█" AND a$(x+1,y)="█" AND a$(x,y-1)="█" AND a$(x,y+1)="█" THEN PRINT AT 21,0;"YOU ARE TRAPPED : GAMEOVER": STOP 140 IF f$="" THEN GO TO 30 150 LET s=s+1 160 LET rl=INT (RND*4)+1 170 GO SUB (rl*10)+180 180 GO TO 30 190 LET a$(x-1,y)="█": BEEP .01,40: PRINT AT x-1,y; INK 6;"█": RETURN 200 LET a$(x+1,y)="█": BEEP .01,40: PRINT AT x+1,y; INK 3;"█": RETURN 210 LET a$(x,y-1)="█": BEEP .01,42: PRINT AT x,y-1; INK 4;"█": RETURN 220 LET a$(x,y+1)="█": BEEP .01,43: PRINT AT x,y+1; INK 5;"█": RETURN 1000 LET b$="E" 1060 RETURN ```