DROPABLOCK is a block-dropping crane simulation game in which the player purchases a crane, orders blocks, and drops them onto a construction platform during a simulated workday. The game uses 14 User-Defined Graphics (UDGs A through N), defined via a DATA/POKE loop at line 710 that writes 112 bytes into UDG memory to render cranes, blocks, and platform tiles. Gameplay tracks money (M), days elapsed (D), and block inventory (A), with economic consequences for damage events and a high-score comparison at session end. The screen layout combines PRINT AT, INK, BRIGHT, FLASH, and OVER attributes to produce a layered construction-site scene with scrolling crane movement driven by a floating-point X/Y position increment variable I.
Program Structure
The program is organized as a main game loop with several distinct phases handled by line ranges:
- Lines 10–20: Title REM and initialization subroutine call (line 710).
- Lines 30–60: Session setup — initializes high score, money, day counter, and routes end-of-day logic.
- Lines 70–90: Scene drawing — renders the construction platform using UDG characters and sets up the backdrop string
W$. - Lines 100–150: Equipment selection — player chooses between two crane types with different capacities and costs.
- Lines 160–230: Block ordering — player inputs how many blocks to buy, with money and capacity validation.
- Lines 240–390: Main gameplay loop — moves the crane horizontally, renders it, and polls
INKEY$for block drops. - Lines 400–510: Drop subroutine — animates a block falling from the crane to the platform level.
- Lines 520–570: End-of-day lorry sequence — a vehicle crosses the screen and triggers damage checks.
- Lines 580–670: Damage and lawsuit logic — handles collisions with yachts and falling lorry incidents.
- Lines 680–700: Profit/high-score reporting and replay.
- Lines 710–750: Initialization subroutine — sets display attributes, reads 112 bytes of UDG data, and POKEs them into UDG memory.
- Line 760:
SAVEwith autostart.
UDG Definitions
Line 710 uses a FOR N=0 TO 111 loop reading from DATA statements at lines 720–750, POKEing each byte into USR "[UDG-A]"+N. This defines 14 UDGs (A through N), covering crane arm parts ([UDG-A], [UDG-B]), truck/lorry shapes ([UDG-C], [UDG-D]), platform tiles ([UDG-E], [UDG-J]), and smaller crane type 2 graphics ([UDG-K], [UDG-L], [UDG-M], [UDG-N]).
Key Variables
| Variable | Role |
|---|---|
M | Player’s money (starts at 10000) |
D | Day counter (drives end-of-game condition at D=16) |
A | Block inventory count |
S | Crane type chosen (1 = large, 2 = small) |
I | Horizontal movement increment (1.0 for type 1, 0.5 for type 2) |
T | In-game clock (simulated minutes past 3:00 PM) |
Y | Crane horizontal position (floating point) |
X | Crane row (fixed at 2) |
N | Platform height (random, 2–14 rows from bottom) |
HI | High score (best profit across replays) |
SUE | Flag for yacht lawsuit event |
Notable BASIC Idioms
NOT PIevaluates to0(since PI is non-zero, NOT PI = 0); used throughout as a compact zero literal — e.g.,LET FU= NOT PI,PRINT AT NOT PI, NOT PI.SGN PIevaluates to1(since PI > 0); used to initializeD=1and setBRIGHT 1at line 710.FOR N= NOT PI TO VAL "RND*12+2"at line 70 usesVALof a string expression for the upper bound — this defers evaluation and is a known memory/token optimization.PAUSE NOT PI(i.e.,PAUSE 0) followed byGO TOacts as a keypress wait without an explicitINKEY$loop.
Gameplay Mechanics
The crane moves automatically from left to right across the screen; the player presses SPACE to drop a block. Block dropping is handled by the subroutine at line 400, which animates the block falling row by row using a FOR F loop with PRINT AT F,G, erasing the previous row each iteration. The crane type affects both the horizontal speed (I) and the time cost per block dropped (type 2 costs 2.5 time units vs. 0.5 for type 1).
The end-of-day trigger is when T >= 59 (representing 4:00 PM), after which a lorry animation runs across the screen at line 520. The lorry is randomly assigned one of several UDG patterns ([UDG-C], [UDG-D], or [UDG-G][UDG-H]), with the last variant only used when both platform inspection points show ATTR = 66 (INK 2, PAPER 0, BRIGHT 1 — a correctly loaded block attribute).
Damage and Economic Events
The damage subroutine at lines 580–670 uses both ATTR and SCREEN$ checks to detect collisions. If the lorry runs over a yacht (ATTR = 70), the player is fined $500 and sued for an additional $1500. If the lorry hits a block in its path (SCREEN$ non-space), it incurs $1500 damage. The falling subroutine at line 670 iterates from the platform top downward, calling line 580 for each row to check for obstructions.
Screen Layout and Attributes
The scene uses OVER 1 at line 90 to draw the road/ground overlay. FLASH 1 is used at end-of-day messages and the lower border status area (PRINT #1 writes to the lower screen). BRIGHT 0 at line 250 marks the lorry drop zones on the platform. The display column check at line 290 (IF INT Y>28) wraps the crane back to column 2 when it reaches the right edge.
Bugs and Anomalies
- Line 550 has a potential infinite loop:
IF P=3 AND ATTR(...)fails when the attribute condition is not met, causingGO TO 520which may again pick P=3, repeating indefinitely if the platform blocks are not correctly loaded. - The variable
INKis used as both a BASIC keyword and a numeric variable (e.g.,LET INK= INT (RND*6)+2at line 520). On the Spectrum,INKis a keyword/color modifier, so using it as a variable name this way is unconventional and may cause interpreter confusion depending on context. - Line 450 has
IF f=19-n THEN GO SUB 510:RETURN— theRETURNafterGO SUBexits the drop loop early when the block lands, which is intentional but means theNEXT Fat line 500 is not reached in that case. - Variable
FALis set at line 590 but never subsequently read, making it a dead assignment. - The lowercase variable names
s,x,y,iappear at lines 420–430, mixed with their uppercase equivalents elsewhere; on the Spectrum these are treated as distinct variables, which could cause unexpected behavior if the case is inconsistent.
Source Code
10 REM DROP A BLOCK
20 GO SUB 710
30 LET HI=10000
40 LET FU= NOT PI:LET A=fu:LET D= SGN PI:LET M=10000:LET V$="ANY KEY"
50 IF D=16 AND M<10000 THEN PRINT AT NOT PI, NOT PI;"NO PROFIT WAS MADE.YOU ARE FIRED"''"ANY KEY TO REPLAY":PAUSE NOT PI:GO TO 40
60 IF D=16 AND M >=10000 THEN GO SUB 680
70 CLS :FOR N= NOT PI TO VAL "RND*12+2":PRINT AT 21-N,1; INK 2;"[UDG-E][UDG-E] [UDG-E][UDG-E] [UDG-E][UDG-E] [UDG-E][UDG-E] [UDG-E][UDG-E]":NEXT N
80 PRINT AT 21-N-2,0;"[UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J][UDG-J]"; INK 2;"[UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-E][UDG-F][UDG-E][UDG-E][UDG-I] [UDG-F][UDG-E][UDG-E][UDG-I] [UDG-F][UDG-E][UDG-E][UDG-I] [UDG-F][UDG-E][UDG-E][UDG-I] [UDG-F][UDG-E][UDG-E][UDG-I]":LET W$=" "
90 PRINT AT 21,0; INK 5; OVER 1;" ":LET W$=W$+" "
100 LET SUE= NOT PI:LET X=2:LET Y=x:LET T=15:IF D>1 THEN GO TO 160
110 PRINT AT NOT PI, NOT PI;"1 [UDG-A][UDG-B] MAX CAPACITY 5 BLOCKS $3000"''"2 [UDG-K] MAX CAPACITY 3 BLOCKS $1000"'" [UDG-L]"
120 INPUT "1 OR 2? ";S
130 IF S>2 OR S<1 THEN GO TO 120
140 IF S=1 THEN LET M=M-3000:LET I=1:LET W$=W$+" "
150 IF S=2 THEN LET M=M-1000:LET I=.5:LET W$=W$+" "
160 FOR W=0 TO 3:PRINT AT W,0;W$:NEXT W:PRINT AT 0,0;"$";M; AT 0,10;"DAYS:";D; AT 0,20;"BLOCKS:";A:INPUT "HOW MANY BLOCKS:";AW
170 LET JK= INT (RND*2)+1:IF JK=1 THEN LET JK=5
180 IF JK=2 THEN LET JK=12
190 LET A=A+AW
200 IF S=1 AND A>5 THEN LET A=A-AW:GO TO 160
210 IF S=2 AND A>3 THEN LET A=A-AW:GO TO 160
220 LET M=M-AW*100
230 IF M<0 THEN PRINT AT 3,0;"YOU HAVEN'T ENOUGH MONEY":LET M=M+AW*100:LET A=A-AW:PAUSE 100:GO TO 160
240 LET J= INT (RND*25)+4:LET J1= INT (RND*25)+4
250 PRINT AT 21-N-1,J; BRIGHT 0;" "; AT 21-N-1,J1;" "
260 PRINT AT 0,0;"$";M;" "; AT 0,10;"DAYS:";D; AT 0,20;"BLOCKS:";A
270 PRINT AT 20,JK; INK 6;"[UDG-M][UDG-N]"; AT 20,JK+7;"[UDG-M][UDG-N]"
280 PRINT AT 0,0;"$";M;" "; AT 0,10;"DAYS:";D; AT 0,20;"BLOCKS:";A
290 IF INT Y>28 THEN PRINT AT X,Y;" ":LET Y=2
300 IF S=1 THEN PRINT AT X,Y; INK 5;" [UDG-A][UDG-B]":GO TO 330
310 IF S=2 THEN PRINT AT X,Y; INK 4;" [UDG-K]"; AT X+1,Y;" [UDG-L]"
320 IF S=2 THEN LET T=T+.4
330 PRINT AT 1,0;"TIME: 3:"; INT T
340 LET Y=Y+I
350 IF S=1 THEN LET T=T+.45
360 IF T >=59 THEN PRINT AT 1,6; FLASH 1;"4:00":GO TO 520
370 PRINT AT 3,30;" "
380 IF INKEY$=" " AND A <>0 THEN GO SUB 400
390 GO TO 290
400 LET A=A-1:LET G=Y:FOR F=X+2 TO 20:PRINT AT F,G; INK 2;"[UDG-E]"; AT F-1,G;" "
410 IF Y >=28 THEN PRINT AT X,Y;" ":LET Y=2
420 IF s=1 THEN PRINT AT x,y; INK 5;" [UDG-A][UDG-B]":LET y=y+i
430 IF s=2 THEN PRINT AT x,y; INK 4;" [UDG-K]"; AT x+1,y;" [UDG-L]":LET y=y+i
440 PRINT AT 3,29;" "
450 IF f=19-n THEN GO SUB 510:RETURN
460 PRINT AT 0,20;"BLOCKS:";A
470 IF S=1 THEN LET T=T+.5
480 IF S=2 THEN LET T=T+2.5
490 IF T >=59 THEN PRINT AT 1,6; FLASH 1;"4:00":GO TO 520
500 PRINT AT 1,0;"TIME: 3:"; INT T:NEXT F:RETURN
510 PRINT AT F+1,G; INK 2;"[UDG-E]"; AT F,G; INK 7;"[UDG-J]";:RETURN
520 LET P= INT (RND*3)+1:IF P=1 THEN LET A$="[UDG-C]":LET INK= INT (RND*6)+2:GO TO 560
530 IF P=2 THEN LET A$="[UDG-D]":LET INK= INT (RND*6)+2:GO TO 560
540 IF P=3 AND ATTR (21-N-1,J)=66 AND ATTR (21-N-1,J1)=66 THEN LET A$="[UDG-G][UDG-H]":LET INK=2:GO TO 560
550 GO TO 520
560 FOR T=1 TO 31:PRINT AT 21-N-2,T; INK INK;A$; AT 21-N-2,T-1; INK 7;"[UDG-J]":BEEP .05,10:IF SCREEN$ (21-N-1,T)=" " THEN GO SUB 670
570 NEXT T:LET D=D+1:LET M=M+1000:PRINT #1; TAB 12; FLASH 1;V$; FLASH 0:PAUSE 0:GO TO 50
580 IF ATTR (U,T)=70 THEN LET M=M-500:PRINT AT 19,T;" "; AT 20,T;"[UDG-D]"; AT 20,T; FLASH 1; OVER 1;"[UDG-E]":LET SUE=1:GO SUB 610
590 IF SCREEN$ (U,T) <>" " THEN PRINT AT 21-N-1,T; INK INK;A$; AT 21-N-2,T; INK 7;"[UDG-J]":LET FAL=1:GO TO 610
600 PRINT AT U-1,T;" ":RETURN
610 PRINT AT 1,0;"$1500 WORTH OF DAMAGE.":LET D=D+1:LET M=M-1500
620 IF U=20 OR U=21 THEN PRINT AT 20,T; INK 5; PAPER 7;"[UDG-A]"; AT 20,T; OVER 1;"[UDG-B]"
630 IF SUE=1 THEN PRINT AT 3,0;"YACHTSMAN SUES YOU FOR $500"
640 IF M <=0 THEN GO TO 660
650 PRINT #1; AT 1,12; FLASH 1;"ANY KEY":PAUSE 0:CLS :GO TO 50
660 CLS :PRINT AT 0,0;"YOU RAN OUT OF MONEY"''"PRESS ANY KEY TO REPLAY":PAUSE 0:CLS :GO TO 40
670 FOR U=21-N-1 TO 20:GO SUB 580:PRINT AT U,T; INK INK;A$; AT 21-N-2,T; INK 7;"[UDG-J]":BEEP .005,21-U:NEXT U:GO TO 610
680 PRINT "WELL DONE !!! YOU MADE A PROFIT OF ";M-10000;:IF M<HI THEN PRINT " ANY KEY TO REPLAY":GO TO 700
690 PRINT " YOU ARE THE BEST WORKER TODAY":LET HI=M:PRINT '"ANY KEY TO REPLAY"
700 PAUSE 0:CLS :GO TO 40
710 BORDER NOT PI:PAPER NOT PI:INK 7:BRIGHT SGN PI:CLS :RESTORE 720:FOR N=0 TO 111:READ A:POKE USR "[UDG-A]"+N,A:NEXT N:RETURN
720 DATA 129,192,255,131,0,0,0,0,255,16,252,226,241,62,36,255
730 DATA 0,0,0,56,36,255,153,102,0,0,254,255,241,255,153,102
740 DATA 247,247,247,0,127,127,127,0,247,119,55,0,31,15,7,0
750 DATA 255,255,255,255,255,153,102,102,224,108,106,106,255,201,54,54,247,246,244,0,112,96,64,0,0,0,0,255,16,16,16,16,60,94,191,191,94,94,60,36,36,60,60,60,0,0,0,0,0,0,12,12,8,127,63,31,128,192,224,240,128,254,252,248
760 SAVE "DROPABLOCK" LINE 2Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

