--- title: "LEAKING" id: 71204 type: "computer_media" slug: "leaking" url: "http://localhost/computer_media/leaking/" markdown_url: "http://localhost/computer_media/leaking.md" published_at: "2026-08-31T08:56:58+00:00" modified_at: "2026-08-31T08:56:58+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/08/leaking.png" alt: "LEAKING screen" excerpt: "Guide your bucket across the screen to catch 30 random drips of water — can you beat your own high score in this quick arcade challenge?" 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/LEAKING%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/08/leaking.png" alt: "LEAKING screen" media_type_tags: "Game" --- # LEAKING 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: 1. **Lines 10–150:** Main game loop — initializes, runs 30 drips, and repeats. 2. **Lines 160–200:** Game-over screen with score display and replay prompt. 3. **Lines 210–270:** Screen setup — clears display and draws a four-row checkerboard background using UDGs `\a` and `\b` in INK 2. 4. **Lines 280–300:** Variable initialization — resets `sc`, `v`, and `d`. 5. **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 variable `u` rather than a numeric literal. Since `u` is 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 `PI` as a DATA value, which evaluates to approximately 3.14159 and is truncated to 3 by `READ u: POKE`. This appears to be intentional pixel data for those specific bytes. - Line 420 uses `U` (uppercase), which is a separate variable from `u` and 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 cell - `l+2=20 AND v+2=p+1` — bucket right cell aligns with drip left cell - `l+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=sc` at line 290 resets `d` to 0 (since `sc` was 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. ## 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 ```