--- title: "Dam Buster" id: 71011 type: "computer_media" slug: "dam-buster" url: "http://localhost/computer_media/dam-buster/" markdown_url: "http://localhost/computer_media/dam-buster.md" published_at: "2026-08-25T13:52:53+00:00" modified_at: "2026-08-25T13:56:38+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/dambuster.png" alt: "Dam Buster screen" excerpt: "Guide your bomber across a scrolling landscape, drop bombs onto the dam using joystick control, and chase a persistent high score in this sprite-based action game." 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/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Dam%20Buster%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "Dam Buster (198x)(-)(TS2068)(US)(Program).tap" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/dambuster.png" alt: "Dam Buster screen" --- # Dam Buster Dam Buster is a side-scrolling bomber game in which the player pilots an aircraft across a landscape and drops bombs onto a dam. The plane sprite is composed of four UDGs (A–D), with additional UDGs for bomb drop animation (E, F, G) and the dam structure (H, I), all defined by 72 bytes of DATA POKEd into USR memory at lines 630–740. Joystick input is read via STICK to trigger bomb release, and SCREEN$ collision detection is used both to detect dam hits and to track whether the bomb has cleared the structure. Scoring increments each horizontal step, with a 100-point bonus awarded for completing a full pass, and a persistent high-score variable survives between games within the same session. *** ### Program Structure The program is organized into a main loop and several subroutines. Execution begins at line 10, which calls the UDG initialization routine (line 630) and sets the high-score variable `hi` to zero. Lines 20–160 form the core game loop, iterating over rows (`v`, 1–15) and columns (`h`, 0–31) to scroll the plane across the screen. Key subroutines are: - **Line 170** – Draws the plane sprite (four UDGs A–D) at position `(v, h)`. - **Line 180–420** – Handles bomb drop animation and collision with the dam. - **Line 430–460** – Handles the plane-hits-dam explosion sequence. - **Line 470** – Awards a 100-point completion bonus and displays “GAME OVER”. - **Line 480–520** – Displays scores and waits for joystick restart. - **Line 540–600** – Draws the dam using UDGs H and I with PAPER coloring. - **Line 610–620** – Initializes display and resets per-game variables. - **Line 630–650** – POKEs all nine UDG bitmaps into memory. - **Lines 660–750** – DATA statements for UDG bitmaps, with a REM at line 750 mapping letter labels to UDG characters. ### UDG Definition and Sprite Design Nine UDGs (A through I) are defined by 72 bytes of DATA across lines 660–740. The subroutine at line 630 uses a `FOR` loop from 0 to 71, READing each byte and POKEing it to `USR "[UDG-A]" + a`, which fills UDGs A–I sequentially since each UDG occupies 8 bytes. UDGs A–D form the four-character-wide plane body; E and F are used for the bomb-drop entry frames; G is the falling bomb; H and I construct the dam wall. The DATA contains several entries labeled `u` — these appear to be a placeholder or token artifact and would read as the value of an uninitialized or re-used variable `u` at runtime, likely evaluating to 0, effectively producing blank rows in some sprite frames. ### Collision Detection via SCREEN$ The game relies entirely on `SCREEN$` for collision detection rather than coordinate mathematics. At line 80, `SCREEN$(v, h+6)` is tested: if it is not a space, the plane has struck the dam and execution jumps to the explosion handler at line 430. During the bomb drop (lines 270–330), `SCREEN$(b+2, b1)` is checked each row to detect whether the bomb has hit the dam structure below. This approach is straightforward but ties gameplay logic directly to screen state, meaning any stray character could trigger a false collision. ### Bomb Drop Mechanics When the player fires (STICK input at line 90), the subroutine at line 180 is called. The bomb is animated downward in a `FOR b` loop (lines 260–330), printing the bomb UDG one row at a time while simultaneously advancing the plane position (`h` and `v` are incremented at lines 200, 230, 300). A BEEP with pitch `b` provides audio feedback on each row of descent. If the bomb reaches the bottom without hitting anything, the loop exits cleanly at line 340–360; if a collision is detected, lines 370–420 handle a small secondary animation and return. The horizontal bomb position `b1` is fixed at the release column, while the plane continues moving. ### Scoring and State Management The score variable `sc` is incremented by 1 at line 100 for every column the plane advances, rewarding survival distance. A bonus of 100 is added at line 470 for completing a full pass. The high score `hi` persists across games in the same session (set once at line 10, updated at line 490). The variable `ch` acts as a one-shot flag: initialized to 1 at line 620, it is cleared to 0 at line 130 when the dam opening is detected, gating a sound effect at line 110 using the AND idiom (`.008 AND ch=1`). ### Key BASIC Idioms - **Boolean AND arithmetic**: Lines 110 uses `(.008 AND ch=1)+(.01 AND ch=0)` to select a BEEP duration based on the flag, avoiding an IF/THEN branch. - **Inline screen clearing**: PRINT strings of spaces with PAPER attributes erase sprites without CLS, preserving other screen content. - **STICK polling**: Lines 90 and 510 read joystick port 2 direction 2 to detect fire/action input. - **Trailing comma in PRINT**: Line 580 ends with a comma to suppress the newline, and line 600 uses `PRINT PAPER 2,,` with double commas for tab advancement when drawing the dam’s base rows. ### Anomalies and Notable Points - The DATA values labeled `u` at lines 660–740 are syntactically valid BASIC — `u` is read as a numeric variable. If `u` is never assigned, it defaults to 0, making those sprite rows blank. This is likely intentional for padding but could be confusing as source code. - Line 530 (`INPUT "Press ENTER to play again."; LINE a$: GO TO 20`) is unreachable — execution never falls through to it because line 520 loops back to 510 indefinitely. The restart path goes through line 510’s STICK check directly to line 20. - The plane position variables `v` and `h` are modified inside the bomb-drop subroutine (lines 200, 230, 300), causing the plane to advance while the bomb is in flight. This produces a realistic offset but means the outer loop’s `NEXT h` at line 140 continues from the already-advanced `h` value. - Line 80 checks `SCREEN$(v, h+6)` rather than `h` itself, accounting for the four-UDG width of the plane sprite to detect the leading edge of the dam. ## Source Code ``` 10 GO SUB 630:LET hi=0 20 GO SUB 610 30 GO SUB 540 40 FOR v=1 TO 15 50 PRINT AT v-1,0; PAPER 8;" " 60 FOR h=0 TO 31 70 GO SUB 170 80 IF SCREEN$ (v,h+6) <>" " THEN GO TO 430 90 IF STICK (2,2)=1 THEN GO SUB 180 100 LET sc=sc+1 110 BEEP (.008 AND ch=1)+(.01 AND ch=0),0 120 IF ch=0 THEN GO TO 140 130 IF (SCREEN$ (13,16)=" " AND SCREEN$ (13,17)=" " AND SCREEN$ (13,18)=" ") THEN LET ch=0:PRINT AT 13,0;" "; AT 14,20; INK 2; PAPER 1;"[UDG-H] "; AT 13,16; PAPER 0;" " 140 NEXT h 150 NEXT v 160 GO TO 470 170 PRINT AT v,h; INK 6; PAPER 8;" [UDG-A][UDG-B][UDG-C][UDG-D]":RETURN 180 PRINT AT v+1,h; INK 5; PAPER 8;" [UDG-E]" 190 GO SUB 170 200 LET h=h+1:IF h>30 THEN LET v=v+1:LET h=0 210 PRINT AT v+1,h; INK 5; PAPER 8;" [UDG-F]" 220 GO SUB 170 230 LET h=h+1:IF h>30 THEN LET v=v+1:LET h=0 240 PRINT AT v+2,h; PAPER 8; INK 6;" " 250 LET b1=h 260 FOR b=v+1 TO 14 270 BEEP .01,b 280 PRINT AT b,b1; PAPER 8; INK 5;" "; AT b+1,b1;"[UDG-G]" 290 GO SUB 170 300 LET h=h+1:IF h>30 THEN LET v=v+1:LET h=0 310 IF SCREEN$ (b+2,b1) <>" " THEN GO TO 370 320 PRINT AT v-1,31;" " 330 NEXT b 340 PRINT AT b,b1; PAPER 8;" " 350 LET h=h-1 360 RETURN 370 FOR b=b TO b+1 380 PRINT AT b,b1; PAPER 8;" "; AT b+1,b1; INK 5;"[UDG-G]" 390 NEXT b 400 BEEP .005,-b 410 LET h=h-1:PRINT AT b,b1; PAPER 8;" " 420 RETURN 430 FOR a=v TO 15 440 PRINT AT a,h+1; PAPER 1;" "; AT a+1,h+1; INK 6;"[UDG-A][UDG-B][UDG-C][UDG-D]" 450 BEEP .5,-a:NEXT a 460 GO TO 480 470 LET sc=sc+100:PRINT AT 0,12;"GAME OVER" 480 PRINT AT 5,10;"You Scored ";sc 490 IF sc>hi THEN LET hi=sc 500 PRINT AT 10,6;"Highest Score ";hi 510 IF STICK (2,2)=1 THEN GO TO 20 520 GO TO 510 530 INPUT "Press ENTER to play again."; LINE a$:GO TO 20 540 CLS 550 PRINT AT 12,16; INK 2;"[UDG-I][UDG-H]" 560 PRINT PAPER 1;" "; INK 2;"[UDG-I][UDG-I]"; PAPER 0;"[UDG-H]" 570 PRINT PAPER 1;" "; INK 2;"[UDG-I][UDG-I][UDG-I][UDG-I]"; PAPER 0;"[UDG-H]" 580 PRINT PAPER 1;" "; INK 2;"[UDG-I][UDG-I][UDG-I][UDG-I][UDG-I][UDG-H]", 590 FOR a=1 TO 4 600 PRINT PAPER 2,,:NEXT a:RETURN 610 BORDER 0:PAPER 0:INK 9:CLS 620 LET sc=0:LET ch=1:RETURN 630 FOR a=0 TO 71 640 READ u:POKE USR "[UDG-A]"+a,u 650 NEXT a:RETURN 660 DATA 56,60,63,u,u,7,0,u 670 DATA 0,u,128,255,u,u,u,0 680 DATA 0,u,63,255,u,u,u,0 690 DATA 0,u,224,248,u,u,240,0 700 DATA 0,u,220,126,u,220,0,u 710 DATA 8,u,28,254,30,14,0,u 720 DATA 36,60,24,60,u,24,0,u 730 DATA 128,192,224,240,248,252,254,255 740 DATA 254,255,u,u,u,u,u,u 750 REM a=[UDG-A] b=[UDG-B] c=[UDG-C] d=[UDG-D] e=[UDG-E] f=[UDG-F] g=[UDG-G] h=[UDG-H] i=[UDG-I] ```