--- title: "Spider" id: 69481 type: "computer_media" slug: "spider" url: "http://localhost/computer_media/spider/" markdown_url: "http://localhost/computer_media/spider.md" published_at: "2026-04-13T08:54:33+00:00" modified_at: "2026-04-13T17:56:09+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/04/SCR-20260413-ezuu.png" excerpt: "Guide a spider through three increasingly tricky stages — plughole, bath, and bathroom — using pixel-perfect collision detection and procedurally generated obstacles." 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/SPIDER%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198" images: - url: "http://localhost/wp-content/uploads/2026/04/SCR-20260413-ezuu.png" - url: "http://localhost/wp-content/uploads/2026/04/SCR-20260413-fagh.png" media_type_tags: "Game" --- Spider is a three-stage game in which the player controls a spider navigating through a plughole, across a bath, and out of a bathroom. The program defines two UDG characters using eight bytes each loaded via POKE USR “b”+z in a setup loop, and it uses USR base (where base is calculated from PEEK 23635/23636) to perform pixel-level collision detection by reading character data back from the display file. The main plughole section (lines 100–330) moves two drips down the screen while the player repositions the spider using keys 5, 7, and 8. The bath-descent section (lines 820–1170) uses an INPUT for bath height and simulates swinging on a web with directional keys 1–9 mapped to swing positions. The bathroom escape sequence (lines 1370–1810) adds randomly placed obstacles and tracks how many times the player collides, incrementing a “lumbered” counter with humorous item names drawn from a DATA list. *** ## Program Analysis ### Program Structure The program is organized into three distinct games accessed sequentially, with a shared instruction menu starting at line 2200. The main flow is: 1. Lines 0–20: UDG initialization and base address calculation 2. Lines 30–550: Game 1 — The Plughole (main spider/drip gameplay loop) 3. Lines 560–620: Death/game-over handler 4. Lines 630–810: Game 1 completion screen 5. Lines 820–1170: Game 2 — The Bath (web-swinging descent) 6. Lines 1180–1810: Game 3 — The Bathroom (escape with obstacle avoidance) 7. Lines 1820–2190: Final exit animation 8. Lines 2200–2780: Instructions menu and sub-page display routines ### UDG Setup and Collision Detection Line 10 calculates `base` from `PEEK 23635` and `PEEK 23636`, which are the system variables holding the display file address. Adding 5 offsets into the character cell under the cursor position after a bare `PRINT AT x,y;` statement. This is the standard technique for reading back a character’s pixel data from the display file to perform collision detection without a separate sprite array. Line 20 loads 24 bytes into UDG “b” (two UDG slots, “b” and the next), defining the spider sprite as alternating checkerboard patterns (85=01010101, 170=10101010) with a solid midline (255). The DATA at line 20 also references variable `a` mid-list (the lowercase letter `a` in the DATA statement is likely a typo or corruption that would cause a syntax error or unexpected value at runtime). Collision detection throughout the program follows the pattern: - `PRINT AT x,y;` (bare print positions the cursor without output) - `USR base` reads the pixel byte at that screen position - Comparisons against 0, 32, 128–138 detect empty, space, or graphic characters ### Game 1 — The Plughole The plughole screens (lines 340–480) are randomly generated using `RND`: each of 22 rows is filled with a block-graphic string, with a gap inserted at one of two positions depending on whether `RND` falls below 0.3 or above 0.7, giving three possible row patterns. The player sprite `s$` is set at line 80 as a two-character string using block graphics. Two drips (`d1x`/`d1y` and `d2x`/`d2y`) descend independently. Drip 2’s advance is gated by `c>rnd` (line 140), where `c` is an incrementing counter and `rnd` is a fixed random threshold set per screen — this creates variable drip speed. Movement uses keys 5 (left), 8 (right), and 7 (up), with the up move restricted to columns 13–15 (line 310). Line 300 uses the Boolean arithmetic idiom `LET y=y+(INKEY$="8" AND USR base <>0)`, combining a keypress test and a collision check into a single assignment. Line 290 uses `PI` (≈3.14159, truncated to 3 by integer context) as a literal constant for `y+3`, which is an unusual but functional substitution. ### Game 2 — The Bath After completing five plughole screens, the player enters the bath descent at line 820. The player inputs a target height `r` (100–1000) and the spider descends, printing random UDG characters (CHR$ 129–137) as obstacles on row 21. The swing mechanic in the subroutine at line 1030 iterates from column 15 to a target column derived from `a-38` (where `a` is the key code), stepping toward or away from center based on whether the key code is below 53 (key “5”). Line 960 uses `POKE 23692,255` to reset the scroll counter, preventing the “scroll?” prompt from appearing during intensive printing activity. The bare `PRINT AT 21,0'` (with apostrophe) forces a newline which would otherwise trigger the scroll. ### Game 3 — The Bathroom The bathroom escape (lines 1380–1810) uses keys 5–8 to move the player `s$` (reset to `"*"` at line 1380). The goal marker “D” is placed near the bottom-right corner. Obstacles are block graphic characters (CHR$ 128–138) randomly placed; hitting one invokes subroutine 1710, which adds a new obstacle, increments a “lumbered” counter `h`, and prints a humorous item name from a DATA list at line 1760. Three collisions end the game. The movement at lines 1600–1610 uses the Boolean arithmetic idiom for all four directions simultaneously, adding/subtracting the results of INKEY$ comparisons for keys 5, 6, 7, 8. ### Instruction Menu The instruction system at line 2240 presents a choice of five options. Line 2290 uses `PRINT (VAL a$*100)+2200` which prints a number (e.g., 2300, 2400, 2500, 2600, 2700) rather than performing a GO TO — this appears to be a bug where the intended `GO TO` was omitted, causing execution to fall through to line 2300 regardless of selection. The individual instruction pages are at lines 2300, 2400, 2500, and 2600, each falling through to line 2360 which waits for a keypress before returning to the menu. ### Notable Techniques and Anomalies - The `base` calculation via PEEK of display-file system variables is a portable collision detection method that works regardless of where the display file sits in RAM. - `PI` is used as an integer constant (evaluating to 3) in lines 290 and 600, avoiding a literal `3` which costs more bytes to store in tokenized BASIC. - The random delay subroutine at line 1230 multiplies `RND` thirteen times to produce a very small number, effectively creating a near-zero busy-wait used for character-by-character print animation in the “NOW, ESCAPE FROM THE BATHROOM” sequence. - Line 240 reads `IF x=2 THEN GO SUB 120`, but line 120 is the spider print line rather than a subroutine — this is a `GO TO`/GO SUB mismatch that would cause a RETURN to send execution back to line 240 unexpectedly. - The DATA statement at line 20 contains bare variable name references (`a,a,a` and `a,a,a`) where numeric literals were presumably intended, which would cause a syntax or type error when `READ a` encounters them. - Line 1670 checks `IF c= CODE "[UDG-B]"`, comparing the collision value against the code of UDG “b” — this is the wall-detection branch that prevents horizontal movement into obstacles. - The exit animation at lines 1820–2190 draws a decorative room scene using block graphics and then loops `PRINT AT 12,10;"GOODBYE*=-"` indefinitely. ## Source Code ``` 0 REM [\*\$><(5(O0205*6\$ _###[\ #y*\! 10 LET base= PEEK 23635+256* PEEK 23636+5:RESTORE :FOR z=0 TO 23:READ a:POKE USR "b"+z,a:NEXT z 20 DATA 85,170,85,170,85,170,85,170,0,a,a,a,85,170,85,170,85,170,85,170,255,a,a,a 30 CLS 40 RANDOMIZE 50 GO SUB 2200 60 LET ult= INT (RND*5)+1 70 LET sc=0 80 LET s$="▚""▞" 90 GO SUB 340 100 GO SUB 490 110 GO SUB 520 120 PRINT AT x,y;s$ 130 PRINT AT d1x,d1y;" "; AT d2x,d2y;" " 140 IF c>rnd AND d2x <>20 THEN LET d2x=d2x+1 150 IF d2x=20 THEN GO SUB 520 160 IF d1x <>20 THEN LET d1x=d1x+1 170 IF d1x=20 THEN GO SUB 490 180 PRINT AT d1x,d1y; 190 IF USR base <>32 THEN GO TO 560 200 PRINT AT d2x,d2y; 210 IF USR base <>32 THEN GO TO 560 220 PRINT AT d1x,d1y;"[UDG-B]"; AT d2x,d2y;"[UDG-B]" 230 FOR a=1 TO 70:NEXT a 240 IF x=2 THEN GO SUB 120 250 IF INKEY$="" THEN GO TO 130 260 PRINT AT x,y;" " 270 PRINT AT x,y-1; 280 IF INKEY$="5" AND USR base <>0 THEN LET y=y-1 290 PRINT AT x,y+ PI; 300 LET y=y+(INKEY$="8" AND USR base <>0) 310 IF INKEY$="7" AND y>13 AND y<16 THEN LET x=x-1 320 LET c=c+1 330 GO TO 120 340 LET sc=sc+1 350 IF sc=5 THEN GO TO 630 360 CLS 370 LET rnd= INT (RND*9)+1 380 FOR l=0 TO 21 390 LET n$="████████████████████████████████" 400 LET rn= RND 410 IF rn<.3 THEN LET n$="███████████ ██████████████" 420 IF rn>.7 THEN LET n$="██████████████ ███████████" 430 PRINT n$ 440 NEXT l 450 LET x=20 460 LET y=15 470 PRINT AT x,y;s$ 480 RETURN 490 LET d1x=0 500 LET d1y=15+ INT (RND*3) 510 RETURN 520 LET d2y=15+ INT (RND*3) 530 LET c=0 540 LET d2x=c 550 RETURN 560 CLS 570 LET c$=" SCREENS" 580 IF sc=1 THEN LET c$=c$( TO 7) 590 PRINT AT 10,0;"THE TERRIBLE DROP HAS KILLED YOU" 600 PRINT AT 15, PI;"YOU WENT THROUGH ";sc;c$ 610 PRINT AT 5,13;"OUCH" 620 GO TO 610 630 CLS 640 FOR q=1 TO 15 650 PRINT "▐"; TAB 31;"▌" 660 NEXT q 670 PRINT "▟▄▄▄▄▄▄▄▄▄▄▄▄▄▄£ ▄▄▄▄▄▄▄▄▄▄▄▄▄▙" 680 FOR q=1 TO 6 690 PRINT "██████████████ ███████████████" 700 NEXT q 710 FOR q=21 TO 10 STEP -1 720 PRINT AT q,14;s$; AT q,14;" " 730 NEXT q 740 PRINT AT 12,0;"CONGRATULATIONS-YOU HAVE MADE IT" 750 PRINT 760 PRINT "DO█YOU█WISH█TO█DESCEND█FROM█THE██████BATH█ONTO█THE█FLOOR?" 770 IF INKEY$="" THEN GO TO 740 780 IF INKEY$="y" THEN RUN 820 790 PRINT 800 PRINT AT 16,12;"OKAY,BYE" 810 GO TO 810 820 CLS 830 PRINT AT 10,0;"INPUT HEIGHT OF BATH (100-1000)" 840 LET v=0 850 INPUT r 860 PRINT AT 10,0,, 870 LET s$="▚""▞" 880 LET x=10 890 LET y=15 900 PRINT AT 4,0;"[UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-D][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B]▐[UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B] LEN [UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B]▌[UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B]▐[UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-D][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B]▌[UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B][UDG-B]" 910 LET a= CODE INKEY$ 920 IF v >=r THEN GO TO 1180 930 IF a <>0 THEN GO SUB 1030 940 PRINT AT 21, INT (RND*31)+1; CHR$ (INT (RND*9)+129) 950 PRINT AT x,y;s$; AT x-1,15;" ▐ " 960 POKE 23692,255:PRINT AT 21,0' 970 PRINT AT x+1,y+1; 980 LET l= USR base 990 IF l>128 AND l<138 THEN GO TO 1150 1000 LET v=v+1 1010 GO TO 910 1020 IF l=32 THEN GO TO 1150 1030 LET z=x 1040 LET t=1 1050 IF a<53 THEN LET t=-1 1060 FOR b=15 TO (a-38) STEP t 1070 LET z=z-1 1080 PRINT AT z+1,b+1; 1090 IF USR base>128 AND USR base<138 THEN GO TO 1150 1100 LET v=v+1 1110 PRINT AT z,b;s$; AT z,b;" ▐ " 1120 POKE 23692,255:PRINT AT 21,0' 1130 NEXT b 1140 RETURN 1150 LET c$=" TURNS" 1160 LET sc=v 1170 GO TO 600 1180 FOR a=1 TO 200 1190 PRINT AT INT (RND*20)+1, INT (RND*21)+1;"WELL DONE" 1200 NEXT a 1210 CLS 1220 GO TO 1250 1230 LET time= RND* RND* RND* RND* RND* RND* RND*99* RND* RND* RND* RND* RND 1240 RETURN 1250 PRINT AT 5,0;"N"; 1260 GO SUB 1230 1270 PRINT "O"; 1280 GO SUB 1230 1290 PRINT "W"; 1300 GO SUB 1230 1310 PRINT ","; AT 10,5;"ESCAPE "; 1320 GO SUB 1230 1330 PRINT "FROM THE "; 1340 GO SUB 1230 1350 PRINT "BATHROOM" 1360 PAUSE 150 1370 CLS 1380 LET s$="*" 1390 LET s1=1 1400 LET s=s1 1410 FOR a=0 TO 31 1420 PRINT AT 0,a;"[UDG-B]"; AT 20,a;"[UDG-A]" 1430 IF a<20 THEN PRINT AT a,0;"[UDG-B]"; AT a,31;"[UDG-B]" 1440 NEXT a 1450 PRINT AT s,s1;s$; AT INT (RND*5)+14, INT (RND*4)+24;"D" 1460 LET a1=3 1470 LET h=0 1480 FOR a=1 TO a1 1490 LET o= INT (RND*20)+1 1500 LET o1= INT (RND*30)+1 1510 PRINT AT o,o1; 1520 IF USR base=0 THEN GO SUB 1710 1530 PRINT AT o,o1; CHR$ (INT (RND*11)+128) 1540 NEXT a 1550 LET t=s 1560 LET t1=s1 1570 GO TO 1600 1580 LET c= USR base 1590 RETURN 1600 LET t=t+(INKEY$="6")-(INKEY$="7") 1610 LET t1=t1+(INKEY$="8")-(INKEY$="5") 1620 PRINT AT t,t1; 1630 GO SUB 1580 1640 IF c= CODE "D" THEN GO TO 1820 1650 IF c>127 THEN GO SUB 1710 1660 PRINT AT s,s1;" " 1670 IF c= CODE "[UDG-B]" THEN GO TO 1690 1680 LET s1=t1 1690 PRINT AT s,s1;s$ 1700 GO TO 1480 1710 LET h=h+1 1720 IF h=3 THEN GO TO 1800 1730 PRINT AT INT (RND*5)+15, INT (RND*5)+26;"D" 1740 PRINT AT 21,0;"YOUR NOW LUMBERED WITH "; 1750 LET z= INT (RND*10)+1 1760 DATA "A TOWEL ","SOME SOAP","A COMB ","A BRUSH ","A GLASS ","A RAZOR ","A SPOON ","A FLANNEL","SHAMPOO " 1770 RESTORE 1760:FOR a=1 TO z:READ a$:NEXT a:PRINT a$ 1780 LET a1=a1+1 1790 RETURN 1800 PRINT AT INT (RND*20)+1, INT (RND*15)+1;"OUCH YOUR DEAD" 1810 GO TO 1800 1820 CLS 1830 FOR a=5 TO 19 1840 PRINT AT A,10;"██████████" 1850 NEXT a 1860 PRINT AT 12,17;"<=-" 1870 PRINT AT 5,20;"▘▘▘▘▘"; AT 19,20;"▖▖▖▖▖" 1880 PRINT AT 5,5;"▝▝▝▝▝"; AT 19,5;"▗▗▗▗▗" 1890 FOR a=0 TO 4 1900 PRINT AT a,a;"▞" 1910 PRINT AT a,29-a;"▚" 1920 NEXT a 1930 FOR a=20 TO 21 1940 PRINT AT a,24-a;"▚" 1950 PRINT AT a,5+a;"▞" 1960 NEXT a 1970 FOR a=5 TO 19 1980 IF a>5 AND a<19 THEN PRINT AT a,5;"▐"; AT a,24;"▌" 1990 PRINT AT a,17;"██ " 2000 NEXT a 2020 FOR a=21 TO 19 STEP -1 2030 PRINT AT 20,a;"▚""▞" 2040 FOR b=1 TO 10 2050 NEXT b 2060 PRINT AT 20,a;" " 2070 NEXT a 2080 PRINT AT 19,19;"""""▞▖" 2090 LET ss= RND* RND* RND* RND* RND* RND* RND* RND* RND* RND* RND* RND* RND 2100 PRINT AT 19,19;"▞▖" 2110 FOR a=1 TO 25 2120 NEXT a 2130 PRINT AT 19,19;"▖" 2140 FOR a=5 TO 19 2150 PRINT AT a,18;"██" 2160 NEXT a 2180 PRINT AT 12,10;"GOODBYE*=-" 2190 GO TO 2180 2200 PRINT AT 5,5;"INSTRUCTIONS? (Y/N)" 2210 IF INKEY$ <>"" THEN GO TO 2210 2220 IF INKEY$="" THEN GO TO 2220 2230 IF INKEY$="n" THEN RETURN 2240 CLS 2250 PRINT AT 5,5;"GAME 1...1"''" GAME 2...2"''" GAME 3...3"''" SCORING..4"''" TO BEGIN.5" 2260 LET a$= INKEY$ 2270 IF a$<"1" OR a$>"5" THEN GO TO 2260 2280 CLS 2290 PRINT (VAL a$*100)+2200 2300 PRINT TAB 5;"GAME 1-THG PLUGHOLE" 2310 PRINT "Beware of the drips and make it through 5 screens of plughole." 2320 PRINT " DIRECTIONS:" 2330 GO SUB 2670 2340 GO SUB 2700 2350 GO SUB 2730 2360 PRINT AT 21,10;"PRESS A KEY" 2370 GO TO 2640 2400 PRINT " GAME 2-THE BATH" 2410 PRINT "Swing on the web to avoid the obstacles placed in your path." 2420 PRINT " DIRECTIONS:" 2430 PRINT AT 6,0;"1 - FOUR SWINGS LEFT 2 - THREE SWINGS LEFT 3 - TWO SWINGS LEFT","4 - ONE SWING LEFT" 2440 PRINT '"5 - NEUTRAL POSITION" 2450 PRINT '"6 - ONE SWING RIGHT","7 - TWO SWINGS RIGHT","8 - THREE SWINGS RIGHT 9 - FOUR SWINGS RIGHT" 2460 GO TO 2360 2500 PRINT " GAME 3-THE BATHROOM" 2510 PRINT "Escape from the bathroom before you are lumbered with 3 objects." 2520 GO TO 2330 2600 PRINT " SCORING" 2610 PRINT AT 5,0;"GAME 1 - Screens passed"'''''"GAME 2 - How far down bath"'''''"GAME 3 - Most number of doors on screen loses" 2620 GO TO 2360 2630 RETURN 2640 IF INKEY$ <>"" THEN GO TO 2640 2650 IF INKEY$="" THEN GO TO 2650 2660 GO TO 2240 2670 PRINT AT 4,2;"▚"; AT 5,1;"▚▄▄▄"; AT 6,1;"▞▀▀▀"; AT 7,2;"▞" 2680 PRINT AT 6,6;".....5" 2690 RETURN 2700 PRINT AT 4,29;"▞"; AT 5,27;"▄▄▄▞"; AT 6,27;"▀▀▀▚"; AT 7,29;"▚" 2710 PRINT AT 6,20;"8..... " 2720 RETURN 2730 PRINT AT 10,3;"▚▞"; AT 11,2;"▚▌▐▞"; TAB 3;"▌▐"; TAB 3;"▌▐" 2740 PRINT AT 13,6;".....7" 2750 RETURN 2760 PRINT AT 10,28;"▌▐"; TAB 28;"▌▐"; TAB 27;"▞▌▐▚"; TAB 28;"▞▚" 2770 PRINT AT 13,20;"6....." 2780 RETURN ```