A camera that follows every step can make the whole scene feel restless. A quiet zone lets the player move a little without scrolling. Push past its edge and the camera moves only far enough to bring the player back to that threshold.

Include and initialise
Reserve public C/P/L/R/M/S/O and private T/A. Reserve lines 3000–3230, combine routines.bas with a caller using build.py and keep END, STOP or a jump before the helper. C64/BBC use GOSUB; Spectrum uses GO SUB. Private T/A belong to the call.
Call 3000 at a reset boundary. It clears all public fields. Set retained camera C, world-space player P, quiet-zone thresholds L/R and maximum camera coordinate M afterwards. All are integral byte values in one consistent set of units.
Update after player movement
Call 3100. The helper examines the non-wrapping difference P-C. Within inclusive thresholds L..R it leaves C alone. Beyond either threshold it moves just enough to put the player on that edge, then clamps the camera to 0..M. S=1 only when C changes; O=1 reports a valid request.
| Field | Use |
|---|---|
| C | Retained world-space camera |
| P / L / R / M | World player, screen-relative thresholds and scroll limit |
| S / O | Camera shifted / valid-input flags |
Require L <= R and current C <= M, in addition to byte/integer inputs. Invalid input clears S/O and preserves C. Player and bounds always survive. If changing M would put the current camera outside the new limit, establish a valid starting camera deliberately rather than expecting this query to repair invalid state.
Equal thresholds make a zero-width quiet zone, not an invalid one. World edges can prevent the player remaining at the preferred screen position; clamping takes precedence.
The reusable routine
Reusable numbered routines
3000 LET C=0: LET P=0: LET L=0: LET R=0: LET M=0: LET S=0: LET O=0: RETURN
3100 LET S=0: LET O=0
3110 IF C<0 OR C>255 OR C<>INT (C) THEN RETURN
3120 IF P<0 OR P>255 OR P<>INT (P) THEN RETURN
3130 IF L<0 OR L>255 OR L<>INT (L) THEN RETURN
3140 IF R<0 OR R>255 OR R<>INT (R) THEN RETURN
3150 IF M<0 OR M>255 OR M<>INT (M) THEN RETURN
3160 IF L>R OR C>M THEN RETURN
3170 LET T=P-C: LET A=C
3180 IF T<L THEN LET A=P-L
3190 IF T>R THEN LET A=P-R
3200 IF A<0 THEN LET A=0
3210 IF A>M THEN LET A=M
3220 IF A<>C THEN LET S=1
3230 LET C=A: LET O=1: RETURNThe temporary relative coordinate may be negative when the player is left of the camera. It must not wrap to an apparently large positive byte. The target camera is likewise clamped before being stored, so a negative desired scroll cannot become a position near 255.
Supply world coordinates each time
With thresholds 40..80, player positions 90 then 100 move the camera from zero to ten, then twenty. The custom caller sets both thresholds to 60 and finishes at camera 40. Further calls exercise world clamps and invalid bounds.
Example calls from the maintained caller
70 GOSUB 3000: LET AA=0: LET BB=0
80 LET C=0: LET L=40: LET R=80: LET M=200
90 LET P=90
100 GOSUB 3100: GOSUB 2000
110 LET P=100
120 GOSUB 3100: GOSUB 2000
130 IF C=20 THEN LET AA=1
140 IF P=100 THEN LET BB=1
150 LET P=0: GOSUB 3100: GOSUB 2000
160 LET P=255: GOSUB 3100: GOSUB 2000
170 LET L=R+1: GOSUB 3100: GOSUB 2000
180 PRINT "VIEW RESULTS";AA;BB
190 ?(MB+995)=AA: ?(MB+996)=BB: ?(MB+997)=GD: ?(MB+998)=WC-256*INT (WC/256): ?(MB+999)=INT (WC/256): ?(MB+1000)=239: STOPLine 2000, AA/BB/JJ (Z on Spectrum) and the mailbox are diagnostics. A game services this query after movement, then passes C to a renderer’s coordinate conversion or scrolling backend. The helper does not upload tiles, shift a bitmap or install a timer.
Customise the view
Choose thresholds for the actual viewport and the player’s preferred space. Logical coordinates can be pixels, tiles or another consistent unit; the byte example is not a claim to cover every full hardware screen width. Wider worlds require wider inputs/results and renewed range verification.
A dead zone is not smoothing. Easing, look-ahead or camera shake adds a different policy, and should not silently change the retained world coordinate used here. An ordinary real-valued BASIC camera may also suit a game better than this byte-facing contract.
Mistake and repair
The wrong caller subtracts C from P before calling an API that expects world P. Its first call looks correct because C starts at zero; the second mixes coordinate spaces and stops following properly. Both saved checks fail. Subtract the camera only in the rendering path. Repaired source and loaded program match normal.

Cost and Maths for Games
The query uses fixed validation, signed relative arithmetic, comparisons and clamping. It performs no allocation or display update. BASIC numeric storage and tokenised listing size are separate from the seven-byte native binding; no cycle budget is inferred.
Maths for Games connects coordinate transforms, intervals and clamping. The Craft connects camera stability, useful viewing space and movement that stays readable.
Global names and line numbers
BASIC numeric names, arrays and numbered lines are global. To combine helpers, rename public and private fields and renumber the helper together with every GO SUB/GO TO reference. Keep each state block under one owner. The maintained build.py rejects duplicate line numbers; it does not automatically namespace or renumber routines.
Machine and measured size
This helper uses scalar numeric fields and allocates no arrays. Its diagnostic uses MODE 7 and HIMEM=&6000 to separate program storage, mailbox and screen. The helper itself changes neither mode nor HIMEM.
The numbered helper occupies 391 tokenised program bytes on this interpreter, including line headers. This excludes the caller, test tables, numeric scalar/array storage, interpreter stacks and ROM. Tokenised size is not machine-code size or a hardware-cycle count. No real-time or whole-game performance budget is inferred from the diagnostic. The caller’s AA/BB, JJ and RAM mailbox are observation machinery, not required game state.
Execution evidence
Working, custom, deliberately wrong and exact repaired callers executed through BBC Micro’s stock BASIC interpreter under Emu198x 0.44.2. Build198x 0.2.9 tokenises C64 PRG and Spectrum TAP programs. C64 enters stock RUN, Spectrum uses ROM tape loading, and BBC enters every numbered source line through MOS/BASIC. Actual loaded program bytes, complete state packets, positive completion/count/guards and visible result pixels are checked. After the positive completion marker, the observer advances two complete display frames before capturing, so a partially scanned final character cannot masquerade as a finished picture. Firmware is not distributed.
An independent mathematical/order model checks the trace and rejects altered source, configuration, loaded program, state, completion and image evidence. Host exhaustive checks complement the native boundary/sequential examples; those host ranges are not claimed as natively exhaustive. The supplied diagnostic callers deliberately end with STOP; the interpreter report is expected. The wrong caller prints 0,0 and the normal/custom/repaired callers print 1,1.
Public CI checks retained evidence; it does not execute restricted firmware. Refresh with python3 scripts/verify-basic-platforms.py camera-deadzone bbc-micro --tools /path/to/extracted/releases and inspect with python3 scripts/check-basic-platforms.py camera-deadzone.
Explore further
Compare the assembly technique. The BASIC game-flow routine makes session boundaries explicit. Complete source and native evidence.