Give the C64 a voice.
Set up a SID voice and get to know the registers behind a sound.
Commodore 64 · AssemblyDraw a sprite. Read a controller. Give a game its sound.
The Pattern Library takes one technique at a time: the code, the machine it needs, and the trade-offs to understand before you adapt it.
Find a techniqueShow health, heat or time remaining with a bar that changes as the value grows.
ZX Spectrum · BASIC · Beginner
Set up a SID voice and get to know the registers behind a sound.
Commodore 64 · AssemblyRead the NES controller and turn button presses into game input.
NES · Assembly1038 patterns
No patterns match these filters. Try a broader search or clear the filters.
When three things happen before the game gets around to handling them, one event byte can only remember the last one.
When three things happen before the game gets around to handling them, one event byte can only remember the last one.
When three things happen before the game gets around to handling them, one event byte can only remember the last one.
When three things happen before the game gets around to handling them, one event byte can only remember the last one.
Entering a player name needs more than appending characters.
Entering a player name needs more than appending characters.
Entering a player name needs more than appending characters.
Entering a player name needs more than appending characters.
Recognise two-word commands without changing the input buffer. Reusable Z80 code, checked vocabulary tables and a working keyboard caller.
Wait for a fresh raster boundary, then read, update and draw. Keep timing separate from the work your game does.
Use the 48K ROM interrupt clock to accept one update at a time, including when game work takes longer.
Poll a fresh vertical-blank request while the main program owns the machine.
Wait for display sync through MOS, keeping the system keyboard, display and interrupt services running.
Reuse the MOS-facing loop while checking the Electron’s own loading, display and workload behaviour.
Let NMI announce elapsed frames while the main loop reads controls and updates game state.
Step a note pattern once per frame from the NMI, handing each APU channel its note from a timer table — the skeleton of every NES music driver.
A coin worth 300 points should still be worth 300 when the low byte fills up.
A coin worth 300 points should still be worth 300 when the low byte fills up.
A coin worth 300 points should still be worth 300 when the low byte fills up.
A coin worth 300 points should still be worth 300 when the low byte fills up.
Enable pulse 1 in $4015, then set its duty, volume, sweep and 11-bit timer. It holds a tone with no further CPU work, as long as nothing mutes it.
A saved score or a small asset can pick up an accidental changed byte.
A saved score or a small asset can pick up an accidental changed byte.
A saved score or a small asset can pick up an accidental changed byte.
A saved score or a small asset can pick up an accidental changed byte.
Turn the player's words into commands your game can understand. A reusable, vocabulary-driven parser with a complete tiny adventure.
Axis-Aligned Bounding Box collision — fast rectangle overlap test for sprites and objects.
Change a logical byte only after enough consecutive identical samples, retaining candidate and run history.
Change a logical byte only after enough consecutive identical samples, retaining candidate and run history.
Change a logical byte only after enough consecutive identical samples, retaining candidate and run history.
Add two-byte awards through a wide intermediate, distinguish an exact cap from clipping and preserve the award.
Add two-byte awards through a wide intermediate, distinguish an exact cap from clipping and preserve the award.
Add two-byte awards through a wide intermediate, distinguish an exact cap from clipping and preserve the award.
Keep an action timer advancing between requests, and spend its cooldown only when a requested resource is available.
Keep an action timer advancing between requests, and spend its cooldown only when a requested resource is available.
Keep an action timer advancing between requests, and spend its cooldown only when a requested resource is available.
Keep an action timer advancing between requests, and spend its cooldown only when a requested resource is available.
Picking up a stack should either fit completely or leave the inventory as it was.
Picking up a stack should either fit completely or leave the inventory as it was.
Picking up a stack should either fit completely or leave the inventory as it was.
Picking up a stack should either fit completely or leave the inventory as it was.
Add a signed eight-point-eight velocity increment in a wider range, then clamp to an explicit symmetric limit before encoding the result.
Add a signed eight-point-eight velocity increment in a wider range, then clamp to an explicit symmetric limit before encoding the result.
Add a signed eight-point-eight velocity increment in a wider range, then clamp to an explicit symmetric limit before encoding the result.
A large score or resource total should stop at its ceiling rather than wrap back to a small number.
A large score or resource total should stop at its ceiling rather than wrap back to a small number.
A large score or resource total should stop at its ceiling rather than wrap back to a small number.
A large score or resource total should stop at its ceiling rather than wrap back to a small number.
A held pose and a running animation need different clocks.
A held pose and a running animation need different clocks.
A held pose and a running animation need different clocks.
A held pose and a running animation need different clocks.
Keep game state between decisions, accept only useful commands, and leave the clock out until the rules need one.
Keep game state between decisions, accept only useful commands, and leave the clock out until the rules need one.
Return a frame index with configurable duration, looping and one-shot completion.
Return a frame index with configurable duration, looping and one-shot completion.
Return a frame index with configurable duration, looping and one-shot completion.
Compute a bounded two-component velocity towards a target with an explicit dominant-axis speed rule.
Compute a bounded two-component velocity towards a target with an explicit dominant-axis speed rule.
Compute a bounded two-component velocity towards a target with an explicit dominant-axis speed rule.
A turret can fire towards the player without a trigonometry table or floating-point division.
A turret can fire towards the player without a trigonometry table or floating-point division.
A turret can fire towards the player without a trigonometry table or floating-point division.
A turret can fire towards the player without a trigonometry table or floating-point division.
Eight occupied flags can fit in one byte when objects already live in fixed slots.
Eight occupied flags can fit in one byte when objects already live in fixed slots.
Eight occupied flags can fit in one byte when objects already live in fixed slots.
Eight occupied flags can fit in one byte when objects already live in fixed slots.
Reserve the lowest free slot and release an occupied slot using one retained eight-bit mask.
Reserve the lowest free slot and release an occupied slot using one retained eight-bit mask.
Reserve the lowest free slot and release an occupied slot using one retained eight-bit mask.
Keep health above zero and give a hit a defined recovery interval, with explicit applied and killed results.
Keep health above zero and give a hit a defined recovery interval, with explicit applied and killed results.
Keep health above zero and give a hit a defined recovery interval, with explicit applied and killed results.
An enemy can move towards a waypoint without orbiting it forever.
An enemy can move towards a waypoint without orbiting it forever.
An enemy can move towards a waypoint without orbiting it forever.
An enemy can move towards a waypoint without orbiting it forever.
Store a level as tiles, query positions safely and keep gameplay properties separate from artwork. Reusable implementations span all 30 currently emulated systems, with their memory and display differences kept explicit.
The Spectrum stores one ink-and-paper colour per 8×8 cell, so pixels and colour live on different grids — the source of colour clash. Understanding it, and the design craft that turns the constraint into the platform's look.
Write colours directly to attribute memory for fast, flicker-free graphics without touching pixel data.
Let the AY shape a note's volume in hardware and add its noise channel — a decaying pluck from the envelope generator, an explosion from noise, each fired with a single register write.
Step a note pattern once per interrupt, handing each of the AY's three channels its note from a period table — a full three-voice tune that plays in the background while the game runs.
Play a tone on the 128K's AY-3-8912 sound chip — select a register through port $FFFD, write it through $BFFD, and the chip holds the note on its own while the CPU gets on with the game.
Play an actual melody on the Spectrum's one-bit speaker — a note table for pitch, a length per note — and coax two or more voices from that single bit with phase accumulators.
Turn an (x, y) pixel into a Spectrum screen address — where consecutive lines are nowhere near each other in memory. The interleaved layout that every Spectrum drawing routine has to reckon with.
PRESS START winks on a 32-frame beat read straight off a frame counter — one AND instruction selects draw or clear. A blink is two renderers taking turns on a clock you already had.
Copy an aligned tile plane with reusable Amiga code, with DMA ownership, pitches and completion made explicit.
The blitter isn't only a copier — in line mode it plots a Bresenham line in hardware, one pixel at a time, straight into a bitplane. Feed it endpoints and an octant; it draws the line while the CPU moves on.
Gravity should keep adding speed until the chosen terminal velocity, not turn a fast fall into an upward launch when an integer overflows.
Gravity should keep adding speed until the chosen terminal velocity, not turn a fast fall into an upward launch when an integer overflows.
Gravity should keep adding speed until the chosen terminal velocity, not turn a fast fall into an upward launch when an integer overflows.
Gravity should keep adding speed until the chosen terminal velocity, not turn a fast fall into an upward launch when an integer overflows.
A maze feels kinder when a turn pressed just before a junction happens as soon as the route opens.
A maze feels kinder when a turn pressed just before a junction happens as soon as the route opens.
A maze feels kinder when a turn pressed just before a junction happens as soon as the route opens.
A maze feels kinder when a turn pressed just before a junction happens as soon as the route opens.
Pack active NES objects into a complete OAM page, hide unused slots and rotate priorities when a row exceeds the hardware limit. Includes a running cartridge.
Nearby objects are worth comparing; distant ones usually are not.
Nearby objects are worth comparing; distant ones usually are not.
Nearby objects are worth comparing; distant ones usually are not.
Nearby objects are worth comparing; distant ones usually are not.
A camera need not move every time the player takes a step.
A camera need not move every time the player takes a step.
A camera need not move every time the player takes a step.
A camera need not move every time the player takes a step.
A restart point should restore a coherent snapshot, not whichever fields happened to be copied before a failed attempt.
A restart point should restore a coherent snapshot, not whichever fields happened to be copied before a failed attempt.
A restart point should restore a coherent snapshot, not whichever fields happened to be copied before a failed attempt.
A restart point should restore a coherent snapshot, not whichever fields happened to be copied before a failed attempt.
Apply signed platform movement to a supported passenger, with explicit position bounds and clipping feedback.
Apply signed platform movement to a supported passenger, with explicit position bounds and clipping feedback.
Apply signed platform movement to a supported passenger, with explicit position bounds and clipping feedback.
A passenger should inherit a moving platform’s displacement without changing the platform’s own position.
A passenger should inherit a moving platform’s displacement without changing the platform’s own position.
A passenger should inherit a moving platform’s displacement without changing the platform’s own position.
A passenger should inherit a moving platform’s displacement without changing the platform’s own position.
Measure a terminated string, divide the unused columns in half, and print it without hard-coded coordinates. Includes a compact 6502 implementation.
Add or remove a whole quantity from four fixed item categories, rejecting requests that exceed stock or capacity.
Add or remove a whole quantity from four fixed item categories, rejecting requests that exceed stock or capacity.
Add or remove a whole quantity from four fixed item categories, rejecting requests that exceed stock or capacity.
Install a picture, share it across cells, then change every instance or just one. Reusable Atari 800XL routines with explicit character, colour and memory rules.
Reusable install, replace and select routines for C64, with real code, native output and explicit video ownership.
Reusable install, replace and select routines for Game Gear, with real code, native output and explicit video ownership.
Install a picture, share it across cells, then change every instance or just one. Reusable Jupiter Ace routines with explicit character, colour and memory rules.
Reusable install, replace and select routines for Master System, with real code, native output and explicit video ownership.
Reusable install, replace and select routines for NES CHR-RAM, with real code, native output and explicit video ownership.
Install a picture, share it across cells, then change every instance or just one. Reusable Oric Atmos routines with explicit character, colour and memory rules.
Install a picture, use it in many cells, then replace the picture or change one instance. Reusable Z80 routines for ColecoVision Graphics I.
Install a picture, use it in many cells, then replace the picture or change one instance. Reusable Z80 routines for Memotech MTX Graphics I.
Install a picture, use it in many cells, then replace the picture or change one instance. Reusable Z80 routines for SG-1000 Graphics I.
Install a picture, use it in many cells, then replace the picture or change one instance. Reusable Z80 routines for Sord M5 Graphics I.
Install a picture, use it in many cells, then replace the picture or change one instance. Reusable Z80 routines for SVI-328 Graphics I.
Install a picture, use it in many cells, then replace the picture or change one instance. Reusable Z80 routines for Tatung Einstein Graphics I.
Print ASCII characters to the screen using the ROM character set. Direct display file access for fast text rendering.
Retain an eight-bit remainder while feeding a message byte by byte, with two explicit polynomial choices and a clear reset boundary.
Retain an eight-bit remainder while feeding a message byte by byte, with two explicit polynomial choices and a clear reset boundary.
Retain an eight-bit remainder while feeding a message byte by byte, with two explicit polynomial choices and a clear reset boundary.
Read and change AMOS map cells, look up tile properties and convert world positions with explicit bounds.
Read and change typed Blitz map cells, look up tile properties and convert world positions with explicit bounds.
A dialogue box needs line breaks that fit its width without requiring a second copy of the text.
A dialogue box needs line breaks that fit its width without requiring a second copy of the text.
A dialogue box needs line breaks that fit its width without requiring a second copy of the text.
A dialogue box needs line breaks that fit its width without requiring a second copy of the text.
Select the highest-priority request while keeping the first equal-priority winner and explicit batch ownership.
Select the highest-priority request while keeping the first equal-priority winner and explicit batch ownership.
Select the highest-priority request while keeping the first equal-priority winner and explicit batch ownership.
A character can face a target in eight directions without angles, trigonometry or a lookup table.
A character can face a target in eight directions without angles, trigonometry or a lookup table.
A character can face a target in eight directions without angles, trigonometry or a lookup table.
A character can face a target in eight directions without angles, trigonometry or a lookup table.
A timid enemy might retreat often and attack rarely.
A timid enemy might retreat often and attack rarely.
A timid enemy might retreat often and attack rarely.
A timid enemy might retreat often and attack rarely.
Choose what advances play, what keeps time and when the machine can show the result.
Map a caller-supplied bounded draw to one of eight weighted outcomes, skipping zero-weight entries.
Map a caller-supplied bounded draw to one of eight weighted outcomes, skipping zero-weight entries.
Map a caller-supplied bounded draw to one of eight weighted outcomes, skipping zero-weight entries.
A pickup chime, a warning and an explosion may all request attention in one update.
A pickup chime, a warning and an explosion may all request attention in one update.
A pickup chime, a warning and an explosion may all request attention in one update.
A pickup chime, a warning and an explosion may all request attention in one update.
Reserve fixed slots, report a full pool safely, release by index and optionally expire objects without moving their payloads.
Reserve fixed slots, report a full pool safely, release by index and optionally expire objects without moving their payloads.
Reserve fixed slots, report a full pool safely, release by index and optionally expire objects without moving their payloads.
Reserve fixed slots, report a full pool safely, release by index and optionally expire objects without moving their payloads.
Find the visible intersection of two half-open rectangles, separating an empty result from invalid reversed edges.
Find the visible intersection of two half-open rectangles, separating an empty result from invalid reversed edges.
Find the visible intersection of two half-open rectangles, separating an empty result from invalid reversed edges.
A partly off-screen object should expose only the part that lies inside the viewport.
A partly off-screen object should expose only the part that lies inside the viewport.
A partly off-screen object should expose only the part that lies inside the viewport.
A partly off-screen object should expose only the part that lies inside the viewport.
Draw the visible part of a byte-aligned sprite in the normal MODE4 screen, preserving source stride and the BBC’s interleaved character-row layout.
A byte-aligned 16×16 sprite can cross any screen edge safely. Reusable signed clipping and masked drawing, with source cropping and a complete 48K tape example.
Let an object enter or leave the picture without wrapping into another row. Keep signed positions, select the visible source pixels and preserve the original image stride.
Crop a 32×16 blitter object against a 320×256 viewport, with separate source and screen strides and no blit for fully invisible objects.
Do not take the player’s ingredients and only then discover there is nowhere to put the result.
Do not take the player’s ingredients and only then discover there is nowhere to put the result.
Do not take the player’s ingredients and only then discover there is nowhere to put the result.
Do not take the player’s ingredients and only then discover there is nowhere to put the result.
A particle update can walk a dense live prefix instead of checking holes forever.
A particle update can walk a dense live prefix instead of checking holes forever.
A particle update can walk a dense live prefix instead of checking holes forever.
A particle update can walk a dense live prefix instead of checking holes forever.
A velocity of −1 must sort below zero even though its stored byte is 255.
A velocity of −1 must sort below zero even though its stored byte is 255.
A velocity of −1 must sort below zero even though its stored byte is 255.
A velocity of −1 must sort below zero even though its stored byte is 255.
Sample eight controller buttons once, distinguish holds, presses and releases, and keep the DMC and strobe contracts explicit.
Keep an inclusive quiet zone around a calibrated centre, then report direction and distance beyond it.
Keep an inclusive quiet zone around a calibrated centre, then report direction and distance beyond it.
Keep an inclusive quiet zone around a calibrated centre, then report direction and distance beyond it.
Draw a shaped, transparent object over the background using all four blitter channels — a mask decides pixel by pixel whether to keep the image or the scenery behind it. The heart of every Amiga bob.
Change the background colour at chosen scanlines from the copper list — no CPU, no interrupt, no jitter — to paint horizontal bars or a smooth vertical gradient the beam draws for you.
Build a copper list to set colours and sprite pointers. The foundation of all Amiga graphics programming.
Have the copper reprogram the bitplane pointers part-way down the frame so the top and bottom of the screen show different bitmaps — a scrolling playfield above a rock-steady status panel, beam-locked and free.
Keep a two-byte active counter, freeze it during pause and give reset explicit priority.
Keep a two-byte active counter, freeze it during pause and give reset explicit priority.
Keep a two-byte active counter, freeze it during pause and give reset explicit priority.
A pause screen should not quietly spend the player’s time allowance.
A pause screen should not quietly spend the player’s time allowance.
A pause screen should not quietly spend the player’s time allowance.
A pause screen should not quietly spend the player’s time allowance.
Check two ingredient stocks and result capacity before applying an all-or-nothing crafting transaction.
Check two ingredient stocks and result capacity before applying an all-or-nothing crafting transaction.
Check two ingredient stocks and result capacity before applying an all-or-nothing crafting transaction.
Apply damage without byte underflow, give an entity time to recover and emit one fatal-hit event.
Apply damage without byte underflow, give an entity time to recover and emit one fatal-hit event.
Apply damage without byte underflow, give an entity time to recover and emit one fatal-hit event.
Apply damage without byte underflow, give an entity time to recover and emit one fatal-hit event.
A noisy or bouncing input should settle before it changes the game’s logical state.
A noisy or bouncing input should settle before it changes the game’s logical state.
A noisy or bouncing input should settle before it changes the game’s logical state.
A noisy or bouncing input should settle before it changes the game’s logical state.
Expand count/value pairs into an eight-cell output with explicit input bounds, actual written length and useful partial-error results.
Expand count/value pairs into an eight-cell output with explicit input bounds, actual written length and useful partial-error results.
Expand count/value pairs into an eight-cell output with explicit input bounds, actual written length and useful partial-error results.
A path or table whose values change slowly can be stored as a starting value followed by small signed differences.
A path or table whose values change slowly can be stored as a starting value followed by small signed differences.
A path or table whose values change slowly can be stored as a starting value followed by small signed differences.
A path or table whose values change slowly can be stored as a starting value followed by small signed differences.
Repeated tiles or pixels can be stored as a count followed by a value.
Repeated tiles or pixels can be stored as a count followed by a value.
Repeated tiles or pixels can be stored as a count followed by a value.
Repeated tiles or pixels can be stored as a count followed by a value.
Spawning or deleting objects during a traversal can accidentally update a new object twice or skip a neighbour.
Spawning or deleting objects during a traversal can accidentally update a new object twice or skip a neighbour.
Spawning or deleting objects during a traversal can accidentally update a new object twice or skip a neighbour.
Spawning or deleting objects during a traversal can accidentally update a new object twice or skip a neighbour.
Holding two buttons together should trigger one action, not one action every frame.
Holding two buttons together should trigger one action, not one action every frame.
Holding two buttons together should trigger one action, not one action every frame.
Holding two buttons together should trigger one action, not one action every frame.
Require a set of held buttons, exclude forbidden buttons and report a rising edge for the complete chord.
Require a set of held buttons, exclude forbidden buttons and report a rising edge for the complete chord.
Require a set of held buttons, exclude forbidden buttons and report a rising edge for the complete chord.
A quotient without its remainder throws useful information away.
A quotient without its remainder throws useful information away.
A quotient without its remainder throws useful information away.
A quotient without its remainder throws useful information away.
Thirty updates from fifty display ticks should be spaced out, not rounded down to zero.
Thirty updates from fifty display ticks should be spaced out, not rounded down to zero.
Thirty updates from fifty display ticks should be spaced out, not rounded down to zero.
Thirty updates from fifty display ticks should be spaced out, not rounded down to zero.
Redraw a room, changed patch or single tile with reusable 6502 code for Acorn Atom's 256×192 monochrome bitmap.
Redraw a room, changed patch or single tile with reusable z80 code for Amstrad CPC's MODE 1 bitmap.
Redraw a room, changed patch or single tile with reusable 6502 code for BBC Micro's MODE 4 bitmap.
Redraw a room, changed patch or single tile with reusable 6809 code for Dragon 32's PMODE 4 bitmap.
Reusable Acorn Electron code for a room, changed tile or strip of scenery, with its display layout and ownership explicit.
Reusable Amiga code for drawing a room, changed tile or strip of scenery, with explicit display ownership.
Reusable Atari 800XL code for drawing a room, changed tile or strip of scenery, with explicit display ownership.
Reusable Commodore PET code for a room, changed tile or strip of scenery, with its display layout and ownership explicit.
Reusable Game Boy code for drawing a room, changed tile or strip of scenery, with explicit display ownership.
Reusable Mattel Aquarius code for a room, changed tile or strip of scenery, with its display layout and ownership explicit.
Reusable Oric Atmos code for drawing a room, changed tile or strip of scenery, with explicit display ownership.
Reusable VIC-20 code for a room, changed tile or strip of scenery, with its display layout and ownership explicit.
Copy a checked rectangle of map cells into ColecoVision's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into Einstein TC01's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into Game Gear's Mode 4 name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into Master System's Mode 4 name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into MSX1's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into MTX's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into SG-1000's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into Sord M5's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Copy a checked rectangle of map cells into SVI-328's Graphics I name table, with reusable Z80 code, explicit video ownership and verified native output.
Reusable 68000 glyph and counted-string routines over a single Chip RAM plane, with 32-bit source pointers, clipping and explicit advance.
Reusable fixed-width characters and counted strings at any pixel position, with explicit clipping, font ownership and drawing costs.
Reusable fixed-width characters and counted strings at any pixel position, with explicit clipping, font ownership and drawing costs.
Reusable fixed-width characters and counted strings at any pixel position, with explicit clipping, font ownership and drawing costs.
Reusable fixed-width characters and counted strings at any pixel position, with explicit clipping, font ownership and drawing costs.
Select and remove an item from a bounded bag, with explicit reset and caller-owned random indices.
Select and remove an item from a bounded bag, with explicit reset and caller-owned random indices.
Select and remove an item from a bounded bag, with explicit reset and caller-owned random indices.
Choose a reusable integer rasteriser or an existing hardware line path. Keep clipping, endpoint ownership, fills and display costs explicit.
Reusable clipped integer geometry, span-filled curves and explicit endpoint ownership for BBC Micro MODE 4.
Reusable clipped integer geometry, span-filled curves and explicit endpoint ownership for CPC 464 MODE 1.
Reusable clipped integer geometry, span-filled curves and explicit endpoint ownership for Dragon 32 PMODE 4.
Reusable clipped integer geometry, span-filled curves and explicit endpoint ownership for Spectrum 48K.
Sort object indices by depth without moving the objects, keeping equal-depth objects in their original order.
Sort object indices by depth without moving the objects, keeping equal-depth objects in their original order.
Sort object indices by depth without moving the objects, keeping equal-depth objects in their original order.
Reusable set/clear pixels, filled boxes and outlines, with machine-specific coordinate conversion.
Reusable set/clear pixels, filled boxes and outlines, with machine-specific coordinate conversion.
Reusable set/clear pixels, filled boxes and outlines, with machine-specific coordinate conversion.
Reusable set/clear pixels, filled boxes and outlines, with machine-specific coordinate conversion.
Start with one bit and build reusable spans and rectangles. Compare eleven qualified bitmap backends without hiding their costs.
Reusable four-pen plotting, readback, spans and rectangles, with CPC packing, partial-byte masks and explicit video ownership.
Reusable 68000 CPU drawing for an A500 PAL single plane, with byte-edge masks and explicit Chip RAM ownership.
Reusable 6502 bitmap primitives with explicit ANTIC display-list and 4 KiB screen addressing.
Reusable 6502 bitmap primitives with explicit ANTIC display-list and 4 KiB screen addressing.
Reusable 6502 drawing for the full-RAM Atom’s 256×192 bitmap, with strict bounds and clear byte ownership.
Callable set, clear, XOR, read, span and rectangle routines for BBC Micro, with explicit bounds and byte ownership.
Reusable 6502 drawing for the standard HIRES bitmap, with strict bounds, protected colour cells and byte masks.
Callable set, clear, XOR, read, span and rectangle routines for Dragon 32, with explicit bounds and byte ownership.
Reusable 6502 drawing for Electron MODE 4, with strict bounds, interleaved rows and explicit display ownership.
Reusable 6502 bitmap primitives with explicit serial-attribute and inverse-bit protection.
Callable set, clear, XOR, read, span and rectangle routines for Spectrum 48K, with explicit bounds and byte ownership.
Reusable 8×8 bitmap characters and counted strings on Spectrum, BBC Micro, Dragon, CPC and Amiga, with clipping and honest storage/work trade-offs.
Turn logical map cells into a native picture. Start with checked rectangles across twenty-one machines, while keeping patterns, colours and video ownership explicit.
Random pieces can arrive in long droughts.
Random pieces can arrive in long droughts.
Random pieces can arrive in long droughts.
Random pieces can arrive in long droughts.
Append a checked character, erase safely and clear a fixed eight-slot buffer while keeping live length separate from capacity.
Append a checked character, erase safely and clear a fixed eight-slot buffer while keeping live length separate from capacity.
Append a checked character, erase safely and clear a fixed eight-slot buffer while keeping live length separate from capacity.
Group up to eight byte values into count/value pairs, checking complete output capacity before changing any encoded byte.
Group up to eight byte values into count/value pairs, checking complete output capacity before changing any encoded byte.
Group up to eight byte values into count/value pairs, checking complete output capacity before changing any encoded byte.
Repeated map values can take less room as a count and a value—but only if the output buffer is big enough.
Repeated map values can take less room as a count and a value—but only if the output buffer is big enough.
Repeated map values can take less room as a count and a value—but only if the output buffer is big enough.
Repeated map values can take less room as a count and a value—but only if the output buffer is big enough.
Climbing should suspend gravity, but jumping away must hand movement back to the ordinary player controller.
Climbing should suspend gravity, but jumping away must hand movement back to the ordinary player controller.
Climbing should suspend gravity, but jumping away must hand movement back to the ordinary player controller.
Climbing should suspend gravity, but jumping away must hand movement back to the ordinary player controller.
Difficulty lives in a table; a level-up pokes the next row into live tuning variables the systems read fresh every frame. The systems never learn that levels exist.
Choose a discrete facing from two positions using signed displacement and a deliberate 2:1 sector rule.
Choose a discrete facing from two positions using signed displacement and a deliberate 2:1 sector rule.
Choose a discrete facing from two positions using signed displacement and a deliberate 2:1 sector rule.
As the NES scrolls sideways, write a fresh column of tiles into the offscreen nametable each time the view crosses a tile boundary — so a level far wider than two screens rolls past seamlessly.
A paint fill can also discover a connected room or reveal matching puzzle cells.
A paint fill can also discover a connected room or reveal matching puzzle cells.
A paint fill can also discover a connected room or reveal matching puzzle cells.
A paint fill can also discover a connected room or reveal matching puzzle cells.
A projectile can cross its owner without hitting them, while still hitting an opponent in the same patch of screen.
A projectile can cross its owner without hitting them, while still hitting an opponent in the same patch of screen.
A projectile can cross its owner without hitting them, while still hitting an opponent in the same patch of screen.
A projectile can cross its owner without hitting them, while still hitting an opponent in the same patch of screen.
Require mutual group acceptance, then classify an accepted pair as a sensor or solid before geometry testing.
Require mutual group acceptance, then classify an accepted pair as a sensor or solid before geometry testing.
Require mutual group acceptance, then classify an accepted pair as a sensor or solid before geometry testing.
Return shortest four-neighbour distances, parents and a first step from a bounded tile map.
Return shortest four-neighbour distances, parents and a first step from a bounded tile map.
Return shortest four-neighbour distances, parents and a first step from a bounded tile map.
Search eight byte-key/value pairs, preserving the dictionary and returning the first match with separate found and validity flags.
Search eight byte-key/value pairs, preserving the dictionary and returning the first match with separate found and validity flags.
Search eight byte-key/value pairs, preserving the dictionary and returning the first match with separate found and validity flags.
Sometimes the useful answer is the whole-number distance, with no floating point in sight.
Sometimes the useful answer is the whole-number distance, with no floating point in sight.
Sometimes the useful answer is the whole-number distance, with no floating point in sight.
Sometimes the useful answer is the whole-number distance, with no floating point in sight.
An enemy can walk around a wall without pretending that moving towards the player is already pathfinding.
An enemy can walk around a wall without pretending that moving towards the player is already pathfinding.
An enemy can walk around a wall without pretending that moving towards the player is already pathfinding.
An enemy can walk around a wall without pretending that moving towards the player is already pathfinding.
Fractional values without floating point. Essential for smooth movement and physics on 8/16-bit CPUs.
Move through four ordered positions, retaining the route cursor and choosing a loop or a finished one-shot.
Move through four ordered positions, retaining the route cursor and choosing a loop or a finished one-shot.
Move through four ordered positions, retaining the route cursor and choosing a loop or a finished one-shot.
A binary score is good for adding points.
A binary score is good for adding points.
A binary score is good for adding points.
A binary score is good for adding points.
Two hexadecimal digits are a compact way to show a byte in a debugger, password or diagnostic panel.
Two hexadecimal digits are a compact way to show a byte in a debugger, password or diagnostic panel.
Two hexadecimal digits are a compact way to show a byte in a debugger, password or diagnostic panel.
Two hexadecimal digits are a compact way to show a byte in a debugger, password or diagnostic panel.
Compare CPU-driven beeper sound, NES channels, SID synthesis and Amiga samples, with their timing and ownership costs.
A complete eight-row sequencer for four Paula voices, with explicit startup, channel ownership and hold semantics. A small step toward music playback.
A quarter-pixel step should eventually move the sprite a whole pixel.
A quarter-pixel step should eventually move the sprite a whole pixel.
A quarter-pixel step should eventually move the sprite a whole pixel.
A quarter-pixel step should eventually move the sprite a whole pixel.
Organise game flow with distinct states (title, playing, game over). Clean separation of game phases.
Separate title, play, pause and game over, preserve a paused session and reset a new one exactly once.
Separate title, play, pause and game over, preserve a paused session and reset a new one exactly once.
Separate title, play, pause and game over, preserve a paused session and reset a new one exactly once.
Separate title, play, pause and game over, preserve a paused session and reset a new one exactly once.
A dialogue option can depend on what the player knows and change what happens next.
A dialogue option can depend on what the player knows and change what happens next.
A dialogue option can depend on what the player knows and change what happens next.
A dialogue option can depend on what the player knows and change what happens next.
Use an explicit countdown context and the stock ROM timer, keeping input and game policy separate.
Use a reusable elapsed-clock helper, keep untimed play valid, and let a deadline expire without blocking on input.
Use a reusable elapsed-clock helper, keep untimed play valid, and let a deadline expire without blocking on input.
Keep untimed turns valid, or add time pressure using the firmware clock and nonblocking character input.
Keep untimed play valid, or use TIMER and a reusable countdown to advance without waiting for a command.
Use a reusable elapsed-clock helper, keep untimed play valid, and let a deadline expire without blocking on input.
Use a reusable elapsed-clock helper, keep untimed play valid, and let a deadline expire without blocking on input.
Use a reusable elapsed-clock helper, keep untimed play valid, and let a deadline expire without blocking on input.
Let the player think, or add a deadline using a serviced clock and physical key edges.
Keep a turn waiting for a decision, or let a separate clock put pressure on the player without blocking on Return.
Keep untimed turns waiting, then add a reusable unsigned deadline and nonblocking key sampling on the unexpanded Ace.
Keep untimed turns useful, then add a serviced jiffy-clock deadline with an explicit input policy.
Keep untimed play valid, then add a reusable FRAMES countdown with an explicit input and expiry policy.
Keep untimed play valid, then add a reusable FRAMES countdown with an explicit input and expiry policy.
Keep untimed turns untimed, then add a reusable clock-driven deadline that can expire without input.
Keep untimed turns untimed, then add a reusable clock-driven deadline that can expire without input.
Keep untimed turns useful, then add a serviced jiffy-clock deadline with an explicit input policy.
Keep untimed turns useful, then add a serviced jiffy-clock deadline with an explicit input policy.
Use the stock FORTH clock with a reusable countdown, a release-gated keyboard reader and a loader that waits for compilation.
Let the player think, enable a ticking deadline when the rules need it, and keep time moving while input waits.
Use a reusable countdown without blocking input or replacing the normal Atari VBI clock.
Reuse a 6502 countdown while preserving Atari BASIC, normal VBI services and explicit high-RAM ownership.
Let the player think, or add a deadline using a serviced clock and physical key edges.
Use TIME and nonblocking input with a reusable countdown, retaining a valid untimed game policy.
Keep optional turn timing, buffered input and BIOS text output separate, using the maintained Z80 countdown.
Build reusable direct 160A headers while keeping zones, graphics placement and DMA ownership explicit.
Select one of eight ready slots from a retained rotating start position, wrapping fairly and leaving work execution to the caller.
Select one of eight ready slots from a retained rotating start position, wrapping fairly and leaving work execution to the caller.
Select one of eight ready slots from a retained rotating start position, wrapping fairly and leaving work execution to the caller.
Move an entity on a grid with boundary checking. Prevents moving outside the play area.
Store up to four object IDs in each of four spatial buckets, with explicit capacity overflow and read-only queries.
Store up to four object IDs in each of four spatial buckets, with explicit capacity overflow and read-only queries.
Store up to four object IDs in each of four spatial buckets, with explicit capacity overflow and read-only queries.
Show a complete 24×21 sprite, set its ninth X bit, and preserve the other sprites’ shared registers. Verified on PAL and NTSC emulators.
Detect newly-pressed buttons, ignoring held inputs. Essential for menus and single-action triggers.
Maintain four descending byte scores with associated tags, retaining existing equal scores first and rejecting an invalid table without changing it.
Maintain four descending byte scores with associated tags, retaining existing equal scores first and rejecting an invalid table without changing it.
Maintain four descending byte scores with associated tags, retaining existing equal scores first and rejecting an invalid table without changing it.
A score table needs a clear answer for ties, a full table and the player who just misses the cut.
A score table needs a clear answer for ties, a full table and the player who just misses the cut.
A score table needs a clear answer for ties, a full table and the player who just misses the cut.
A score table needs a clear answer for ties, a full table and the player who just misses the cut.
Reusable glyph uploads and cell selection on Game Boy; keep pictures, character numbers and placement separate.
Reusable glyph uploads and cell selection on MSX1; keep pictures, character numbers and placement separate.
Reusable glyph uploads and cell selection on VIC-20; keep pictures, character numbers and placement separate.
Reusable glyph upload, replacement and cell selection on sixteen qualified targets, including native C64, NES CHR-RAM and Sega Mode 4. Separate the picture from its code, placement and colours.
A menu panel or camera can move towards an endpoint without a different hand-written position for every frame.
A menu panel or camera can move towards an endpoint without a different hand-written position for every frame.
A menu panel or camera can move towards an endpoint without a different hand-written position for every frame.
A menu panel or camera can move towards an endpoint without a different hand-written position for every frame.
Detect newly-pressed joystick directions, ignoring held inputs. Essential for grid-based movement and menu navigation.
Read both C64 joystick ports, distinguish holds, presses and releases, and map one event to one action.
Read Amiga joystick using the JOY1DAT register with XOR decoding for up/down directions.
Press Jump just before landing and it is frustrating when the press disappears.
Press Jump just before landing and it is frustrating when the press disappears.
Press Jump just before landing and it is frustrating when the press disappears.
Press Jump just before landing and it is frustrating when the press disappears.
Undo should restore the previous cell value, including when the same cell was edited twice.
Undo should restore the previous cell value, including when the same cell was edited twice.
Undo should restore the previous cell value, including when the same cell was edited twice.
Undo should restore the previous cell value, including when the same cell was edited twice.
A list can hold more choices than the screen has rows while its cursor still stays in view.
A list can hold more choices than the screen has rows while its cursor still stays in view.
A list can hold more choices than the screen has rows while its cursor still stays in view.
A list can hold more choices than the screen has rows while its cursor still stays in view.
A trailing companion needs where the leader was, not another guess at where it might be going.
A trailing companion needs where the leader was, not another guess at where it might be going.
A trailing companion needs where the leader was, not another guess at where it might be going.
A trailing companion needs where the leader was, not another guess at where it might be going.
A prompt should not flicker between two nearby objects whenever their distances differ by one pixel.
A prompt should not flicker between two nearby objects whenever their distances differ by one pixel.
A prompt should not flicker between two nearby objects whenever their distances differ by one pixel.
A prompt should not flicker between two nearby objects whenever their distances differ by one pixel.
An urgent event may need service before an older routine event, while equal priorities should remain fair.
An urgent event may need service before an older routine event, while equal priorities should remain fair.
An urgent event may need service before an older routine event, while equal priorities should remain fair.
An urgent event may need service before an older routine event, while equal priorities should remain fair.
Retain a requested turn, try it before the current direction and move at most one checked grid cell per service.
Retain a requested turn, try it before the current direction and move at most one checked grid cell per service.
Retain a requested turn, try it before the current direction and move at most one checked grid cell per service.
Track a finite duration and pulse interval, including a possible pulse on the final active tick.
Track a finite duration and pulse interval, including a possible pulse on the final active tick.
Track a finite duration and pulse interval, including a possible pulse on the final active tick.
Produce bounded signed camera offsets for a retained lifetime, without modifying the world position.
Produce bounded signed camera offsets for a retained lifetime, without modifying the world position.
Produce bounded signed camera offsets for a retained lifetime, without modifying the world position.
An impact can shake the view without moving the player, the level or the collision geometry.
An impact can shake the view without moving the player, the level or the collision geometry.
An impact can shake the view without moving the player, the level or the collision geometry.
An impact can shake the view without moving the player, the level or the collision geometry.
Emit a chosen numerator of events per denominator calls without discarding the remainder.
Emit a chosen numerator of events per denominator calls without discarding the remainder.
Emit a chosen numerator of events per denominator calls without discarding the remainder.
Add a signed eight-point-eight displacement to a retained position, preserving sub-unit motion and making wrapping explicit.
Add a signed eight-point-eight displacement to a retained position, preserving sub-unit motion and making wrapping explicit.
Add a signed eight-point-eight displacement to a retained position, preserving sub-unit motion and making wrapping explicit.
Choose an eligible nearby target while retaining the current one within an explicit distance margin.
Choose an eligible nearby target while retaining the current one within an explicit distance margin.
Choose an eligible nearby target while retaining the current one within an explicit distance margin.
Allocate, query and release four stable slots while rejecting references to an earlier generation of a slot.
Allocate, query and release four stable slots while rejecting references to an earlier generation of a slot.
Allocate, query and release four stable slots while rejecting references to an earlier generation of a slot.
Separate fresh sessions, held-button edges and pause/resume transitions with explicit caller-owned progress.
Separate fresh sessions, held-button edges and pause/resume transitions with explicit caller-owned progress.
Separate fresh sessions, held-button edges and pause/resume transitions with explicit caller-owned progress.
Retain a world-space camera, move only beyond a screen-relative quiet zone and clamp the result to valid scrolling bounds.
Retain a world-space camera, move only beyond a screen-relative quiet zone and clamp the result to valid scrolling bounds.
Retain a world-space camera, move only beyond a screen-relative quiet zone and clamp the result to valid scrolling bounds.
Mark, inspect and consume pending cell updates without losing repeated marks or crossing the two-byte boundary.
Mark, inspect and consume pending cell updates without losing repeated marks or crossing the two-byte boundary.
Mark, inspect and consume pending cell updates without losing repeated marks or crossing the two-byte boundary.
Move within inclusive axis bounds while consuming the whole requested distance, retaining direction and counting repeated reflections.
Move within inclusive axis bounds while consuming the whole requested distance, retaining direction and counting repeated reflections.
Move within inclusive axis bounds while consuming the whole requested distance, retaining direction and counting repeated reflections.
Queue four event/priority pairs, service the highest priority first and preserve insertion order for equal priorities.
Queue four event/priority pairs, service the highest priority first and preserve insertion order for equal priorities.
Queue four event/priority pairs, service the highest priority first and preserve insertion order for equal priorities.
Read the ZX Spectrum keyboard matrix by polling I/O ports. Simple, efficient, and no ROM routines required.
A fast-falling character can cross a thin platform between two updates without ever having its feet exactly on the top.
A fast-falling character can cross a thin platform between two updates without ever having its feet exactly on the top.
A fast-falling character can cross a thin platform between two updates without ever having its feet exactly on the top.
A fast-falling character can cross a thin platform between two updates without ever having its feet exactly on the top.
Compare old and proposed feet against a platform top, using widened horizontal spans and a deliberate drop-through flag.
Compare old and proposed feet against a platform top, using widened horizontal spans and a deliberate drop-through flag.
Compare old and proposed feet against a platform top, using widened horizontal spans and a deliberate drop-through flag.
Linear Feedback Shift Register for fast, deterministic pseudo-random numbers.
Accept each target once during a chosen attack interval, retaining a hit set across updates.
Accept each target once during a chosen attack interval, retaining a hit set across updates.
Accept each target once during a chosen attack interval, retaining a hit set across updates.
A sword can overlap the same enemy for several frames without dealing damage on every frame.
A sword can overlap the same enemy for several frames without dealing damage on every frame.
A sword can overlap the same enemy for several frames without dealing damage on every frame.
A sword can overlap the same enemy for several frames without dealing damage on every frame.
An item code, tile identifier or command token often needs a small associated value.
An item code, tile identifier or command token often needs a small associated value.
An item code, tile identifier or command token often needs a small associated value.
An item code, tile identifier or command token often needs a small associated value.
Query an eight-column height profile, mirror it without copying data and reject a surface that would exceed the byte coordinate range.
Query an eight-column height profile, mirror it without copying data and reject a surface that would exceed the byte coordinate range.
Query an eight-column height profile, mirror it without copying data and reject a surface that would exceed the byte coordinate range.
The picture number in a map does not automatically tell you whether a tile is solid, harmful or climbable.
The picture number in a map does not automatically tell you whether a tile is solid, harmful or climbable.
The picture number in a map does not automatically tell you whether a tile is solid, harmful or climbable.
The picture number in a map does not automatically tell you whether a tile is solid, harmful or climbable.
Five small programs connect controls, movement, collision, drawing and sound, with reusable routines you can bring into your own game.
On a four-way grid, distance is the horizontal gap plus the vertical gap.
On a four-way grid, distance is the horizontal gap plus the vertical gap.
On a four-way grid, distance is the horizontal gap plus the vertical gap.
On a four-way grid, distance is the horizontal gap plus the vertical gap.
The Spectrum has no hardware sprites, so a moving object is drawn by hand — AND a mask to punch a hole in the background, OR the image into it — with pre-shifted copies for pixel-accurate, fast movement.
Draw an 8×8 software object over BBC Micro MODE4 scenery, restore what it covered, then move it. A small reusable primitive with a complete caller.
Measure and align labels, choose character or word wrapping, and give narrow letters less room with proportional text.
Measure and align labels, choose character or word wrapping, and give narrow letters less room with proportional text.
Measure and align labels, choose character or word wrapping, and give narrow letters less room with proportional text.
Measure and align labels, choose character or word wrapping, and give narrow letters less room with proportional text.
A menu should move once when you press Down, pause briefly, then scroll while you hold it.
A menu should move once when you press Down, pause briefly, then scroll while you hold it.
A menu should move once when you press Down, pause briefly, then scroll while you hold it.
A menu should move once when you press Down, pause briefly, then scroll while you hold it.
A stored row of pixels can face the other way without keeping a second copy of the artwork.
A stored row of pixels can face the other way without keeping a second copy of the artwork.
A stored row of pixels can face the other way without keeping a second copy of the artwork.
A stored row of pixels can face the other way without keeping a second copy of the artwork.
Combine input, bounded movement, box collision, drawing and sound in a small program you can take apart.
Combine input, bounded movement, box collision, drawing and sound in a small program you can take apart.
Combine input, bounded movement, box collision, drawing and sound in a small program you can take apart.
Combine input, bounded movement, box collision, drawing and sound in a small program you can take apart.
Combine input, bounded movement, box collision, drawing and sound in a small program you can take apart.
A small machine still needs products larger than one byte: an area, a score multiplier or a scaled distance.
A small machine still needs products larger than one byte: an area, a score multiplier or a scaled distance.
A small machine still needs products larger than one byte: an area, a score multiplier or a scaled distance.
A small machine still needs products larger than one byte: an area, a score multiplier or a scaled distance.
Move through a two-screen NES background with reusable scroll routines and a complete cartridge. Publish a finished display update before NMI uses it.
Convert a number (0-99) to two ASCII digits and print them. Essential for scores and counters.
Test quest conditions before accepting a choice, then apply its changes once.
Test quest conditions before accepting a choice, then apply its changes once.
Test quest conditions before accepting a choice, then apply its changes once.
Queue a silent reload after a sample starts, so it finishes once. Understand DMA ownership, interrupt latency and safe reuse.
Keep an optional turn deadline moving with a private A500 VBlank clock, even while foreground work slows down.
Let commands advance a game, add an optional NMI-clock deadline, and keep time moving during slow work.
Compact paired flag/payload arrays in place, clearing vacated entries while preserving unused capacity.
Compact paired flag/payload arrays in place, clearing vacated entries while preserving unused capacity.
Compact paired flag/payload arrays in place, clearing vacated entries while preserving unused capacity.
Load colour palettes into PPU memory at $3F00. Required setup for any NES graphics.
A score name box and a numeric prompt need different input rules.
A score name box and a numeric prompt need different input rules.
A score name box and a numeric prompt need different input rules.
A score name box and a numeric prompt need different input rules.
A short hexadecimal input still needs validation before it becomes an address, colour or seed.
A short hexadecimal input still needs validation before it becomes an address, colour or seed.
A short hexadecimal input still needs validation before it becomes an address, colour or seed.
A short hexadecimal input still needs validation before it becomes an address, colour or seed.
Reusable BASIC V2 code turns words into game concepts, with exact matching, synonyms, clear errors and measured costs.
A guard walks to the end of a corridor, turns and comes back.
A guard walks to the end of a corridor, turns and comes back.
A guard walks to the end of a corridor, turns and comes back.
A guard walks to the end of a corridor, turns and comes back.
Preserve score, health and held-input history on resume, and reset them only for a fresh session.
Choose one next state, preserve progress while paused, and reset the owner only for a fresh session.
Separate state entry from a fresh session so pause preserves score, health and held-input history.
Choose among four active candidates using Manhattan distance, preserving the first slot on ties and retaining the ninth distance bit.
Choose among four active candidates using Manhattan distance, preserving the first slot on ties and retaining the ninth distance bit.
Choose among four active candidates using Manhattan distance, preserving the first slot on ties and retaining the ninth distance bit.
Trade chip RAM for sixteen prepared mask/image phases, reusing the checked word-aligned clipped blitter renderer at individual pixel positions.
Use eight prepared mask phases with signed pixel coordinates, normal forty-column MODE4 mapping and a bounded three-byte drawing routine.
Draw counted labels and character pictures with the machine's ROM, with explicit bounds and display ownership.
Draw counted labels and character pictures with the machine's ROM, with explicit bounds and display ownership.
Draw counted labels and character pictures with the machine's ROM, with explicit bounds and display ownership.
Draw counted labels and character pictures with the machine's ROM, with explicit bounds and display ownership.
Select one of eight prepared masks, keep signed pixel positions correct at the left edge, and draw the visible three-byte footprint.
Prepare shifted mask/image phases once, then choose the right one for a pixel position. Working Spectrum, BBC and Amiga code makes the memory and integration costs explicit.
Point Paula's audio channel 0 at a waveform in chip RAM, choose a period and volume, and let DMA repeat it — then predict the pitch you will hear.
Reuse coarse cells and glyph stamps without losing sight of the TIA's scanline schedule.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Print a map slice with a complete bounds and tile-ID preflight before any output.
Find where a Spectrum routine spends its time, change one thing, and measure the saving against the extra code.
Horizontal progress bar coloured like a gauge — red when low, yellow in the middle, green when high. Useful for fuel, health or time left.
Convert byte-pair world coordinates to visible screen positions without dropping high bytes or wrapping negative differences.
Convert byte-pair world coordinates to visible screen positions without dropping high bytes or wrapping negative differences.
Convert byte-pair world coordinates to visible screen positions without dropping high bytes or wrapping negative differences.
A world can be larger than the screen even when the drawing routine expects byte-sized screen coordinates.
A world can be larger than the screen even when the drawing routine expects byte-sized screen coordinates.
A world can be larger than the screen even when the drawing routine expects byte-sized screen coordinates.
A world can be larger than the screen even when the drawing routine expects byte-sized screen coordinates.
Detect a one-dimensional moving solid crossing an actor and propose a safe displacement or an explicit blocked result.
Detect a one-dimensional moving solid crossing an actor and propose a safe displacement or an explicit blocked result.
Detect a one-dimensional moving solid crossing an actor and propose a safe displacement or an explicit blocked result.
A crate should move with the player only when the space beyond it is free.
A crate should move with the player only when the space beyond it is free.
A crate should move with the player only when the space beyond it is free.
A crate should move with the player only when the space beyond it is free.
Check the adjacent cell and the space beyond a crate before changing the player or map.
Check the adjacent cell and the space beyond a crate before changing the player or map.
Check the adjacent cell and the space beyond a crate before changing the player or map.
A moving wall should carry an actor ahead of its leading face, or report that the actor cannot fit.
A moving wall should carry an actor ahead of its leading face, or report that the actor cannot fit.
A moving wall should carry an actor ahead of its leading face, or report that the actor cannot fit.
A moving wall should carry an actor ahead of its leading face, or report that the actor cannot fit.
Measure counted labels and choose character or word wrapping with four reusable machine-specific implementations.
Read and change a room, classify tiles and convert world positions with reusable FORTH words that fit the unexpanded Ace.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 68000 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6809 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable SM83 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable 6502 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change map cells, look up tile properties and convert world positions with reusable Z80 code and an explicit memory contract.
Read and change tiles, look up their properties and convert world positions with reusable routines for expanded and stock 1 KiB ZX80 configurations.
Read and change tiles, look up their properties and convert world positions with reusable routines for expanded and stock 1 KiB ZX81 configurations.
A sloping tile needs a surface at each horizontal position, not one flat collision edge.
A sloping tile needs a surface at each horizontal position, not one flat collision edge.
A sloping tile needs a surface at each horizontal position, not one flat collision edge.
A sloping tile needs a surface at each horizontal position, not one flat collision edge.
Visit the cells along an integer line and stop at the first blocking cell.
Visit the cells along an integer line and stop at the first blocking cell.
Visit the cells along an integer line and stop at the first blocking cell.
Keep room data separate from its picture, with checked reads, edits, properties and world-to-cell conversion.
Keep room data separate from its picture, with checked reads, edits, properties and world-to-cell conversion.
Keep room data separate from its picture, with checked reads, edits, properties and world-to-cell conversion.
Keep room data separate from its picture, with checked reads, edits, properties and world-to-cell conversion.
Keep room data separate from its picture, with checked reads, edits, properties and world-to-cell conversion.
Keep level data separate from the screen. Reusable integer BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Locomotive BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Atari BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Commodore BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Commodore BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Dragon BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Aquarius BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable MSX BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable Oric BASIC routines read and change tiles, look up properties and draw a small text region.
Keep level data separate from the screen. Reusable SVI BASIC routines read and change tiles, look up properties and draw a small text region.
A key collected, a door unlocked, a conversation finished: eight yes/no facts fit in one byte.
A key collected, a door unlocked, a conversation finished: eight yes/no facts fit in one byte.
A key collected, a door unlocked, a conversation finished: eight yes/no facts fit in one byte.
A key collected, a door unlocked, a conversation finished: eight yes/no facts fit in one byte.
Store byte-valued game requests in a bounded FIFO, with explicit full/empty results and validated wrap-around.
Store byte-valued game requests in a bounded FIFO, with explicit full/empty results and validated wrap-around.
Store byte-valued game requests in a bounded FIFO, with explicit full/empty results and validated wrap-around.
Fire an interrupt when the beam reaches a chosen scanline and change a VIC-II register mid-screen — the basis of colour bars, split panels, and beating the chip's limits.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Store two logical cells per numeric byte value and update either half without damaging its neighbour.
Store two logical cells per numeric byte value and update either half without damaging its neighbour.
Store two logical cells per numeric byte value and update either half without damaging its neighbour.
Sixteen tile values do not need sixteen whole bytes when each value fits in four bits.
Sixteen tile values do not need sixteen whole bytes when each value fits in four bits.
Sixteen tile values do not need sixteen whole bytes when each value fits in four bits.
Sixteen tile values do not need sixteen whole bytes when each value fits in four bits.
Format one byte as two ASCII digits and parse two checked digits back into a byte.
Format one byte as two ASCII digits and parse two checked digits back into a byte.
Format one byte as two ASCII digits and parse two checked digits back into a byte.
Packed flags and small fields can share a byte, provided the reader knows exactly how many bits remain.
Packed flags and small fields can share a byte, provided the reader knows exactly how many bits remain.
Packed flags and small fields can share a byte, provided the reader knows exactly how many bits remain.
Packed flags and small fields can share a byte, provided the reader knows exactly how many bits remain.
Extract up to eight bits at a time from a four-byte block, keeping a cursor and rejecting a field that would cross the end.
Extract up to eight bits at a time from a four-byte block, keeping a cursor and rejecting a field that would cross the end.
Extract up to eight bits at a time from a four-byte block, keeping a cursor and rejecting a field that would cross the end.
Accept one ASCII digit at a time while retaining the valid prefix, rejecting other characters and refusing values above 255.
Accept one ASCII digit at a time while retaining the valid prefix, rejecting other characters and refusing values above 255.
Accept one ASCII digit at a time while retaining the valid prefix, rejecting other characters and refusing values above 255.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Reuse the actual machine-specific reader, with its caller, state, ownership and a diagnosed input mistake.
Expand up to eight signed byte differences from an explicit base, wrapping modulo 256 and preserving output when input is invalid.
Expand up to eight signed byte differences from an explicit base, wrapping modulo 256 and preserving output when input is invalid.
Expand up to eight signed byte differences from an explicit base, wrapping modulo 256 and preserving output when input is invalid.
A sequence is about order.
A sequence is about order.
A sequence is about order.
A sequence is about order.
Remember a short ordered prefix, pulse on a match and retain the useful suffix for overlapping matches.
Remember a short ordered prefix, pulse on a match and retain the useful suffix for overlapping matches.
Remember a short ordered prefix, pulse on a match and retain the useful suffix for overlapping matches.
Check two boxes without wrapped coordinates, distinguish touching from overlap, and reuse the existing C64 helper.
Reuse the Amiga’s unsigned word-edge box test, with touching-edge errors, wider-coordinate limits and native proof.
Reuse a checked half-open rectangle test, understand touching edges and diagnose the equality mistake.
Reuse a checked half-open rectangle test, understand touching edges and diagnose the equality mistake.
A bounce can lose speed along a wall’s normal while keeping its sideways motion.
A bounce can lose speed along a wall’s normal while keeping its sideways motion.
A bounce can lose speed along a wall’s normal while keeping its sideways motion.
A bounce can lose speed along a wall’s normal while keeping its sideways motion.
A fast ball should use the distance left after a bounce rather than sticking to the wall.
A fast ball should use the distance left after a bounce rather than sticking to the wall.
A fast ball should use the distance left after a bounce rather than sticking to the wall.
A fast ball should use the distance left after a bounce rather than sticking to the wall.
Scale a normal-speed magnitude by quarter-step restitution, reverse its direction and preserve its tangential component.
Scale a normal-speed magnitude by quarter-step restitution, reverse its direction and preserve its tangential component.
Scale a normal-speed magnitude by quarter-step restitution, reverse its direction and preserve its tangential component.
A reused pool slot should not let an old reference suddenly name a different enemy.
A reused pool slot should not let an old reference suddenly name a different enemy.
A reused pool slot should not let an old reference suddenly name a different enemy.
A reused pool slot should not let an old reference suddenly name a different enemy.
Remember which pairs have already been considered during one traversal, without treating reversed IDs as a new pair.
Remember which pairs have already been considered during one traversal, without treating reversed IDs as a new pair.
Remember which pairs have already been considered during one traversal, without treating reversed IDs as a new pair.
The same contact can appear in both objects’ candidate lists.
The same contact can appear in both objects’ candidate lists.
The same contact can appear in both objects’ candidate lists.
The same contact can appear in both objects’ candidate lists.
Retain separate jump-buffer and coyote timers, grant a jump only when they overlap and consume permission after the pulse.
Retain separate jump-buffer and coyote timers, grant a jump only when they overlap and consume permission after the pulse.
Retain separate jump-buffer and coyote timers, grant a jump only when they overlap and consume permission after the pulse.
Append positions without shifting the buffer, then query a sample by its age, including after wraparound.
Append positions without shifting the buffer, then query a sample by its age, including after wraparound.
Append positions without shifting the buffer, then query a sample by its age, including after wraparound.
Changing one cell should not force a whole board to be redrawn.
Changing one cell should not force a whole board to be redrawn.
Changing one cell should not force a whole board to be redrawn.
Changing one cell should not force a whole board to be redrawn.
Pulse on a new hold, wait a configurable delay, then repeat at a separate cadence until release.
Pulse on a new hold, wait a configurable delay, then repeat at a separate cadence until release.
Pulse on a new hold, wait a configurable delay, then repeat at a separate cadence until release.
Seed and restore a portable eight-bit LFSR, expose corrupted zero state and keep random-call order explicit.
Seed and restore a portable eight-bit LFSR, expose corrupted zero state and keep random-call order explicit.
Seed and restore a portable eight-bit LFSR, expose corrupted zero state and keep random-call order explicit.
Standing in a doorway should not count as entering it on every update.
Standing in a doorway should not count as entering it on every update.
Standing in a doorway should not count as entering it on every update.
Standing in a doorway should not count as entering it on every update.
Turn an eight-bit overlap snapshot into separate entered, stayed and exited masks while retaining the previous snapshot.
Turn an eight-bit overlap snapshot into separate entered, stayed and exited masks while retaining the previous snapshot.
Turn an eight-bit overlap snapshot into separate entered, stayed and exited masks while retaining the previous snapshot.
Standard NES initialisation: disable interrupts, wait for PPU, clear RAM. Required boilerplate for every NES program.
Cancel opposed directions, then use retained axis preference to choose a single direction from a diagonal.
Cancel opposed directions, then use retained axis preference to choose a single direction from a diagonal.
Cancel opposed directions, then use retained axis preference to choose a single direction from a diagonal.
A maze character needs one direction even when the player holds a diagonal.
A maze character needs one direction even when the player holds a diagonal.
A maze character needs one direction even when the player holds a diagonal.
A maze character needs one direction even when the player holds a diagonal.
An empty magazine should refuse a shot, not turn into 255 rounds.
An empty magazine should refuse a shot, not turn into 255 rounds.
An empty magazine should refuse a shot, not turn into 255 rounds.
An empty magazine should refuse a shot, not turn into 255 rounds.
Enter, retain and leave a bounded ladder mode with explicit gravity and jump-release outputs.
Enter, retain and leave a bounded ladder mode with explicit gravity and jump-release outputs.
Enter, retain and leave a bounded ladder mode with explicit gravity and jump-release outputs.
Claim and release fixed game-object slots, handle exhaustion, and expire objects without moving their neighbours.
Give bullets, enemies and effects fixed slots, handle a full pool, and remove objects without skipping their neighbours.
Give bullets, enemies and effects fixed slots, handle a full pool, and remove objects without skipping their neighbours.
Claim and release fixed game-object slots, handle exhaustion, and expire objects without moving their neighbours.
Acquire the lowest free slot, reject invalid releases, and keep object lifetime in the game.
Acquire the lowest free slot, validate releases before indexing, and let the game own object lifetime.
Acquire the lowest free slot, check success before indexing, and keep object lifetime with the caller.
Allocate, release and age reusable object slots, with explicit full-pool results and caller-owned payloads.
Allocate, release and age reusable object slots, with explicit full-pool results and caller-owned payloads.
Allocate, release and age reusable object slots, with explicit full-pool results and caller-owned payloads.
A line of dialogue can appear a character at a time, with a button to show the rest immediately.
A line of dialogue can appear a character at a time, with a button to show the rest immediately.
A line of dialogue can appear a character at a time, with a button to show the rest immediately.
A line of dialogue can appear a character at a time, with a button to show the rest immediately.
Emit up to four event IDs with explicit quiet-call delays, retaining the cursor and emitting at most one event per call.
Emit up to four event IDs with explicit quiet-call delays, retaining the cursor and emitting at most one event per call.
Emit up to four event IDs with explicit quiet-call delays, retaining the cursor and emitting at most one event per call.
A reusable BASIC press-edge update with a MOS-paced caller, separate display work and verified held-key and missing-wait mistakes.
A reusable BASIC press-edge update with a MOS-paced caller, separate display work and verified held-key and missing-wait mistakes.
Capture three byte-valued fields in RAM and validate the complete stored record before restoring any live field.
Capture three byte-valued fields in RAM and validate the complete stored record before restoring any live field.
Capture three byte-valued fields in RAM and validate the complete stored record before restoring any live field.
Keep a separate packed background for each Spectrum object, then restore overlaps in reverse order. Reusable rectangle helpers and a complete masked-sprite tape caller.
Move word-aligned blitter objects over a persistent background. Reusable chip-RAM save, masked drawing and restore routines with a complete two-object ADF caller.
Move software objects over scenery without trails. Give each object its own saved background, handle overlaps in the right order, and choose when saved pixels stop being useful.
Draw a 1-cell border around the play area with title and footer bars. The standard game screen layout.
Move the camera, expose new scenery and keep objects attached to the world. Choose software shifts, hardware offsets and streaming for the machine you are using.
Reusable seed and next routines, repeatable draws, state replay and a visible zero-state trap.
Reusable seed and next routines, repeatable draws, state replay and a visible zero-state trap.
Reusable seed and next routines, repeatable draws, state replay and a visible zero-state trap.
Reusable seed and next routines, repeatable draws, state replay and a visible zero-state trap.
Background jobs should each get a turn when the game can afford only one piece of work this tick.
Background jobs should each get a turn when the game can afford only one piece of work this tick.
Background jobs should each get a turn when the game can afford only one piece of work this tick.
Background jobs should each get a turn when the game can afford only one piece of work this tick.
An enemy or homing projectile needs a target-selection rule that stays predictable when candidates tie.
An enemy or homing projectile needs a target-selection rule that stays predictable when candidates tie.
An enemy or homing projectile needs a target-selection rule that stays predictable when candidates tie.
An enemy or homing projectile needs a target-selection rule that stays predictable when candidates tie.
Extend BBC MODE4 masked drawing beyond one save slot. Each object gets its own background buffer and old cell address, with a running two-object caller.
A short tune needs a clock and a sequence of notes, not a fresh sound effect every frame.
A short tune needs a clock and a sequence of notes, not a fresh sound effect every frame.
A short tune needs a clock and a sequence of notes, not a fresh sound effect every frame.
A short tune needs a clock and a sequence of notes, not a fresh sound effect every frame.
A sound can swell, settle and fade instead of switching between full volume and silence.
A sound can swell, settle and fade instead of switching between full volume and silence.
A sound can swell, settle and fade instead of switching between full volume and silence.
A sound can swell, settle and fade instead of switching between full volume and silence.
A wave can have deliberate pauses without burying every spawn in the main loop.
A wave can have deliberate pauses without burying every spawn in the main loop.
A wave can have deliberate pauses without burying every spawn in the main loop.
A wave can have deliberate pauses without burying every spawn in the main loop.
A poison effect needs a duration and a pulse interval, not a fresh timer every time the actor is updated.
A poison effect needs a duration and a pulse interval, not a fresh timer every time the actor is updated.
A poison effect needs a duration and a pulse interval, not a fresh timer every time the actor is updated.
A poison effect needs a duration and a pulse interval, not a fresh timer every time the actor is updated.
Keep time moving between requests, then grant an action only when the cooldown and caller-supplied availability allow it.
Keep time moving between requests, then grant an action only when the cooldown and caller-supplied availability allow it.
Keep time moving between requests, then grant an action only when the cooldown and caller-supplied availability allow it.
Draw large seven-segment display digits using PLOT/DRAW. Cell-aligned with 1px outline. 10 DATA strings define all digits 0-9.
Service attack, decay, sustain and release as bounded logical control levels with retained gate-edge history.
Service attack, decay, sustain and release as bounded logical control levels with retained gate-edge history.
Service attack, decay, sustain and release as bounded logical control levels with retained gate-edge history.
Step a note pattern once per raster interrupt, handing each of the SID's three voices its note from a frequency table — the skeleton of every C64 music player.
Start a note on one SID voice by setting its gate, and end it by clearing the gate, with the envelope rates the chip actually uses.
Configure a SID voice with frequency, waveform, and ADSR envelope. Foundation for all SID audio programming.
Combine VIC-II fine offsets with a complete character and colour shift. Prepare the next column and budget the costly coarse step.
Move a Spectrum playfield one pixel at a time, supplying the newly exposed edge yourself. Reusable Z80 code and a running tiled-band caller.
When two sprites have the same depth, their order should not flicker from frame to frame.
When two sprites have the same depth, their order should not flicker from frame to frame.
When two sprites have the same depth, their order should not flicker from frame to frame.
When two sprites have the same depth, their order should not flicker from frame to frame.
Make a fixed beep, a rising or falling effect, and a short click with separate pitch and length controls.
Let the APU bend pitch and fade volume in hardware — a swept pulse for a laser, a decaying noise burst for an explosion — each fired with a single trigger write.
Reject unaffordable spending atomically, but accept a refill and cap it deliberately at 255.
Reject unaffordable spending atomically, but accept a refill and cap it deliberately at 255.
Reject unaffordable spending atomically, but accept a refill and cap it deliberately at 255.
Use sprite 0 overlap to mark a horizontal scroll split, with a missed-hit deadline and explicit PPU state ownership.
Cycle through animation frames with configurable timing. Walk cycles, explosions, idle animations.
Calculate and update Amiga sprite control words from X/Y coordinates. Position sprites anywhere on screen.
Move a C64 sprite with joystick port 2, clamp it to the screen edges, and handle its ninth X bit without disturbing other sprites.
Move sprites with joystick input and play area boundary checks. Foundation for player control.
Move sprites with D-pad input and screen boundary clamping. Essential for player-controlled objects.
Draw sixteen sprites in two fixed bands, with a complete raster IRQ example verified on PAL and NTSC emulators.
Draw animated objects with hardware sprites, software masking, blitter objects and combinations of them. Go beyond fixed hardware counts while making the compromises visible.
Organise game flow with distinct states (title, playing, game over). Clean separation of game phases.
Unpack logical RGB332, move each channel by one towards its target and repack without cross-channel carry.
Unpack logical RGB332, move each channel by one towards its target and repack without cross-channel carry.
Unpack logical RGB332, move each channel by one towards its target and repack without cross-channel carry.
A fade can approach its target one channel step at a time instead of treating a packed colour as a single number.
A fade can approach its target one channel step at a time instead of treating a packed colour as a single number.
A fade can approach its target one channel step at a time instead of treating a packed colour as a single number.
A fade can approach its target one channel step at a time instead of treating a packed colour as a single number.
Sweep one interval towards a requested endpoint, returning first contact instead of letting a fast step pass through a wall.
Sweep one interval towards a requested endpoint, returning first contact instead of letting a fast step pass through a wall.
Sweep one interval towards a requested endpoint, returning first contact instead of letting a fast step pass through a wall.
A fast object can cross a wall between frames even when neither endpoint overlaps it.
A fast object can cross a wall between frames even when neither endpoint overlaps it.
A fast object can cross a wall between frames even when neither endpoint overlaps it.
A fast object can cross a wall between frames even when neither endpoint overlaps it.
Understand the resources an exclusive Amiga caller owns, using the executed boot example and an explicit reset-to-leave lifetime.
Check an inclusive circular boundary without a square root, preserving full coordinate differences and enough arithmetic range for squared distances.
Check an inclusive circular boundary without a square root, preserving full coordinate differences and enough arithmetic range for squared distances.
Check an inclusive circular boundary without a square root, preserving full coordinate differences and enough arithmetic range for squared distances.
A round pickup should not become a square just because a box test was convenient.
A round pickup should not become a square just because a box test was convenient.
A round pickup should not become a square just because a box test was convenient.
A round pickup should not become a square just because a box test was convenient.
Align two eight-by-eight opaque masks, then return the first overlapping row rather than treating overlapping boxes as a pixel hit.
Align two eight-by-eight opaque masks, then return the first overlapping row rather than treating overlapping boxes as a pixel hit.
Align two eight-by-eight opaque masks, then return the first overlapping row rather than treating overlapping boxes as a pixel hit.
A sentry looking down a corridor must stop at the first wall.
A sentry looking down a corridor must stop at the first wall.
A sentry looking down a corridor must stop at the first wall.
A sentry looking down a corridor must stop at the first wall.
Two sprite boxes can overlap while their visible shapes still miss each other.
Two sprite boxes can overlap while their visible shapes still miss each other.
Two sprite boxes can overlap while their visible shapes still miss each other.
Two sprite boxes can overlap while their visible shapes still miss each other.
Centre text on any row and clear rows — two tiny subroutines used in every BASIC game.
Win or lose, the screen holds for a beat before any button is believed. The pause is the punctuation that lets the player read their own ending — and it stops a held button blowing through three screens in three frames.
A second of invulnerability after every respawn, covering every damage source, made visible by blinking the player. Without it, dying once where a hazard sits can spend every life in as many frames.
A level counter, a table index, and a HUD digit are three different numbers with three different caps. The counter never stops, the index clamps for safety, the digit caps for display — conflate them and the game lies about one of them.
A guard looking across a room needs more than a same-row check.
A guard looking across a room needs more than a same-row check.
A guard looking across a room needs more than a same-row check.
A guard looking across a room needs more than a same-row check.
Moving arrows from a chest to a pack should never remove more than the pack can hold.
Moving arrows from a chest to a pack should never remove more than the pack can hold.
Moving arrows from a chest to a pack should never remove more than the pack can hold.
Moving arrows from a chest to a pack should never remove more than the pack can hold.
Turning rows into columns is the building block behind rotating small glyphs and adapting bitmap layouts.
Turning rows into columns is the building block behind rotating small glyphs and adapting bitmap layouts.
Turning rows into columns is the building block behind rotating small glyphs and adapting bitmap layouts.
Turning rows into columns is the building block behind rotating small glyphs and adapting bitmap layouts.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Reuse a small real effect, understand who stops it, and compare its native output with an omitted-trigger control.
Store a phrase as timed events, distinguish looping from stopping, and trace the player separately from the hardware that makes the sound.
Convert an unsigned 16-bit value into exactly five ASCII character codes, preserving its two input bytes and making leading-zero policy explicit.
Convert an unsigned 16-bit value into exactly five ASCII character codes, preserving its two input bytes and making leading-zero policy explicit.
Convert an unsigned 16-bit value into exactly five ASCII character codes, preserving its two input bytes and making leading-zero policy explicit.
A joystick that rests a little off-centre should not make the player creep across the screen.
A joystick that rests a little off-centre should not make the player creep across the screen.
A joystick that rests a little off-centre should not make the player creep across the screen.
A joystick that rests a little off-centre should not make the player creep across the screen.
Record each cell’s previous value before editing it, then restore edits in reverse order with a four-entry log.
Record each cell’s previous value before editing it, then restore edits in reverse order with a four-entry log.
Record each cell’s previous value before editing it, then restore edits in reverse order with a four-entry log.
Commit one turn per press, then add a deadline without confusing the turn with the clock.
Commit one turn per press, then add a deadline without confusing the turn with the clock.
Commit one turn per press, then add a deadline without confusing the turn with the clock.
A damaged save should leave the current game alone rather than half-replacing it with invalid state.
A damaged save should leave the current game alone rather than half-replacing it with invalid state.
A damaged save should leave the current game alone rather than half-replacing it with invalid state.
A damaged save should leave the current game alone rather than half-replacing it with invalid state.
A reusable character-driven turn update, with a stock-firmware caller, owned state and verified mistakes and repairs.
A reusable character-driven turn update, with a stock-firmware caller, owned state and verified mistakes and repairs.
Read a command, update the world once and wait again, with a callable BASIC routine you can put in your own game.
Read a command, update the world once and wait again, with a callable BASIC routine you can put in your own game.
Reusable Atari BASIC turn updates, with a complete caller, bounded byte wrap, custom steps and an independently verified reset mistake.
Keep an untimed game waiting for the player, with a reusable command update, a working variation and a diagnosed state-reset mistake.
Keep an untimed game waiting for the player, with a reusable command update, a working variation and a diagnosed state-reset mistake.
Keep an untimed game waiting for the player, with a reusable command update, a working variation and a diagnosed state-reset mistake.
Keep an untimed game waiting for the player, with a reusable command update, a working variation and a diagnosed state-reset mistake.
Keep an untimed game waiting for the player, with a reusable command update, a working variation and a diagnosed state-reset mistake.
Reusable assembly turn state, independent field servicing and verified faulty/fixed callers, with Atari XL hardware ownership kept explicit.
Reusable assembly turn state, independent field servicing and verified faulty/fixed callers, with ColecoVision hardware ownership kept explicit.
Keep the display serviced while the game waits for one action, with separate reusable turn and field counters.
Keep the display serviced while the game waits for one action, with separate reusable turn and field counters.
Keep the display serviced while the game waits for one action, with separate reusable turn and field counters.
Reuse an untimed update with a small native caller, clear state ownership, a custom step and a reset mistake you can recognise.
Reuse an untimed update with a small native caller, clear state ownership, a custom step and a reset mistake you can recognise.
Keep an untimed world waiting for the player, with machine-specific code, a working variation and a state-reset mistake you can recognise.
Keep an untimed world waiting for the player, with machine-specific code, a working variation and a state-reset mistake you can recognise.
Reuse a bounded turn update with a native caller, clear ownership, a custom step and an observed reset mistake.
Keep an untimed world waiting for the player, with machine-specific code, a working variation and a state-reset mistake you can recognise.
Keep an untimed world waiting for the player, with machine-specific code, a working variation and a state-reset mistake you can recognise.
Reuse a bounded turn update with a native caller, clear ownership, a custom step and an observed reset mistake.
Reuse a bounded turn update with a native caller, clear ownership, a custom step and an observed reset mistake.
Reuse an untimed update with a small native caller, clear state ownership, a custom step and a reset mistake you can recognise.
Reuse an untimed update with a small native caller, clear state ownership, a custom step and a reset mistake you can recognise.
Reuse an untimed command or press loop while retaining the machine’s actual display responsibilities.
Reuse an untimed command or press loop while retaining the machine’s actual display responsibilities.
Reuse an untimed command or press loop while retaining the machine’s actual display responsibilities.
Reuse an untimed command or press loop while retaining the machine’s actual display responsibilities.
Reuse an untimed command or press loop while retaining the machine’s actual display responsibilities.
Reuse an untimed command or press loop while retaining the machine’s actual display responsibilities.
A guard should reach a waypoint before choosing the next, even when one movement step would overshoot it.
A guard should reach a waypoint before choosing the next, even when one movement step would overshoot it.
A guard should reach a waypoint before choosing the next, even when one movement step would overshoot it.
A guard should reach a waypoint before choosing the next, even when one movement step would overshoot it.
Move a bounded selection in either direction, wrap at the ends and skip options that are currently disabled.
Move a bounded selection in either direction, wrap at the ends and skip options that are currently disabled.
Move a bounded selection in either direction, wrap at the ends and skip options that are currently disabled.
A menu should wrap cleanly at either end and skip options the player cannot choose.
A menu should wrap cleanly at either end and skip options the player cannot choose.
A menu should wrap cleanly at either end and skip options the player cannot choose.
A menu should wrap cleanly at either end and skip options the player cannot choose.
Pack the low bits of a value into a four-byte block while preserving neighbouring bits and rejecting incomplete writes.
Pack the low bits of a value into a four-byte block while preserving neighbouring bits and rejecting incomplete writes.
Pack the low bits of a value into a four-byte block while preserving neighbouring bits and rejecting incomplete writes.
Flags and short fields can share a compact record without overwriting their neighbours.
Flags and short fields can share a compact record without overwriting their neighbours.
Flags and short fields can share a compact record without overwriting their neighbours.
Flags and short fields can share a compact record without overwriting their neighbours.