--- title: "New York by Night" id: 55142 type: "computer_media" slug: "new-york-by-night" url: "http://localhost/computer_media/new-york-by-night/" markdown_url: "http://localhost/computer_media/new-york-by-night.md" published_at: "2024-06-17T00:30:03+00:00" modified_at: "2026-03-30T21:44:18+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/06/SCR-20240616-rufj.png" excerpt: "Guide your antimatter flying disc against waves of descending aliens threatening a procedurally generated nighttime cityscape, with difficulty levels and UDG sprite graphics." 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/" indiv: - name: "George Chambers" slug: "george-chambers" taxonomy: "indiv" url: "http://localhost/indiv/george-chambers/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 54965 title: "ISTUG Public Domain Library 5" type: "computer_media" url: "http://localhost/computer_media/istug-public-domain-library-5/" - id: 55430 title: "Timex Sinclair Public Domain Library Tape 2004" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-2004/" media_type: "Program" programmers: - name: "George Chambers" slug: "george-chambers" taxonomy: "indiv" url: "http://localhost/indiv/george-chambers/" mediadate: "1983" images: - url: "http://localhost/wp-content/uploads/2024/06/SCR-20240616-rufj.png" - url: "http://localhost/wp-content/uploads/2024/06/SCR-20240616-rtng.png" - url: "http://localhost/wp-content/uploads/2024/06/SCR-20240616-ruoe.png" media_type_tags: "Game" --- # New York by Night “New York By Night” is a Space Invaders-style arcade game in which the player controls a flying disc that destroys descending aliens before they can flatten New York City. The game uses three custom User Defined Graphics (UDGs) — characters A, m, and n/c — whose 8-byte shape data is POKEd directly into the UDG area at startup via READ/DATA statements. Gameplay difficulty is selectable from level 2 to 8 at startup, with the variable `le` controlling the depth range of alien drops. The skyline is generated procedurally using random PLOT calls, and collision detection relies on reading screen attribute bytes with ATTR rather than tracking sprite coordinates, a common Spectrum technique. Attack waves are tracked with variable `aw`, and the game ends when 27 aliens (`i=27`) have been destroyed, triggering a city-destruction animation sequence. *** ## Program Analysis ### Program Structure The program is organized into two broad phases: an initialization/setup subroutine starting at line `620`, called via `GO SUB 620` at line `50`, and the main game loop beginning at line `60`. Control flow is largely managed through `GO TO` jumps rather than structured loops, which is typical for action games of this era. 1. **Lines 50–80:** Call setup, set border/paper/ink, draw the random starfield and city skyline. 2. **Lines 90–120:** Build the buildings column by column using UDG characters printed at incrementing column `z`. 3. **Lines 130–320:** Main game loop — player movement, alien drop, collision detection, scoring. 4. **Lines 330–550:** Hit/miss resolution, wave completion, alien landing animation, and transition logic. 5. **Lines 560–610:** End-of-game sequence, “another game?” prompt, and port-cycling sound effect. 6. **Lines 620–870:** Setup subroutine — variable initialization, UDG definition, instructions display, difficulty selection. ### User Defined Graphics (UDGs) Three UDG characters are defined by POKEing 8-byte shape data into the UDG memory area. The setup loop at line `660` reads 32 bytes from the DATA statements at lines `670`–`700` and POKEs them starting at `USR "A"`, defining UDGs A and B (16 bytes each, covering characters A and B). A second loop at line `710` reads 16 bytes into `USR "m"`, defining UDG m. | UDG | Lines | Used as | | --- | --- | --- | | `\a` (A) | 670–680 | Alien sprite | | `\c` (C) / `\b` (B) | 670–700 | Building tiles / disc hit effect | | `\m` (m) | 720–730 | Player flying disc / ship animation | | `\n` (n) | (shares m block) | Ship animation frame | Note that the DATA at lines `690` and `700` contain the bare variable name `s` rather than a numeric literal in two positions (e.g., `60,126,153,s,255,...`). At READ time, `s` will hold whatever value it was last assigned in the loop (the previous byte read), so these act as self-referential fill values — an unintentional but functional quirk. ### Collision Detection via ATTR Rather than maintaining sprite coordinate tables, collision detection at line `280` reads the screen attribute byte at the player’s disc position using `ATTR (x,y)` and `ATTR (x,y+1)`, checking for the value `71` (INK 7, PAPER 0, BRIGHT 1 — the building color). Similarly, line `290` checks `ATTR (k,l)=68` to detect when a falling alien lands on the city floor. This attribute-based collision approach avoids any coordinate bookkeeping for the static city geometry. ### Key BASIC Idioms and Techniques - **Variable reuse for zero-initialization:** Line `630` sets `j=0`, then reuses `j` to initialize `sc`, `bh`, and `k` at lines `640`–`650`, saving tokenized bytes. - **Building construction loop:** Lines `90`–`120` increment column `z` and print UDG characters vertically using a FOR loop, building up the skyline one column at a time until `z>=29`. - **Port-cycling sound:** Line `590` loops `OUT 254,b` for b=0 to 224, producing a sweeping border-color sound effect by toggling the EAR/MIC bits of the ULA port. - **Starfield generation:** Line `70` uses 50 random BRIGHT 0 PLOT calls with random INK colors to simulate a night sky behind the city. - **Alien drop depth:** The FOR loop at line `200` runs from 0 to 21 rows, but the building height is influenced by `le` (difficulty level) at line `100`: `21-INT(RND*le)` varies how far down building columns are printed, making higher difficulty produce shorter (more exposed) buildings. - **Comma-separated PRINT AT blanking:** Line `400` uses `PRINT AT 5,0,,,,,,,,` to overwrite multiple screen positions with empty strings in a single PRINT statement. ### Bugs and Anomalies - **DATA with variable `s`:** Lines `690` and `700` include `s` as a DATA value. During READ, `s` holds the most recently read numeric value from the DATA list. This will produce valid (if unintended) sprite byte patterns, but the UDG shapes may not exactly match the original program’s intent if `s` was meant to be a specific literal. - **Wave counter logic:** Line `130` checks `IF aw>=0`, which is always true after initialization (aw starts at 1), so `bh` is unconditionally incremented on every pass through this line, potentially causing the player disc’s row `x` to drift upward unexpectedly over many waves. - **Line 20 is blank:** An empty line at `20` with no statement is syntactically harmless but occupies space in the program. - **REM at line 40 contains a stray comment inside another line:** Line `40` begins with whitespace before `REM`, which is valid but unusual formatting likely from the original magazine typesetting. - **UDG `\n` (char n) is used at lines 430 and 540** but is never explicitly defined in a dedicated DATA/POKE block. It falls within the 16-byte block POKEd to `USR "m"` (which covers m and n), so it does receive data — but this is implicit rather than clearly documented in the listing. ### Game Flow Summary After setup and the skyline drawing phase, the main loop repeatedly drops a single alien from the top of the screen while allowing left/right player movement via `Q` and `P`. A counter `i` tracks aliens that reach the city floor; reaching 27 triggers the “city destroyed” ending. A counter `c` tracks successful interceptions; reaching 20 advances the attack wave. After each wave, an animation sequence at lines `420`–`540` shows the aliens departing, and the game loops back to the skyline drawing phase for the next wave. ## Source Code ``` 10 REM 'New York' 20 30 REM Taken from 'Popular Computing Weekly' 2/8 june 83 40 REM entered by G.F. Chambers 50 GO SUB 620 60 BORDER 0: PAPER 0: INK 7: CLS 70 LET z=0: FOR m=Z TO 50: INK INT (RND*6)+1: PLOT BRIGHT 0;INT (RND*255),175-INT (RND*125): NEXT m 80 PRINT #1; INK 6;" New York By Night": INK 7 90 LET z=z+INT (RND*1)+1 100 FOR u=20 TO (21-INT (RND*le)) STEP -1: PRINT AT u,z; INK 4; BRIGHT 1;"\d": PRINT AT u-1,z; INK 4; BRIGHT 1;"\c": NEXT u 110 IF z<=29 THEN GO TO 90 120 PRINT AT 21,0; BRIGHT 1; INK 4;" " 130 IF aw>=0 THEN LET bh=bh+1: LET x=19-bh: LET y=13 140 REM PRINT #1; INK 6;" New York By Night" 150 PRINT AT 5,9;"Attack Wave ";aw: LET c=0 160 PAUSE 100: PRINT AT 5,9;" " 170 PRINT AT 0,0; FLASH 1;"Score = ";sc: PRINT FLASH 1;"Level ";le: LET c=c+1 180 LET k=0 190 LET l=INT (RND*30)+1 200 FOR f=0 TO 21 210 PRINT AT x,y; INK 2; BRIGHT 1;"__" 220 IF INKEY$="q" AND y>1 THEN LET y=y-2: PRINT AT x,y+2;" " 230 IF INKEY$="p" AND y<28 THEN LET y=y+2: PRINT AT x,y-2;" " 240 PRINT AT k,l; BRIGHT 1;"\a" 250 PRINT AT k-1,l;" " 260 LET k=k+1 270 IF k=21 AND c>=20 THEN LET aw=aw+1: GO TO 380 280 IF ATTR (x,y)=71 OR ATTR (x,y+1)=71 THEN GO TO 330 290 IF f=20 AND ATTR (k,l)=68 THEN LET i=i+1: BEEP .03,30: BEEP .09,45: BEEP .06,20 300 IF i=27 THEN GO TO 360 310 NEXT f 320 GO TO 170 330 BEEP .07,10: PRINT AT x,y;"\b\b" 340 LET sc=sc+1 350 GO TO 170 360 PRINT AT k,l; BRIGHT 1;"\a": PRINT AT k-1,l;" ": PRINT AT 5,0; INK 2; BRIGHT 1; FLASH 1;"A sufficient amount of New York has been destroyed.The aliens are leaving " 370 PRINT AT 5,31;" ": PRINT AT 6,31;" ": PRINT AT 7,31;" " 380 IF i<>27 THEN PRINT AT 5,0; FLASH 1; INK 3;" Attack wave ";aw-1;" is completed, a mother ship will pick up the aliens-Prepare for the next attack wave", 390 FOR v=0 TO 350: NEXT v 400 PRINT AT 5,0,,,,,,,, 410 LET d=31 420 FOR w=1 TO 31: LET q=2: FOR r=20 TO 2 STEP -1 430 PRINT AT q,w-1;"\n\c\m" 440 IF w>=2 THEN PRINT AT q,w-2;" " 450 IF w>=31 THEN GO TO 510 460 IF ATTR (21,w)<>71 AND ATTR (21,w)<>7 AND ATTR (21,w)<>0 THEN NEXT w: PRINT AT r-1,w;"\a" 470 PRINT AT r,w;"\a" 480 IF r<=20 THEN PRINT AT r+1,w;" " 490 IF r=21 THEN BEEP .02,09: BEEP .05,45: BEEP .07,5 500 NEXT r: NEXT w 510 PRINT AT 2,29;" " 520 PRINT AT x,y;" ": LET h=4: FOR t=30 TO 0 STEP -1: PRINT AT h,t;" " 530 LET h=h+INT (RND*3-1) 540 INK (RND*7): PLOT BRIGHT 0;INT (RND*255),175-INT (RND*100): INK 7: PRINT AT h,t;"\n\c\m ": NEXT t 550 PRINT AT h,0;" ": IF i<>27 THEN PAUSE 20: GO TO 120 560 CLS 570 INPUT "Another game ? ";j$ 580 IF j$<>"y" AND j$<>"n" THEN GO TO 570 590 FOR b=0 TO 224: OUT 254,b: NEXT b: PRINT AT 10,14;"OK": PAUSE 150 600 IF j$="y" THEN RUN 610 STOP 620 REM SETUP 630 LET aw=1: LET j=0: LET sc=j: LET bh=j 640 BORDER j: PAPER j: INK 7: CLS 650 LET i=j: LET c=i: LET k=i 660 RESTORE : FOR f=0 TO 31: READ s: POKE USR "A"+f,s: NEXT f 670 DATA 0,65,34,28,42,93,73,65 680 DATA 136,105,186,28,255,221,174,107 690 DATA 60,126,153,s,255,153,s,255 700 DATA 255,153,s,s,255,153,s,255 710 FOR f=0 TO 15: READ s: POKE USR "m"+f,s: NEXT f 720 DATA 128,224,88,87,254,248,192,128 730 DATA 1,7,26,234,127,31,3,1 740 PRINT """New York By Night"" is a typical" 750 PRINT '"invader game. The aim is to" 760 PRINT '"destroy the aliens which are" 770 PRINT '"attempting to flatten New York." 780 PRINT '"You are in control of a flying" 790 PRINT '"disc which has an antimatter" 800 PRINT '"surface. The aliens,on contact" 810 PRINT '"with your disc, self-destruct." 820 PRINT '"Your flight controls are:" 830 PRINT '"Q.....Left, P.....Right" 840 PRINT ''"Hit any key to start game" 850 INPUT "Level of Difficulty (2 to 8)";le: LET bh=le 860 IF le<2 OR le>8 THEN GO TO 850 870 RETURN 880 SAVE "New York" LINE 10 ```