Web64 Game Runtime Libraries
Version: 2026-09-29
Copyright (c) 2026 Mika Jussila, Siteledger Solutions Oy
Web64 Game Runtime is a modular C library family for reusable C64 game machinery. Its independently linked modules cover subpixel Motion, deterministic authored Trajectories, material-map Collision, deterministic Animation, direct Sprite rendering, PAL sprite multiplexing, Actor pools and open actor batches, World maps and scrolling, and explicit composition helpers. Applications select only the modules they call.
This page is the short, findable library entry point. The complete generated SDK declarations remain in the Web64 C Compiler Manual, and exact printable source listings are available from Web64 SDK Header Printouts.
Web64 Game Runtime quick reference
The Game Runtime is composition-first. It never owns main(), never installs a hidden frame tick, and never links unrelated subsystems merely because a neighboring header was included. Call only the primitives your game needs, in the order your game loop owns.
| Need | Include | Primary calls/macros | Runtime closure | Does not imply |
|---|---|---|---|---|
| Shared Q12.4 positions and compact boxes | <web64/game.h> | WEB64_POS_FROM_PX, WEB64_POS_TO_PX, Web64GameBox | Header-only macros and types | Motion, collision, animation, sprites, actors |
| Hardware disk loading | <web64/loader.h> | web64_loader_init, web64_loader_read, web64_loader_load_raw, web64_loader_load_packed, web64_loader_unpack | Independently linked transport, raw, packed and decoder kernels | IRQ/vector ownership, music, display, caches, background loading, automatic KERNAL fallback |
| One-axis acceleration/braking and position integration | <web64/motion.h> | web64_motion_axis, web64_motion_steer_s16, web64_motion_integrate, web64_motion_clamp, web64_motion_wrap | Motion helpers only when called; literal cases may specialize inline | Collision, animation, sprites, actors |
| Bitmap setup and drawing | <web64/bitmap.h> | web64_bitmap_init, web64_bitmap_plot*, web64_bitmap_line*, web64_bitmap_rect*, web64_bitmap_ellipse*, web64_bitmap_flood_fill* | Only the called setup, pixel, line, shape, or flood module | Palette validity, hidden workspace, recursion, automatic screen/Color RAM palette rewrites |
| Authored delta/duration trajectories | <web64/trajectory.h> | web64_trajectory_validate, web64_trajectory_init*, web64_trajectory_step*, web64_trajectory_step_batch*, WEB64_TRAJECTORY_APPLY_* | Scalar execution exact-links web64-runtime/game-trajectory.asm; batch execution adds web64-runtime/game-trajectory-batch.asm and reuses the scalar module's private preparation/divider dependency; declarations, storage, and projection macros link neither | Actor ownership, Motion integration, collision, animation, sprites, mux |
| Material-map and AABB collision | <web64/collision.h> | web64_collision_material_at, web64_collision_probe_*, web64_collision_sweep_*, web64_collision_find_material_rect, web64_collision_map_write | Collision helpers only when called | Motion state, animation, rendering policy |
| Deterministic frame-tick animation | <web64/animation.h> | web64_animation_init, web64_animation_play, web64_animation_queue, web64_animation_tick, web64_animation_take_events | Animation player only | Motion, collision, sprite renderer |
| Direct eight-sprite and native pair rendering | <web64/sprite-runtime.h> | web64_sprite_renderer_init, web64_sprite_render, web64_sprite_render_asset_pair, web64_sprite_apply_overlay_palette, web64_sprite_render_attachment | web64-runtime/game-sprites.asm only | Animation playback, actors, multiplexer |
| PAL sprite multiplexing | <web64/sprite-mux.h> | WEB64_SPRITE_MUX_STORAGE, web64_sprite_mux_init, web64_sprite_mux_begin_frame, web64_sprite_mux_submit*, web64_sprite_mux_commit, web64_sprite_mux_irq_service, web64_sprite_mux_irq_service_fast | web64-runtime/game-sprite-mux.asm only | Direct renderer, IRQ vector/acknowledgement/RTI, hidden asset copying |
| Fixed-size actor pools | <web64/actors.h> | WEB64_ACTOR_POOL*, web64_actor_activate, web64_actor_deactivate | Actor helper only when activation/deactivation is called | Collision, animation, sprites, multiplexer |
| Open actor-batch pipeline | <web64/actor-batch.h> | web64_actor_batch_integrate_*, web64_actor_batch_animation_tick, web64_actor_batch_cull, web64_actor_batch_pairs_x, web64_actor_batch_build_commands, web64_actor_commands_*, web64_actor_batch_run_mux | Only the called phase or fused adapter and its exact dependencies | Allocation, a hidden game loop, hidden buffers, IRQ installation, asset copying |
| Optional fused helpers | <web64/game-compose.h> | web64_compose_motion_axis_integrate, web64_actor_motion_step | Exactly the primitives named by the helper | A framework update loop |
Typical explicit game-loop order:
- Read input and set intent/facing state.
- Apply motion primitives, or step authored trajectories and explicitly project their Q12.4 result into the game-owned Motion/Actor position storage.
- Run collision probes or sweeps, then apply game-owned responses.
- Tick animation players using the caller-owned frame tick.
- Render direct sprite states, or build and commit the next mux schedule.
- At the application-owned raster IRQ, acknowledge the source and call preserving
web64_sprite_mux_irq_service(), or callweb64_sprite_mux_irq_service_fast()when the enclosing dispatcher already preserved A/X/Y, before chaining or executingRTI.
Game Runtime flag groups:
| Group | Constants | Meaning |
|---|---|---|
| Material properties | WEB64_MATERIAL_SOLID, WEB64_MATERIAL_ONE_WAY, WEB64_MATERIAL_LADDER, WEB64_MATERIAL_HAZARD, WEB64_MATERIAL_TRIGGER, WEB64_MATERIAL_COLLECTIBLE, WEB64_MATERIAL_MODIFIER, WEB64_MATERIAL_USER | Bits stored in the 256-entry material-property table. |
| Collision contacts | WEB64_CONTACT_LEFT, WEB64_CONTACT_RIGHT, WEB64_CONTACT_CEILING, WEB64_CONTACT_FLOOR, WEB64_CONTACT_LADDER, WEB64_CONTACT_HAZARD, WEB64_CONTACT_TRIGGER, WEB64_CONTACT_COLLECTIBLE | Bits returned by collision probes, sweeps, and events. |
| Motion contacts | WEB64_MOTION_HIT_MIN_X, WEB64_MOTION_HIT_MAX_X, WEB64_MOTION_HIT_MIN_Y, WEB64_MOTION_HIT_MAX_Y | Boundary bits returned by clamp helpers. |
| Trajectory controls | WEB64_TRAJECTORY_NEGATE_X, WEB64_TRAJECTORY_NEGATE_Y, WEB64_TRAJECTORY_LOOP, WEB64_TRAJECTORY_PING_PONG, WEB64_TRAJECTORY_REVERSE | Per-instance traversal and mirroring over shared immutable pattern bytes. |
| Trajectory events/status | WEB64_TRAJECTORY_EVENT_SEGMENT, WEB64_TRAJECTORY_EVENT_LOOP, WEB64_TRAJECTORY_EVENT_DIRECTION, WEB64_TRAJECTORY_EVENT_COMPLETE, WEB64_TRAJECTORY_STATUS_* | Explicit deterministic transition events and checked-call outcomes. |
| Animation modes | WEB64_ANIMATION_LOOP, WEB64_ANIMATION_ONCE, WEB64_ANIMATION_PINGPONG, WEB64_ANIMATION_HOLD, WEB64_ANIMATION_HIDE | Sequence playback behavior. |
| Animation play policy/status | WEB64_ANIMATION_PLAY_IF_CHANGED, WEB64_ANIMATION_PLAY_RESTART, WEB64_ANIMATION_STATUS_COMPLETE, WEB64_ANIMATION_STATUS_HIDDEN | Caller-selected sequence switching and returned playback state. |
| Sprite flags | WEB64_SPRITE_VISIBLE, WEB64_SPRITE_MULTICOLOR, WEB64_SPRITE_EXPAND_X, WEB64_SPRITE_EXPAND_Y, WEB64_SPRITE_BEHIND | Direct renderer logical sprite-state bits. |
| Sprite mux status | WEB64_SPRITE_MUX_BUSY, WEB64_SPRITE_MUX_CAPACITY, WEB64_SPRITE_MUX_INVALID_FRAME, WEB64_SPRITE_MUX_PALETTE_MISMATCH, WEB64_SPRITE_MUX_UNSCHEDULABLE, WEB64_SPRITE_MUX_UNSUPPORTED_STANDARD | Explicit submission, scheduling, palette, and PAL/NTSC outcomes. |
| Actor storage options | WEB64_ACTOR_STORAGE_NONE, WEB64_ACTOR_STORAGE_ANIMATION, WEB64_ACTOR_STORAGE_SPRITE_BINDING | Storage-layout declarations only; they do not link animation or sprite runtime code. |
| Actor-batch pipeline facts | WEB64_ACTOR_MUX_PIPELINE_BOUNDS_STABLE, ANIMATION_TICKS_READY, DENSE_ACTIVE_IDS, ANIMATION_PRETICKED, PAIRS_PRECOMPUTED, STABLE_TOPOLOGY, STABLE_ORDER_IDENTITY, DENSE_MOTION_PREINTEGRATED | Caller-proven preparation facts that select measured fast paths. Supplying a false fact violates the _fast precondition; checked phase entry points retain validation. |
Hardware Loader Runtime
For synchronous raw/packed loading, the C and ASM ABI, transactional workspace, IRQ/music coexistence, SAVE/reinitialization and native disk authoring, see Web64 Hardware Loader Runtime. Its caller-owned memory and exact-link contracts apply to arbitrary applications, not only games.
Native Cartridge Runtime
For managed logical ROM resources and the expert physical bank/window API across Standard 8K, Standard 16K, Magic Desk and EasyFlash, see Web64 Native Cartridge Runtime. It documents C and web64/cartridge.inc assembly calls, generated resource handles, declared RAM ownership, status codes, and interrupt constraints.
Bitmap Drawing Runtime
The <web64/bitmap.h> runtime targets VIC-II standard bitmap memory: logical 320×200 hires pixels use indices 0–1 and logical 160×200 multicolor pixels use indices 0–3. Web64Bitmap is caller-owned and records the bitmap base, screen base, mode, background, VIC bank, D018 setup, and configured flag. web64_bitmap_configure() validates the VIC-visible layout without touching memory; web64_bitmap_init() additionally clears the bitmap, applies the caller palette, and activates the mode. Palette calls are explicit. Drawing calls never infer or rewrite palette assignments.
Imported PNG bitmaps in C
Import Bitmap... produces an editable charset and a character-index map. The charset contains reusable eight-byte bitmap cells; the map determines their position in the image. The import also creates a video-matrix plane and, for multicolor images, a Color RAM plane. Copying only <name>_charset to bitmap RAM copies the unique patterns once and cannot reproduce the displayed map.
After importing a 320×200 hires PNG named backdrop, save the project and use this C path. Include assets/generated.h and inspect its actual generated symbol names if the asset name differs. This example uses VIC bank 0, bitmap RAM at $2000, and screen RAM at $0400; keep the program and other assets clear of those addresses.
#include <stdint.h>
#include <web64/bitmap.h>
#include <assets/generated.h>
#define BITMAP_RAM ((uint8_t *)0x2000)
#define SCREEN_RAM ((uint8_t *)0x0400)
Web64Bitmap picture;
void main(void) {
if (web64_bitmap_configure(&picture, BITMAP_RAM, SCREEN_RAM,
WEB64_BITMAP_MODE_HIRES) != WEB64_BITMAP_OK) return;
if (web64_bitmap_load_map(&picture, &backdrop_tilemap_asset,
&backdrop_charset_asset) != WEB64_BITMAP_OK) return;
picture.background = backdrop_charset_background_color;
if (web64_bitmap_activate(&picture) != WEB64_BITMAP_OK) return;
while (1) {}
}
web64_bitmap_load_map expands the map's one- or two-byte cell indexes into bitmap RAM and copies the imported video-matrix plane to screen RAM. For a multicolor PNG, select WEB64_BITMAP_MODE_MULTICOLOR; the same helper also copies its Color RAM plane to $d800. The generated charset background-color constant supplies the import's shared background. The helper accepts a complete 40×25 bitmap-character map. Use the Map Editor's linked charset mode and assets/generated.h to confirm the mode and symbol names.
Assembly callers can include web64/bitmap.inc and use web64_rt_prepare_bitmap_load_map bitmap, map, charset to fill the six-byte _web64_rt argument window, or web64_rt_call_bitmap_load_map bitmap, map, charset to prepare it and call the routine. The editor's right sidebar shows these macro arguments as you type.
Checked plot, get, horizontal/vertical line, general line, rectangle, filled rectangle, and ellipse calls validate context, logical coordinates, pixel index, and operation. Their _fast counterparts require those preconditions. Replace and XOR are available for ordinary drawing. Dot and circle are transparent aliases for plot and equal-radius ellipse. The optimized general-line path canonicalizes endpoint order, selects a mode/operation/major-axis/minor-direction kernel, and advances the physical bitmap cursor incrementally. The independent benchmark covers both ABIs, both modes, shallow and steep octants, reverse endpoints, and horizontal lines; the maximum 319×199 hires diagonal measures 19,218 cycles under web64-static-v0 and 19,219 under web64-stack-v1, inside the 19,267-cycle acceptance gate.
web64_bitmap_flood_fill() and _fast() are intentionally replace-only in v1. Connectivity is four-neighbor against the logical source index read at the seed. The caller supplies a bounded Web64BitmapFloodWorkspace; there is no recursion and no hidden allocation. The checked entry validates the complete surface, seed, replacement, workspace descriptor, span extent, address wrap, and overlap with the context, bitmap, screen RAM, workspace descriptor, and Color RAM before mutation where possible. Each span is recorded before it is painted. Aligned span discovery and replacement compare and write complete bitmap bytes using the hires $00/$ff or multicolor $00/$55/$aa/$ff repeated-index patterns; adjacent byte columns advance by eight physical bitmap bytes, while irregular boundaries retain masked logical-pixel handling. If capacity is exhausted, every recorded span is restored through the same byte-oriented path to the original source index, workspace.used remains at the deterministic exhausted count, and status WEB64_BITMAP_WORKSPACE_EXHAUSTED is returned. Flood fill modifies bitmap bytes only and never changes screen RAM or Color RAM; the replacement index must already be valid for every affected cell palette.
WEB64_BITMAP_FLOOD_STORAGE(name, capacity) declares caller-owned span storage plus its descriptor, and WEB64_BITMAP_FLOOD_WORKSPACE_INIT(name, capacity) initializes the descriptor at run time. The flood benchmark is deliberately separate from line timing and covers small, fragmented, corridor, large-open, and near-full-screen regions for checked and fast calls in both bitmap modes, with an independent four-neighbor oracle and screen/Color RAM invariants.
Trajectory Pattern Runtime
A Web64TrajectoryPattern stores shared immutable 3-byte segments: signed pixel delta_x, signed pixel delta_y, and a 1–255-frame duration. Each caller-owned 19-byte Web64TrajectoryState carries independent Q12.4 position, traversal index/direction, prepared quotient/remainder, and centered error state. Forward, reverse, loop, ping-pong, X/Y mirroring, exact transition events, one-frame segments, and maximum-duration segments use the same public representation. Every segment reaches its exact mathematical endpoint; repeated loops cannot accumulate interpolation drift.
The optional first-class .w64traj authoring asset and independent Canvas Trajectory Editor compile to the same raw triplets; they do not change this runtime. The generated .traj contains no anchor, map, appearance, editor, or world metadata, and can be used from arbitrary caller coordinates by C, assembly, or custom code. The authoring source is never a runtime dependency. See Trajectory assets and Trajectory Editor for the generated-family and Tiled interchange workflow.
The selected 6502 strategy is measured generated-table hybrid preparation plus centered DDA. Duration one is direct, powers of two use shifts, duration three uses a complete generated quotient/remainder table (258 bytes), durations 5, 6, and 7 use compact fractional tables (10, 12, and 14 bytes), and duration 31 uses 5 integer bytes plus 62 fractional bytes. Other bounded durations retain exact arithmetic fallbacks. The fixed shared table set is therefore 361 bytes and the public state remains 19 bytes. On the representative 1,846-frame strategy gate the production hybrid measures 185,085 cycles, versus 202,494 for the zero-table hybrid, 207,028 for ordinary fixed preparation, and 245,959 plus 512 table bytes for reciprocal assistance. The tables are deterministically generated and exact-link only with scalar execution or the batch private-divider dependency; including declarations or allocating public trajectory storage links no table or runtime bytes.
web64_trajectory_step_batch() and web64_trajectory_step_batch_fast() advance up to 255 contiguous states in stable input order and write one event byte per state. The checked entry preflights the complete non-null, non-wrapping, non-overlapping state and event spans plus every state before mutation. The fast entry requires already validated lockstep states that share one immutable pattern, segment index, phase, and traversal mode; per-state X/Y negation may differ. Its RAM-resident self-modifying kernel is mainline-only and non-reentrant. It retains only patched operand addresses, detects caller-buffer relocation, and reconstructs every semantic decision from the public 19-byte states, so C or assembly may inspect or mutate those states between calls.
The strengthened eight-actor performance gate measures one direct-label batch call, excluding C argument marshalling and host-side pointer relocation while including JSR/RTS, transition preparation, public writes, and any required cold operand repatch. Its complete 24-variant matrix covers both C ABIs, four code origins, stable caller buffers, and both adverse $fb/$fc state/event low-byte arrangements. The current worst stable call is 3,481 cycles and the worst cold relocation/repatch call is 3,786 cycles. Both are below the 3,931-cycle practical acceptance gate (20% of a 19,656-cycle PAL frame); the cold case retains 145 cycles of headroom. The 4,914-cycle 25% line remains the absolute rejection ceiling, not the acceptance target.
Interoperability is explicit and additive. WEB64_TRAJECTORY_APPLY_BODY() projects a state into an existing Web64Motion2D; WEB64_TRAJECTORY_APPLY_POSITION() projects into caller-owned Actor Batch X/Y arrays. Both are transparent header-only assignments: they allocate nothing, hide no mirror, and link no adapter. Both ABI builds are byte-identical to spelling the same four public-buffer assignments by hand, so the convenience boundary adds no instructions, bytes, or calls. The scalar executor depends on no Actor, Motion, Sprite, or Mux module. Batch execution exact-links only game-trajectory.asm and game-trajectory-batch.asm; no Actor, Sprite, or Mux runtime is pulled in. A verified mixed pipeline steps trajectory state, publishes it into Actor SoA storage, culls, builds public sprite commands, and submits them to the mux with exactly five unique closures and neither redundant actor-motion nor direct-sprite code. Games may instead consume the same state from assembly or render it through the direct sprite runtime, as the standalone example does.
Every parameterized trajectory entry follows _web64_rt. web64/trajectory.inc owns the packed layout offsets, limits, masks, event bits, status constants, and standard web64_rt_prepare_trajectory_* / web64_rt_call_trajectory_* helpers; compatible web64_trajectory_prepare_* / web64_trajectory_call_* aliases remain. web64/runtime.inc is the optional whole-registry catalog for callable labels and exact-width named argument windows. The trajectory helpers expand to ordinary assembly, add no hidden storage or adapter, and unused helpers link no runtime. The independent Kick-compatible scalar oracle uses the same pointer-based public state contract. Across an origin/alignment sweep it measures 716,485 cycles. Web64 measures at most 676,801 cycles under web64-static-v0 and 676,782 under web64-stack-v1, including legitimate direct-label preparation and calls but excluding C argument marshalling: 39,684 cycles (5.539%) and 39,703 cycles (5.541%) of headroom. The trajectory-patterns example runs eight independently phased instances sharing one pattern, exercises every X/Y negation combination plus loop/ping-pong behavior, exposes the state to an assembly reader, and exact-links only game-trajectory.asm plus the deliberately selected direct sprite renderer. Its trajectory-patterns-asm companion uses a setup-only fast batch window in the native hot loop and proves the helpers preserve the existing sub-20% PAL measurements.
Native overlay pairs and PAL sprite multiplexing
A .spritepair.json file is an editor/compiler descriptor, not a runtime byte payload. The compiler applies the Sprite Editor shared validator, resolves one multicolor base bank and one mono overlay bank, and emits a Web64SpriteOverlayAsset that references both Web64SpriteAsset descriptors. Missing layers, duplicate paths, wrong modes, zero or unequal frame counts, and counts above 256 are compile diagnostics. Merely compiling pair metadata links no runtime and embeds no JSON bytes.
Web64SpriteOverlayBinding adds only the installed frame-zero VIC pointer values. The application must copy both 64-byte-aligned layer banks into the active VIC bank. web64_sprite_render_asset_pair() validates both independent frame indices and pointer additions before touching VIC state, applies descriptor colors, shares position/expansion/priority, forces the base to multicolor and overlay to mono, and places the overlay in the higher-precedence VIC slot. web64_sprite_apply_overlay_palette() is the explicit $d025/$d026 write.
The PAL mux is caller-owned and double buffered. Capacity is 1–24 physical layers; a pair consumes two and is always accepted or dropped atomically. begin_frame() opens the inactive buffer, submissions are ordered by descending priority then submission order, and commit() publishes one pending schedule. event_line, end_line, and per-slot interval ends are 16-bit raster positions, so line 300 cannot alias line 44. Commit converts accepted entries into 24-byte prepared display-list records, including complete owned-slot VIC control snapshots. Stable-topology adapters may publish a deterministic layout generation and refresh that schedule without rebuilding it. stable_identity_x_low is a public proof byte: the fused adapter sets it only after proving the viewport's entire representable VIC X range is below 256; stable commit may then omit the cumulative X-high scan. A generic or high-X schedule leaves it clear and uses the complete scan. The raster IRQ uses patched absolute-indexed low/high windows and direct stores rather than recomputing masks. Schedules with at most ten accepted entries patch only the live low operand window; larger capacities retain the complete low/high patcher. Reuse admission reserves ceil((300 + 48 * layers + 63) / 63) PAL lines: seven for one layer and eight for an atomic pair. The measured worst aligned fast intervals are 283 and 337 cycles; modeled KERNAL entry plus the example acknowledgement wrapper brings the end-to-end paths to 336 and 390 cycles, below the 378/441-cycle budgets that remain after the full 63-cycle safety line. The 49-cycle Web64 handler-tail-to-next-compare path beats the bundled Copper64 normal irqHandlersReturn plus fetchNext reference path of 76 cycles for that equivalent dispatch segment. IRQ dispatch follows the mux-owned armed compare identity, so entry latency cannot confuse line 300 with a later current raster value. A pending schedule is consumed only by the armed PAL line-300 boundary; without another commit, the active schedule repeats. NTSC initialization returns WEB64_SPRITE_MUX_UNSUPPORTED_STANDARD.
The mux updates only its owned hardware slots and owned bits in $d010/$d015/$d017/$d01b/$d01c/$d01d, plus their coordinates, colors, and pointer entries. $d025/$d026 are the active mux shared palette. The application retains the IRQ vector, source identification and $d019/CIA acknowledgement, chaining, game tick, and RTI. web64_sprite_mux_irq_service() preserves A/X/Y; web64_sprite_mux_irq_service_fast() clobbers them and is for a wrapper such as the KERNAL $0314 dispatcher that already owns the register envelope. Both paths use module-local absolute scratch rather than compiler zero page $02-$17 or call scratch $fb-$fe.
See the standalone sprite-multiplexer-overlay project in web64-examples for nine moving native overlay pairs rendered as eighteen physical layers. A compact unsigned 32-sample sine lookup supplies smooth side-to-side X coordinates at quarter-turn phase offsets, so the rows weave without linking the Motion runtime. Three pairs simultaneously fill the six owned slots and six later pairs exercise repeated two-slot reuse. Every pair supplies independent four-frame base and overlay indices; the runtime converts both pointers, preserves shared geometry, forces a multicolor base and mono overlay, and assigns the overlay higher VIC precedence. The final low-priority pair is dropped as one logical entry and two physical layers. Its live PAL gate requires 120 consecutive complete frames with no cherry-picking, exact frame/tick progression, the bounded bidirectional lookup wave and all four base/overlay frames in every active pair, at least forty bright mono-overlay pixels in every pair region, stable reserved HUD bytes, and the same deterministic atomic drop.
Open actor-batch runtime
Web64ActorBatchView points at the existing caller-owned active IDs and Q12.4 position, velocity, geometry, category, and mask arrays. Animation, sprite bindings, visible records, coherent X order, actor pairs, resolved render commands, bounds, and status remain separate public buffers. Capacities and actor IDs are at most 255. Native overlay pairs carry independent base and overlay frames but remain one atomic render command. Checked calls validate before mutation; _fast calls accept documented prepared layouts and use the same buffers. Every phase is an exact-closure module, so selecting motion does not link culling, pair generation, commands, or either renderer.
The X-sweep repairs caller-owned order deterministically by left edge and actor ID, applies symmetric category/mask filtering and half-open AABBs, emits each overlapping pair once, and reports predictable buffer overflow. Culling preserves active-ID order and emits only positions representable by the explicit camera viewport. Command building resolves all frame and pointer arithmetic before append, so a bad layer cannot expose half a pair. The direct adapter sorts by priority and stable order, touches only its owned slots, and gives an overlay the higher VIC precedence. The mux adapter submits resolved commands but never begins or commits a frame. Neither adapter copies sprite bytes or writes the shared palette implicitly.
web64_actor_batch_run_mux_fast() is the production fused adapter for callers that can prove the pipeline facts in Web64ActorMuxPipeline.flags. Bounds, animation preparation, pair results, stable topology/order, and preintegrated motion can be supplied or retained openly by the application; no private runtime mirror replaces them. Its self-modifying kernels are RAM-resident, mainline-only, non-reentrant, and include operand preparation in their measured cost. The matching web64/actor-batch.inc publishes every structure offset, flag, status, entry label, and _web64_rt argument-window symbol for native or Kick-compatible assembly consumers.
The canonical 24-actor workload has 18 visible actors, four overlay pairs, motion, animation, culling, pair output, public commands, and mux output. The frozen competent KickAssembler baseline is 15,338 cycles. The complete Web64 fused direct-label path, including legitimate internal preparation and JSR/RTS but excluding C argument marshalling, measures 14,908 cycles under web64-static-v0 and 14,914 under web64-stack-v1: 430 and 424 cycles of headroom (2.80% and 2.76%) with byte-identical semantic output. The original 9,828-cycle figure remains an aspirational research target, not a release gate. The independent _web64_rt measurement reduces the six-call C-facing overhead from 756 to 252 cycles under both ABIs.
Open _web64_rt runtime ABI
All 163 parameterized native web64_* runtime functions use registry-generated exact-width named argument windows. This includes hardware loading, disk and file I/O, cartridge resources, fixed-point math, asset copying, bitmap drawing, motion, collision, animation, direct sprites, sprite multiplexing, actors, actor batches, trajectories, and World. Ordinary application C remains ordinary C: the bundled external declarations select the runtime convention, pure arguments are written directly into the window, and side-effectful expressions retain stable ordinary marshalling. The 10 parameterless native runtime entry points need no window and retain their direct labels.
Every native Web64 runtime family now has a self-contained assembly include such as web64/fixed.inc, web64/actor-batch.inc, or web64/world.inc. Registry-generated web64_rt_prepare_* helpers fill complete exact-width named windows, while web64_rt_call_* helpers prepare and call the unchanged underscore-prefixed entry; parameterless entries receive the call form only. C-owned structs and buffers pass directly by emitted labels such as _view, with no copy or private mirror. The expansion is byte-identical to handwritten window stores plus JSR, and an unused family include links zero runtime bytes. web64/runtime.inc remains the optional whole-registry metadata catalog. Windows are public, adjacent to their entries, mainline-only, and non-reentrant unless an entry documents otherwise. No ABI call allocates memory, copies an asset implicitly, installs an interrupt, or hides caller-owned state.
The standalone actor-batch-arena example keeps 32 actors in open SoA storage, moves all 32 through an application-owned sine/velocity adapter, renders an 18-actor hot cohort with four independently animated native overlay pairs, reserves direct HUD slots 0–1, and gives the mux slots 2–7. Its stable PAL frame accepts nine logical entries and 13 physical layers, deterministically drops nine entries/nine layers, and repeatedly reuses slots. The executable gate completed 120 consecutive live PAL frames with all 18 visible actors observed moving, zero busy-frame submissions, correct atomic pair precedence, stable HUD bytes, and a measured 12,487-cycle application frame workload.
Runtime kernel performance and compatibility
The September 2026 runtime optimization campaign changes internal kernels, not public layouts or calling conventions. C under both supported ABIs and direct assembly use the same entries, exact-width windows, generated prepare/call helpers, and caller-owned state. Mainline helpers remain non-reentrant; no new IRQ ownership or scratch allowance is implied.
| Operation and measured case | Direct-label cycles before → after | Conditions |
|---|---|---|
| Hires plot at (319,199) | 1,002 → 304 | Fast replace, includes address/mask preparation and JSR/RTS |
| Animation sequence 2, step 3 transition | 1,525 → 814 static; 1,518 → 814 stack | Same 11-byte player, 4-byte sequence and step records |
| AABB high-bit category overlap | 964 → 448 | Native byte-mask intersection, unchanged half-open bounds |
| Material-map row 255 | 16,301 → 759 | 16-byte stride; bounded full-width row multiplication |
| Direct sprite slot 7, unchanged cache | 415 → 252 | Same 51-byte renderer and dirty-write behavior |
These are executed 6502 kernel measurements, not whole-game frame rates. C argument marshalling is additional: 52 cycles for the hires plot, 12 for the animation tick, 24 for the AABB call, 40 for the material lookup, and 58 for the sprite call in these fixtures. Explicit immediate-load/absolute-store ASM window preparation costs 42, 12, 24, 36, and 54 cycles respectively. Neither call boundary is hidden in the runtime comparison.
Bitmap addressing no longer walks preceding character rows, and animation addressing no longer walks preceding four-byte records. The direct sprite path adds one independently exact-linked 8-byte mask table while reducing total isolated closure by 5 bytes; renderer initialization alone does not link that table. Slot 0 costs eight extra cycles, while the other slots improve. No large generic lookup table or per-instance storage was added.
Web64CollisionMap row addressing honors the full 16-bit height and row stride. A pre-existing truncation made row 256 alias row 0; rows above 255 now access their correct cells. Out-of-range coordinates still return the configured outside material. The fixed address kernel adds 16 code bytes and costs five extra cycles for the measured row-1 case, in exchange for correctness and bounded work on taller maps.
The unchanged Ascender hybrid C/ASM example shrinks from 12,428 to 12,307 PRG bytes. Its sampled headless update/render maximum falls from 18,615 to 17,933 cycles, excluding raster idle. A separate real VICE run presents all 180 sampled PAL frames without a missed page flip, compared with two missed presentations with the baseline runtime. Canonical per-presentation screen/sprite output and native charset bytes remain identical; this is a bounded regression test, not a guarantee for every possible play session. The Mirror Pulse example also retains canonical rendering while shrinking by 59 bytes in both ABI rendering fixtures. Its published URL-loading demo disk is maintained separately and need not match the latest build.
Web64 Game Runtime World module quick reference
World is an independently linked module family within Web64 Game Runtime, alongside Motion, Collision, Animation, Sprites, and Actors. It streams already-linked native Web64 asset planes into screen RAM and Color RAM, but it does not own main(), the frame tick, IRQ policy, camera policy, collision meaning, or game rules.
| Need | Include | Primary calls/macros | Runtime closure | Does not imply |
|---|---|---|---|---|
| Shared world/camera/view types | <web64/world.h> | Web64WorldCamera, Web64WorldView, Web64WorldRect, WEB64_WORLD_PIXEL_TO_CELL, WEB64_WORLD_SUBPIXEL_TO_PIXEL/CELL/FINE | Header-only macros and types | Static rendering, scrolling, mutation, collision, sprites |
| Video-mode setup | <web64/world.h> | web64_world_apply_video_mode | World video helper only | Renderer, scroller, other Game Runtime modules |
| Static native-map rendering | <web64/world.h> | web64_world_draw_char_view, web64_world_draw_block2_view | World render helper only | Scroller, collision policy, sprites |
| Screen-only rendering | <web64/world.h> | web64_world_draw_char_view_screen, web64_world_draw_block2_view_screen, WEB64_WORLD_COLOR_NONE | Specialized render code with no color/material setup, reads, or writes | Color RAM or a material plane |
| Offscreen strip primitives | <web64/world.h> | web64_world_stream_column, web64_world_stream_row, web64_world_shift_* | World scroll helpers only | Permission to modify the screen currently selected by VIC-II; Motion, Collision, Animation, Sprites, Actors |
| Screen-only strip and mutation helpers | <web64/world.h> | web64_world_stream_column_screen, web64_world_stream_row_screen, web64_world_shift_*_screen, web64_world_mutate_cell_screen | Specialized screen-only helpers | Color RAM, material planes, collision policy |
| Fine-scroll camera math | <web64/world.h> | web64_world_scroll_x, web64_world_scroll_y, web64_world_camera_sync_x/y, web64_world_camera_vic_fine_x/y | World scroll helper only | Rendering, user input, motion, collision, IRQ installation |
| Buffered smooth-scrolling templates | generated src/world-scroll.asm | asm_world_scroll_init, asm_world_scroll_step | Exact project-local renderer plus explicitly called modules | Visible-screen shifts, in-loop Color RAM rewrites, framework-owned input/tick policy |
| Visible mutation | <web64/world.h> | web64_world_mutate_cell | World mutation helper only | Collectible/hazard/gameplay policy |
| Native asset wrappers | project tree | .w64chr, .w64blk, .w64map, .w64spr | Editable first-class asset files with deterministic generated outputs | Legacy .chr, .blk, .map, .spr conversion loss |
Game Runtime World-module template families:
- World Static Map
- World Horizontal Scroller
- World Subpixel Motion Scroller
- World Vertical Scroller
- World Bidirectional Scroller
- World Multicolor Platformer
- World + Motion and Sprites
The moving templates use transactional double buffering and never modify the displayed VIC screen. A complete next viewport is rendered into the hidden page; D018, D016, and D011 are staged and committed together at the frame boundary. Physical page ownership is released only after presentation, so a high-speed or subpixel caller cannot render into a page that is still visible. Horizontal movement uses 38-column geometry and vertical movement uses verified 25-row geometry. Default buffered templates fill Color RAM once with a stable region color and perform no in-loop Color RAM writes; the static renderer and explicitly scheduled public APIs retain exact per-cell color support. Stopping and reversal preserve the exact partial fine phase.
The Subpixel Motion template keeps its authoritative camera position in Motion Q12.4 and passes that position through web64_world_camera_sync_x(). Its PAL-safe profile visibly demonstrates 0.125-4.0 pixels/frame, progressive acceleration and braking, reversal through zero, and deterministic settling without feeding rounded renderer coordinates back into physics. The renderer consumes up to four integer scroll steps per game tick so its displayed position tracks the Motion target instead of lagging behind it.
The executable benchmark measures complete sustained edge-to-edge movement using stable region Color RAM in the transactional buffered templates. Worst frames are 14,499 cycles horizontal (62.041% below the frozen 38,196-cycle path), 17,708 vertical (51.305% below 36,365), 15,223 bidirectional (60.145% below 38,196), and 14,746 multicolor bidirectional (61.394% below 38,196). The composed 0.125-4.0-pixel Motion + World update peaks at 16,083 cycles. Displayed-screen writes and in-loop Color RAM writes are zero; idle frames also perform zero screen writes. The equivalent public per-cell horizontal boundary path uses 31,485 cycles versus 37,156 for the repository c64lib tile2 compatibility path, a 15.263% advantage while both write 880 screen and 880 Color RAM cells.
Reference and print links:
web64/loader.h— printable listingweb64/loader.inc— printable listingweb64/assets.h— printable listingweb64/assets.inc— printable listingweb64/disk.h— printable listingweb64/disk.inc— printable listingweb64/fixed.h— printable listingweb64/fixed.inc— printable listingweb64/game.h— printable listingweb64/motion.h— printable listingweb64/motion.inc— printable listingweb64/bitmap.h— printable listingweb64/bitmap.inc— printable listingweb64/trajectory.h— printable listingweb64/trajectory.inc— printable listingweb64/collision.h— printable listingweb64/collision.inc— printable listingweb64/animation.h— printable listingweb64/animation.inc— printable listingweb64/sprite-runtime.h— printable listingweb64/sprite-runtime.inc— printable listingweb64/sprite-mux.h— printable listingweb64/sprite-mux.inc— printable listingweb64/actor-batch.h— printable listingweb64/actor-batch.inc— printable listingweb64/runtime.inc— printable listingweb64/actors.h— printable listingweb64/actors.inc— printable listingweb64/game-compose.h— printable listingweb64/world.h— printable listingweb64/world.inc— printable listing
Game Runtime header printouts
| Header | Summary | Printout |
|---|---|---|
web64/actor-batch.h | Open caller-owned actor SoA phases, pair/visible/command buffers, direct and mux adapters, fused prepared pipeline, and checked/fast entry points. | raw |
web64/actor-batch.inc | Assembly ABI constants, exact structure offsets, flags, status values, and standard runtime prepare/call macros. | raw |
web64/actors.h | Compile-time actor-pool storage macros plus activation and compaction helpers. | raw |
web64/actors.inc | Registry-generated Actor-pool runtime prepare/call macros for native assembly. | raw |
web64/animation.h | Independent deterministic animation-bank playback state, sequence control, completion status, and step events. | raw |
web64/animation.inc | Registry-generated Animation runtime prepare/call macros for native assembly. | raw |
web64/assets.h | Public Web64 Asset Model v1 descriptor types and constants for generated asset metadata. | raw |
web64/assets.inc | Registry-generated Web64 Asset Model runtime prepare/call macros for native assembly. | raw |
web64/bitmap.h | Caller-owned C64 hires and multicolor bitmap setup, logical-pixel drawing primitives, optimized line kernels, and bounded replace-only scanline flood fill. | raw |
web64/bitmap.inc | Bitmap layouts, constants, and registry-generated native assembly prepare/call macros. | raw |
web64/collision.h | Independent material-map and AABB collision probes, swept contacts, interaction queues, and map mutation helpers. | raw |
web64/collision.inc | Registry-generated Collision runtime prepare/call macros for native assembly. | raw |
web64/disk.h | Dependency-linked disk load/save, streaming file I/O, disk markers, and IDE-assisted disk swap requests. | raw |
web64/disk.inc | Registry-generated disk and file-I/O runtime prepare/call macros for native assembly. | raw |
web64/fixed.h | 8.8 fixed-point, secondary 16.16 macros, angle8 trig helpers, and vector/motion declarations. | raw |
web64/fixed.inc | Registry-generated fixed-point runtime prepare/call macros for native assembly. | raw |
web64/game-compose.h | Opt-in composition macros for proven hot primitive combinations without introducing a framework update loop. | raw |
web64/game.h | Shared Game Runtime numeric contract, Q12.4 conversion macros, and compact point/delta/box structs. | raw |
web64/loader.h | Synchronous hardware loading and transactional W64X installation with caller-owned RAM, IRQ and lifecycle. | raw |
web64/loader.inc | Exact-width native ASM loader argument windows, request offsets and convenience macros. | raw |
web64/motion.h | Independent subpixel motion primitives for acceleration, braking, clamping, wrapping, gravity, and integration. | raw |
web64/motion.inc | Registry-generated Motion runtime prepare/call macros for native assembly. | raw |
web64/runtime.inc | Registry-generated _web64_rt entry and exact-width named argument-window reference for native and Kick-compatible assembly callers. | raw |
web64/sprite-mux.h | Caller-owned PAL schedule storage, deterministic atomic submissions, double-buffer publication, explicit status, and application-chained IRQ service. | raw |
web64/sprite-mux.inc | Registry-generated sprite-multiplexer prepare/call macros, including parameterless IRQ-service calls, for native assembly. | raw |
web64/sprite-runtime.h | Independent direct eight-sprite renderer with 9-bit X, dirty writes, camera projection, native overlay-asset pairs, and raw attachment helpers. | raw |
web64/sprite-runtime.inc | Registry-generated direct-sprite runtime prepare/call macros for native assembly. | raw |
web64/trajectory.h | Compact deterministic waypoint patterns, caller-owned Q12.4 execution state, exact scalar and synchronized-batch stepping, and transparent Motion/Actor projection. | raw |
web64/trajectory.inc | Assembly ABI constants, exact packed offsets, standard runtime prepare/call macros, compatible trajectory aliases, descriptor/storage emitters, and position-copy helpers. | raw |
web64/world.h | Independent Game Runtime World-module camera, viewport, native asset streaming, static rendering, fine-scroll, and visible mutation declarations. | raw |
web64/world.inc | Registry-generated World runtime prepare/call macros for native assembly. | raw |
Related documentation
- Complete Web64 examples repository — ready-to-open games, scrolling demos, and runtime projects
- Web64 C Compiler User Manual
- Web64 SDK Header Printouts
- Web64 IDE User Manual