LEAKING is a falling-drop catching game in which the player moves a bucket left and right to catch drips of water that fall from random horizontal positions on screen. The program defines ten custom UDG characters (stored at lines 310–430) to draw the drip sprite in three two-character rows and a two-cell bucket graphic. Scoring is checked at line 90 with a three-condition OR test that checks whether the bucket overlaps the drip at row 20, accommodating one or two column offsets. The game runs for 30 drips per round, tracks a session high score, and loops back for replay via an INPUT LINE prompt.
Program Structure
The program is organized into a main loop and three subroutines:
- Lines 10–150: Main game loop — initializes, runs 30 drips, and repeats.
- Lines 160–200: Game-over screen with score display and replay prompt.
- Lines 210–270: Screen setup — clears display and draws a four-row checkerboard background using UDGs
\aand\bin INK 2. - Lines 280–300: Variable initialization — resets
sc,v, andd. - Lines 310–430: UDG loader — reads 80 bytes from DATA statements and POKEs them into the ten UDG slots starting at
USR "\a".
UDG Graphics
Ten UDGs (\a through \j) are defined by the DATA at lines 340–430. Each UDG occupies 8 bytes, for 80 bytes total, loaded by the FOR a=0 TO 79 loop at line 310. The drip is drawn as a 2×3 character sprite using UDGs \c\d, \e\f and a two-space top row. The bucket at the bottom of the screen uses UDGs \g\h (top row) and \i\j (bottom row), displayed in INK 6 (yellow) at rows 20 and 21.
The checkerboard floor/ceiling pattern at lines 230–260 alternates \a\b pairs across all 32 columns for four rows, creating a tiled effect in INK 2 (red) on the black background.
Data Anomalies
The DATA statements contain several anomalies worth noting:
- Many entries use the token
u(unquoted), which the Spectrum BASIC interpreter would evaluate as the variableurather than a numeric literal. Sinceuis never assigned before the DATA is read, it defaults to 0. This is effectively a shorthand for zero in the pixel data. - Line 360 and line 380 contain
PIas a DATA value, which evaluates to approximately 3.14159 and is truncated to 3 byREAD u: POKE. This appears to be intentional pixel data for those specific bytes. - Line 420 uses
U(uppercase), which is a separate variable fromuand also uninitialized, so it also evaluates to 0.
Game Mechanics
Each drip cycle picks a random column p in the range 1–30 (INT(RND*30)+1) and animates the drip sprite falling from row 6 to row 18 via a FOR l=6 TO 18 loop. The bucket column v is updated inside the same loop at line 100, using INKEY$ checks for keys "8" (move right) and "5" (move left), with boundary clamping to keep v in 0–28.
The collision check at line 90 tests three overlap conditions using a compound IF with OR:
l+2=20 AND v+1=p+1— drip bottom row at 20, bucket left cell aligns with drip left celll+2=20 AND v+2=p+1— bucket right cell aligns with drip left celll+2=20 AND v+2=p— bucket right cell aligns with drip column directly
This gives a two-column catch window but misses a leftmost overlap case (v+1=p), meaning the bucket must be slightly to the right to score — a minor asymmetry in hit detection.
Scoring and High Score
The score sc is incremented on a successful catch and printed immediately at AT 0,0. After 30 drips (d=30), the game over routine at lines 160–200 compares sc to hi and updates the session high score. The variable hi is initialized only once at line 20 (LET hi=0), so it persists across replays within the same session. Replaying via the INPUT LINE prompt at line 200 branches to line 30, which re-initializes sc and d but preserves hi.
Notable BASIC Idioms
LET d=scat line 290 resetsdto 0 (sincescwas just set to 0) — an unusual indirect reset.- The boolean expression in line 100 uses the Spectrum idiom of multiplying a condition by a direction:
v=v+(INKEY$="8" AND v<28)-(INKEY$="5" AND v>0), where the AND conditions return 1 or 0. - The REM at line 440 documents the UDG-to-escape-sequence mapping, serving as an in-program reference for the developer.
Content
Source Code
10 REM *** Call The Plummer
20 GO SUB 310:LET hi=0
30 GO SUB 280
40 GO SUB 210
50 LET p= INT (RND*30)+1:LET d=d+1:PRINT AT 0,25;"Drip ";d
60 FOR l=6 TO 18
70 PRINT AT 20,v; INK 6;" \g\h "; AT 21,v;" \i\j "
80 PRINT AT l,p; INK 5;" "; AT l+1,p;"\c\d"; AT l+2,p;"\e\f"
90 IF l+2=20 AND v+1=p+1 OR l+2=20 AND v+2=p+1 OR l+2=20 AND v+2=p THEN LET sc=sc+1:PRINT AT 0,0;"SCORE ";sc
100 LET v=v+(INKEY$="8" AND v<28)-(INKEY$="5" AND v>0)
110 NEXT l
120 PRINT AT l,p;" "; AT l+1,p;" "
130 IF d=30 THEN GO TO 160
140 BEEP .01, INT (RND*10)+30
150 GO TO 50
160 PRINT AT 5,11;"GAME OVER"
170 PRINT ''''" You Scored ";sc
180 IF sc>hi THEN LET hi=sc
190 PRINT '''" Highest Score Today ";hi
200 INPUT "Press ENTER To Play Again."; LINE a$:GO TO 30
210 CLS
220 PRINT "SCORE ";sc
230 PRINT INK 2;"\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b"
240 PRINT INK 2;"\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a"
250 PRINT INK 2;"\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b"
260 PRINT INK 2;"\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a"
270 RETURN
280 BORDER 0:PAPER 0:INK 7:CLS :BRIGHT 0
290 LET sc=0:LET v=15:LET d=sc
300 RETURN
310 FOR a=0 TO 79
320 READ u:POKE USR "\a"+a,u
330 NEXT a:RETURN
340 DATA 255,u,u,u,u,u,0,u
350 DATA 252,u,u,u,u,u,0,u
360 DATA 0,u,u,u,u,1, PI,7
370 DATA 0,u,u,u,u,128,192,224
380 DATA 7,u,15,u,u,7,u, PI
390 DATA 224,u,240,u,u,224,u,192
400 DATA 0,u,127,63,95,111,119,59
410 DATA 0,u,254,u,253,251,u,246
420 DATA 62,63,U,u,31,u,u,u
430 DATA 14,254,u,u,252,u,u,u
440 REM a=\a b=\b c=\c d=\d e=\e f=\f g=\g h=\h i=\i j=\j
450 SAVE "LEAKING" LINE 10
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
