Web64 logo Web64 Documentation Web64 Game Runtime Libraries

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.

NeedIncludePrimary calls/macrosRuntime closureDoes not imply
Shared Q12.4 positions and compact boxes<web64/game.h>WEB64_POS_FROM_PX, WEB64_POS_TO_PX, Web64GameBoxHeader-only macros and typesMotion, 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_unpackIndependently linked transport, raw, packed and decoder kernelsIRQ/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_wrapMotion helpers only when called; literal cases may specialize inlineCollision, 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 modulePalette 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 neitherActor 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_writeCollision helpers only when calledMotion 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_eventsAnimation player onlyMotion, 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_attachmentweb64-runtime/game-sprites.asm onlyAnimation 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_fastweb64-runtime/game-sprite-mux.asm onlyDirect renderer, IRQ vector/acknowledgement/RTI, hidden asset copying
Fixed-size actor pools<web64/actors.h>WEB64_ACTOR_POOL*, web64_actor_activate, web64_actor_deactivateActor helper only when activation/deactivation is calledCollision, 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_muxOnly the called phase or fused adapter and its exact dependenciesAllocation, 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_stepExactly the primitives named by the helperA framework update loop

Typical explicit game-loop order:

  1. Read input and set intent/facing state.
  2. Apply motion primitives, or step authored trajectories and explicitly project their Q12.4 result into the game-owned Motion/Actor position storage.
  3. Run collision probes or sweeps, then apply game-owned responses.
  4. Tick animation players using the caller-owned frame tick.
  5. Render direct sprite states, or build and commit the next mux schedule.
  6. At the application-owned raster IRQ, acknowledge the source and call preserving web64_sprite_mux_irq_service(), or call web64_sprite_mux_irq_service_fast() when the enclosing dispatcher already preserved A/X/Y, before chaining or executing RTI.

Game Runtime flag groups:

GroupConstantsMeaning
Material propertiesWEB64_MATERIAL_SOLID, WEB64_MATERIAL_ONE_WAY, WEB64_MATERIAL_LADDER, WEB64_MATERIAL_HAZARD, WEB64_MATERIAL_TRIGGER, WEB64_MATERIAL_COLLECTIBLE, WEB64_MATERIAL_MODIFIER, WEB64_MATERIAL_USERBits stored in the 256-entry material-property table.
Collision contactsWEB64_CONTACT_LEFT, WEB64_CONTACT_RIGHT, WEB64_CONTACT_CEILING, WEB64_CONTACT_FLOOR, WEB64_CONTACT_LADDER, WEB64_CONTACT_HAZARD, WEB64_CONTACT_TRIGGER, WEB64_CONTACT_COLLECTIBLEBits returned by collision probes, sweeps, and events.
Motion contactsWEB64_MOTION_HIT_MIN_X, WEB64_MOTION_HIT_MAX_X, WEB64_MOTION_HIT_MIN_Y, WEB64_MOTION_HIT_MAX_YBoundary bits returned by clamp helpers.
Trajectory controlsWEB64_TRAJECTORY_NEGATE_X, WEB64_TRAJECTORY_NEGATE_Y, WEB64_TRAJECTORY_LOOP, WEB64_TRAJECTORY_PING_PONG, WEB64_TRAJECTORY_REVERSEPer-instance traversal and mirroring over shared immutable pattern bytes.
Trajectory events/statusWEB64_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 modesWEB64_ANIMATION_LOOP, WEB64_ANIMATION_ONCE, WEB64_ANIMATION_PINGPONG, WEB64_ANIMATION_HOLD, WEB64_ANIMATION_HIDESequence playback behavior.
Animation play policy/statusWEB64_ANIMATION_PLAY_IF_CHANGED, WEB64_ANIMATION_PLAY_RESTART, WEB64_ANIMATION_STATUS_COMPLETE, WEB64_ANIMATION_STATUS_HIDDENCaller-selected sequence switching and returned playback state.
Sprite flagsWEB64_SPRITE_VISIBLE, WEB64_SPRITE_MULTICOLOR, WEB64_SPRITE_EXPAND_X, WEB64_SPRITE_EXPAND_Y, WEB64_SPRITE_BEHINDDirect renderer logical sprite-state bits.
Sprite mux statusWEB64_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_STANDARDExplicit submission, scheduling, palette, and PAL/NTSC outcomes.
Actor storage optionsWEB64_ACTOR_STORAGE_NONE, WEB64_ACTOR_STORAGE_ANIMATION, WEB64_ACTOR_STORAGE_SPRITE_BINDINGStorage-layout declarations only; they do not link animation or sprite runtime code.
Actor-batch pipeline factsWEB64_ACTOR_MUX_PIPELINE_BOUNDS_STABLE, ANIMATION_TICKS_READY, DENSE_ACTIVE_IDS, ANIMATION_PRETICKED, PAIRS_PRECOMPUTED, STABLE_TOPOLOGY, STABLE_ORDER_IDENTITY, DENSE_MOTION_PREINTEGRATEDCaller-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 caseDirect-label cycles before → afterConditions
Hires plot at (319,199)1,002 → 304Fast replace, includes address/mask preparation and JSR/RTS
Animation sequence 2, step 3 transition1,525 → 814 static; 1,518 → 814 stackSame 11-byte player, 4-byte sequence and step records
AABB high-bit category overlap964 → 448Native byte-mask intersection, unchanged half-open bounds
Material-map row 25516,301 → 75916-byte stride; bounded full-width row multiplication
Direct sprite slot 7, unchanged cache415 → 252Same 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.

NeedIncludePrimary calls/macrosRuntime closureDoes not imply
Shared world/camera/view types<web64/world.h>Web64WorldCamera, Web64WorldView, Web64WorldRect, WEB64_WORLD_PIXEL_TO_CELL, WEB64_WORLD_SUBPIXEL_TO_PIXEL/CELL/FINEHeader-only macros and typesStatic rendering, scrolling, mutation, collision, sprites
Video-mode setup<web64/world.h>web64_world_apply_video_modeWorld video helper onlyRenderer, scroller, other Game Runtime modules
Static native-map rendering<web64/world.h>web64_world_draw_char_view, web64_world_draw_block2_viewWorld render helper onlyScroller, collision policy, sprites
Screen-only rendering<web64/world.h>web64_world_draw_char_view_screen, web64_world_draw_block2_view_screen, WEB64_WORLD_COLOR_NONESpecialized render code with no color/material setup, reads, or writesColor 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 onlyPermission 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_screenSpecialized screen-only helpersColor 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/yWorld scroll helper onlyRendering, user input, motion, collision, IRQ installation
Buffered smooth-scrolling templatesgenerated src/world-scroll.asmasm_world_scroll_init, asm_world_scroll_stepExact project-local renderer plus explicitly called modulesVisible-screen shifts, in-loop Color RAM rewrites, framework-owned input/tick policy
Visible mutation<web64/world.h>web64_world_mutate_cellWorld mutation helper onlyCollectible/hazard/gameplay policy
Native asset wrappersproject tree.w64chr, .w64blk, .w64map, .w64sprEditable first-class asset files with deterministic generated outputsLegacy .chr, .blk, .map, .spr conversion loss

Game Runtime World-module template families:

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:

Game Runtime header printouts

HeaderSummaryPrintout
web64/actor-batch.hOpen 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.incAssembly ABI constants, exact structure offsets, flags, status values, and standard runtime prepare/call macros.raw
web64/actors.hCompile-time actor-pool storage macros plus activation and compaction helpers.raw
web64/actors.incRegistry-generated Actor-pool runtime prepare/call macros for native assembly.raw
web64/animation.hIndependent deterministic animation-bank playback state, sequence control, completion status, and step events.raw
web64/animation.incRegistry-generated Animation runtime prepare/call macros for native assembly.raw
web64/assets.hPublic Web64 Asset Model v1 descriptor types and constants for generated asset metadata.raw
web64/assets.incRegistry-generated Web64 Asset Model runtime prepare/call macros for native assembly.raw
web64/bitmap.hCaller-owned C64 hires and multicolor bitmap setup, logical-pixel drawing primitives, optimized line kernels, and bounded replace-only scanline flood fill.raw
web64/bitmap.incBitmap layouts, constants, and registry-generated native assembly prepare/call macros.raw
web64/collision.hIndependent material-map and AABB collision probes, swept contacts, interaction queues, and map mutation helpers.raw
web64/collision.incRegistry-generated Collision runtime prepare/call macros for native assembly.raw
web64/disk.hDependency-linked disk load/save, streaming file I/O, disk markers, and IDE-assisted disk swap requests.raw
web64/disk.incRegistry-generated disk and file-I/O runtime prepare/call macros for native assembly.raw
web64/fixed.h8.8 fixed-point, secondary 16.16 macros, angle8 trig helpers, and vector/motion declarations.raw
web64/fixed.incRegistry-generated fixed-point runtime prepare/call macros for native assembly.raw
web64/game-compose.hOpt-in composition macros for proven hot primitive combinations without introducing a framework update loop.raw
web64/game.hShared Game Runtime numeric contract, Q12.4 conversion macros, and compact point/delta/box structs.raw
web64/loader.hSynchronous hardware loading and transactional W64X installation with caller-owned RAM, IRQ and lifecycle.raw
web64/loader.incExact-width native ASM loader argument windows, request offsets and convenience macros.raw
web64/motion.hIndependent subpixel motion primitives for acceleration, braking, clamping, wrapping, gravity, and integration.raw
web64/motion.incRegistry-generated Motion runtime prepare/call macros for native assembly.raw
web64/runtime.incRegistry-generated _web64_rt entry and exact-width named argument-window reference for native and Kick-compatible assembly callers.raw
web64/sprite-mux.hCaller-owned PAL schedule storage, deterministic atomic submissions, double-buffer publication, explicit status, and application-chained IRQ service.raw
web64/sprite-mux.incRegistry-generated sprite-multiplexer prepare/call macros, including parameterless IRQ-service calls, for native assembly.raw
web64/sprite-runtime.hIndependent direct eight-sprite renderer with 9-bit X, dirty writes, camera projection, native overlay-asset pairs, and raw attachment helpers.raw
web64/sprite-runtime.incRegistry-generated direct-sprite runtime prepare/call macros for native assembly.raw
web64/trajectory.hCompact deterministic waypoint patterns, caller-owned Q12.4 execution state, exact scalar and synchronized-batch stepping, and transparent Motion/Actor projection.raw
web64/trajectory.incAssembly ABI constants, exact packed offsets, standard runtime prepare/call macros, compatible trajectory aliases, descriptor/storage emitters, and position-copy helpers.raw
web64/world.hIndependent Game Runtime World-module camera, viewport, native asset streaming, static rendering, fine-scroll, and visible mutation declarations.raw
web64/world.incRegistry-generated World runtime prepare/call macros for native assembly.raw