The first playable 2D profile connects tile painting to the normal world editor, publication, shared rooms and saved player state. It supports flat vector tiles, imported PNG sprites and looping sheet animation for tiles and travelers. This is a functional slice of roadmap 18; richer animation states, additional 2D collision tools and the final art pass remain open.
#Try it
Run npm run dev:editor and open the private editor URL printed by that command.
Choose New world → The little atlas, name the world, preview it and save.
Open Tilemap, choose a palette entry and click or drag over cells. You can
rename/recolor entries and toggle whether they block travelers. Preview and save
changes; Undo and Redo use the existing document history. Keep the arrival clear.
Use Map size & view to resize. The north-west corner stays fixed, existing cells retain their positions, and new ground uses the selected palette entry. Shrinking crops cells outside the new dimensions. Use Fill connected area to replace a connected patch of one color. + Color extends the palette.
+ Layer adds a transparent overlay above the ground. Select it to paint, rename it, change its order, or remove it. Erase clears overlay cells (on the ground it resets cells to palette entry zero). Hidden layers neither render nor block movement. Turning off Solid tiles block makes an overlay decorative; solid ground or another solid layer underneath still blocks travelers. Keep the arrival clear across all visible collision layers. Save/Undo retains the entire map, including layer order, palette and dimensions. Publish, open the invitation in two browser profiles, and enter the world. WASD moves across the map, Shift runs, and E collects the garden light. The pickup is shared; the collecting traveler's inventory survives reload.
#Sprite artwork
Select a palette entry, then expand Sprite artwork & animation. Import a PNG, set its equal-sized frame grid (columns and rows), frame count and playback rate. Frames run left to right, then down, and loop. Zero frames/second holds frame zero. The live preview uses the same frame selection as the player. Paint that palette entry on any layer; transparent overlay pixels reveal what is beneath them. Ground sprites retain the palette color beneath their transparent pixels.
Use this artwork for travelers applies the selected sprite to local and remote travelers. All travelers currently share that one sheet at 0.8 metres square, with their existing name labels. Removing the artwork restores vector rendering. Images and animation settings are saved in the world and its publications; other players do not need the original file. Save/Undo works through the normal map transaction. PNG input is capped at 8 MiB; decoded sheets are at most 512 × 512, up to 64 frames and 24 frames/second, with 262,144 pixels across the palette.
#Directional travelers
For an idle/walk character sheet, use exactly four rows in this order: down, left, right, up. Set Columns, Rows = 4 and Frames = Columns × 4 in the artwork settings. Enable Directional idle & walk. Choose the idle column, the first walking column, the number of walking frames and their playback rate. Columns start at zero. The direction/movement preview lets you inspect every row before saving. All four rows use the same column ranges.
The selected artwork applies to local and remote travelers. Movement chooses the facing row; stopping holds that direction's idle frame. Reduced motion holds the idle frame while retaining direction changes. Tile and free-object artwork keep their ordinary looping animation. Save and publish normally. Replacing the traveler image clears its directional setup so the new sheet can be configured.
#Objects in the overhead view
After importing artwork into the palette, choose + Place sprite in the sidebar. Give it a name and choose its artwork. Preview and save, then click the sprite in the scene or select it in the object list. Move and scale use the X/Z handles; rotation uses the Y ring. Arrow keys on a focused handle also adjust it. The transform fields support exact position, size and rotation values. Duplicate, delete, saved undo/redo and visibility use the existing object system.
Scroll to zoom, middle-drag to pan in either selection mode, and use Overview to fit the map. In transform mode, dragging empty space also pans. Frame selection centers and zooms to the selected object. Selection boxes, outlines, remote previews and handles now share the orthographic projection.
Free sprites reference their place's palette; recoloring the underlying palette color does not tint imported artwork. Their X/Z scale determines the displayed size and aspect. They can be decorative, interaction anchors, or carry a static 2D collision shape. Solid tiles and object shapes both block travelers. Flat rotation and a height above the tile layers are validated. Sprite art cannot be removed while a free object still references it.
#Solid object shapes
Select one object in a tile world and choose 2D collision…. Choose a rectangle, diamond, triangle, beveled rectangle, or custom convex polygon. The preview shows the local silhouette; position, Y rotation and X/Z scale place it in the world. Preview and save. No object collision removes the shape. Saved undo/redo, duplication and publication preserve it.
Custom vertices use X/Z coordinates from −0.5 to 0.5, with 3–16 vertices ordered around a strictly convex edge. A place supports 256 shapes. Shapes are static; hidden objects remain solid, and pickup-hidden objects cannot carry them. Spawn and live-revision checks reject shapes overlapping the local traveler. Use the ordinary transform tools to place or resize the solid silhouette.
#Contracts
World format 37 adds Place.tilemap with profile tilemap-topdown.1. Maps have
4–32 cells on each axis, 0.5–4 metre cells and up to 16 named palette colors.
Cells reference a palette index. Outside the map and solid palette cells block
movement. Presentation format 20 carries the map to the renderer, which generates
flat tile geometry. The overhead camera uses orthographic projection.
World format 38 and presentation format 21 add tilemap-topdown.2: up to four
named overlays with stable IDs and nullable cells. Earlier single-layer maps
remain valid. Layers render in array order above the ground. Visible tiles have
a combined 3,072-instance budget (solid tiles use two); overly dense maps reject
preview with an actionable error. Layer visibility is shared world state.
World format 39 and presentation format 22 add tilemap-topdown.3, normalized
RGBA sprite pixels and optional traveler artwork. The WebGPU renderer packs
sheets into one atlas and draws layers in order with alpha and depth handling.
Sprite frame selection uses the supplied environment time, with frame zero for
reduced motion. Collision remains tile-based and independent of sprite alpha.
World format 41 and presentation format 24 add tilemap-topdown.4 and saved
four-way.1 traveler animation settings. Facing follows each displayed traveler
(including interpolated peers); it is presentation state rather than inventory
or authoritative simulation state.
World format 42 adds SceneObject.collider2d (static-convex.1). Both physics
backends use the same continuous separating-axis sweep of the square motor
against transformed convex polygons, with sliding along contact normals. Shapes
are compiled from saved object geometry; exact checkpoints retain motor state.
World format 40 adds SceneObject.spriteTile; presentation format 23 resolves
that palette reference alongside the ordinary ECS transform and visibility.
The sprite renderer draws the resulting X/Z basis, preserving independent scale
and in-plane rotation. Free sprites and travelers sort with tile layers by height.
Both existing scene backends use the same swept axis-aligned 2D motor on X/Z, with a 0.48 metre square traveler at Y=0.8, acceleration 24, walking speed 2.8 and running speed 4.7 metres/second. Camera yaw, jumping and collapse do not change 2D movement. The existing lifecycle, publication, room, inventory and checkpoint machinery is reused. Tile edits are atomic authoring commands and live edits reject solid tiles overlapping the local traveler.
This profile accepts static decoration, pickups, dialogue and travel portals. It rejects 3D collision bodies, mechanisms, terrain, water and visual portal windows rather than silently treating them as 2D physics.
#Return to these items
- Finish the full 2D physics profile: dynamic bodies, impulses, rotation, joints, sensors and their ownership/persistence tools; add action animation states. All travelers currently share the selected artwork.
- Review directional transitions/diagonal movement, blocked walking, jitter and sparse peer samples. Facing starts down after reload, teleport, graphics recovery; it is not saved. Review configurable row order, animated idle clips, action clips and facing continuity. Current stop grace is 160 ms and walking follows displayed displacement.
- Review non-square sprite aspect/size controls, per-traveler variations, atlas memory/per-frame allocation, image provenance and large-image transport budgets. Qualify device-loss/live-image-replacement behavior and alpha overlap with 3D decorations; PNG import currently runs on the editor thread.
- Review free-object interactions, artwork rebinding UI, imported-model framing, object elevation extremes, selection on transparent pixels and alpha ordering for equal heights. Picking currently uses the object's rectangular bounds. 2D groups and dynamic bodies are still unavailable. Static polygon collision is authored explicitly rather than extracted from transparent artwork.
- Adapt player control hints, touch controls, preview orbit buttons and camera framing to the overhead mode. The garden-ferry test fixture also supplies an unrelated objective overlay; make hints/objectives appropriate to the world. Review mode changes and cross-mode travel.
- Review polygon budgets/allocation, corner stacks, tiny or highly stretched shapes, concurrent transforms, prefab capture, and occupied-object edits across peers. Circle/concave collision and dynamic response remain future work.
- Review occupied-cell edits across all peers, hostile saved positions, corner contacts and large-map budgets in the final qualification pass. Review touch painting/scrolling, cropped object/interaction positions, layer accessibility and concurrent edits (map changes currently conflict as one atomic unit).
- Qualify PostgreSQL restart/recovery, trusted routing, hardware/mobile rendering, accessibility and performance. Focused local results do not close those gates.
- Replace the provisional vector tiles/travelers with the required cohesive art pass. Existing 3D characters remain unapproved as well.
#Focused delivery check
Four native tests in tests/tilemap.test.ts pass: canonical authoring/schema and
presentation, swept bounds/sliding, and movement/pickup/exact continuation/live
painting in each physics backend. Existing compiler, presentation, simulation and
owned-simulation suites pass. TypeScript and package boundaries pass (243 files).
The packaged software-WebGPU journey in tests/browser/tilemap.spec.ts passes
painting, save, undo/redo, publication, two connected players, shared pickup and
inventory after reload. Editor, painter and shared-player screenshots were
visually reviewed. Initial runs exposed an old preview-envelope version and a
camera accessing world data before loading; both were corrected before the
passing run. Hardware/mobile and persistent-database qualification remain open.
#Layer and map tools delivery
Seven focused tilemap tests pass, including resize coordinate preservation, connected fill, transparent cells, draw ordering/budgets, and collision with exact restore/live hiding in both physics backends. Existing presentation, authoring merge and undo suites pass. All eight general authoring tests pass outside the sandbox; the sandbox run returned empty CLI subprocess output. TypeScript and package boundaries pass (244 files).
The expanded packaged two-player browser journey passes resize, connected fill, layer naming, painting/erasing, visibility, save/undo/redo, publication and shared pickup/reload. The layer editor, rendered map and player views were reviewed. No broader device/database qualification was repeated for this increment.
#Imported sprites delivery
Three focused native tests cover bounded pixels/frames, alpha preservation, ordered atlas instances, versioned publication identity and exact continuation in each physics backend. The seven tilemap tests and sixteen presentation tests also pass. TypeScript and package boundaries pass (247 files).
The packaged software-WebGPU journey imports a two-frame transparent PNG, previews its animation, applies it to tiles/travelers, publishes, joins with two players, renders the sprites, collects a shared item and restores inventory on reload. Import and player views were reviewed. An initial browser run overshot the pickup with a held movement key; the test now centers the traveler with bounded presses before interacting. This is not hardware or performance qualification. The fixture flowers demonstrate the pipeline, not approved art.
#Free sprite objects and overhead tools delivery
Two focused native checks pass for orthographic picking/dragging, flat handle axes, sprite identity/duplication/transforms, ECS visibility and exact checkpoint restoration. Existing handle, marquee, sprite and ECS presentation suites pass.
The browser smoke check caught viewport navigation being intercepted by transform handles. Wheel zoom and middle-button panning now also reach the viewport when started over a handle. Broader object interaction, input/device and rendering qualification remains in the review list above.
TypeScript and package boundaries pass (247 files). The expanded packaged software-WebGPU journey passes sprite placement, scene picking, saved move/rotate, wheel zoom, middle-button pan, publication, two connected players, sprite draws, shared pickup and inventory restoration after reload. Editor/player screenshots were reviewed. A subsequent test run exposed a camera-observation race after Overview; the test now waits for the displayed camera before deriving click coordinates. Hardware/mobile and wider regression checks remain deferred.
#Directional traveler delivery
Three focused native checks cover sheet bounds and frame selection, local/peer facing and stop behavior, atlas UV selection, versioned publication and exact checkpoint restoration. The existing sprite and free-object suites also pass. The browser smoke check caught inactive animation fields blocking form submission; those fields are now disabled until directional animation is enabled. Creating a free sprite also now preserves newer world versions. Slow-frame movement no longer discards facing just because the renderer had a half-second gap.
TypeScript/package checks pass (248 files). The native integration also feeds real simulation steps through the ECS presentation bridge into traveler animation and verifies moving/up-facing output before exact checkpoint restoration. The editor imports, previews, saves and publishes the directional sheet; its controls and up-facing preview were visually reviewed using a synthetic arrow sheet.
Shared browser qualification remains open. The expanded two-player check has
not passed for this increment: local animation observations stayed down/idle
while simulation movement advanced; subsequent software-WebGPU attempts stalled
in rendering/teardown or closed the browser during editor controls. The half-second
frame-gap reset was removed and sparse-frame native coverage added, but that does
not prove the browser symptom resolved. The test retains local/remote walking,
idle, pickup and reload assertions. Close the completed editor before shared play
to release its GPU resources. Revisit graphics-worker delivery/observations and
capture actual animated player frames in the final qualification pass; do not
count this as a passed multiplayer-animation gate. Logs used for this investigation
are /tmp/directional-browser3.log through /tmp/directional-browser6.log.
#Static 2D object collision delivery
Four new native checks cover convex validation, transformed geometry, swept collision and sliding, duplication/removal, and exact restoration/live revisions in both Rapier and owned scene adapters. All seven existing tilemap checks pass with the shared collision sweep. This delivers static object collision, not the complete dynamic 2D physics profile. The first browser checks caught a missing durable undo inverse and a compiler name rejected by the content manifest; both were corrected, with native inverse/publication coverage retained.
TypeScript/package checks pass (249 files), as do the existing durable undo tests. The packaged software-WebGPU browser journey authors a wall, saves and undoes/ redoes its shape, publishes it, connects two players, stops both at the same boundary, and restores the saved position after reload. The silhouette editor and shared-player views were visually reviewed. This focused pass does not resolve the separate directional-animation browser issue recorded above, nor qualify hardware/mobile, persistent database or adversarial shared edits.
#Pushable 2D boxes
Select a box in a tile world, open 2D collision…, choose Pushable box, preview and save. Keep every scale dimension between 0.2 and 4 metres. Publish and approach it, then use E / Interact to push. Contact movement can nudge it too; Interact is the reliable shared-play control. Sprite objects can use the same setting. Choosing a fixed shape or no collision removes the moving body. Duplication retains the planar body setting; ordinary undo/redo retains the edit.
World format 43 stores body.planar: true in the existing dynamic-box settings.
Both adapters use the same continuous planar sweep, retaining height and authored
orientation. Boxes slide, damp to rest, collide with tiles/static silhouettes,
travelers and other boxes, and transfer bounded contact momentum. Existing room
ownership, frame replication, canonical ECS transforms, portable saves and native
checkpoints retain their motion. Planar state admission rejects height changes,
vertical velocity, spin and changed orientation. The existing 32-body world limit
applies. This is a translating-box increment, not the completed 2D physics profile.
Focused delivery checks: three new native checks pass, covering publication,
invalid geometry/settings, high-speed boundary sweeps, offline nudges, exact
checkpoint continuation, portable saves, room pushes/forks and shared-frame
application in both backends. Static-collision, tilemap, buoyancy-simulation and
durable-undo suites pass. Type/import checks pass (251 files). The packaged
software-WebGPU journey passes editor save/undo/redo, publication, two-player
push/settling and identical retained positions after reload. Editor and shared
player screenshots were visually reviewed (test-results/planar-body-*.png).
Return for review and remaining implementation:
- Rotating bodies, angular impulses, dynamic convex/circle shapes, joints and sensors remain unfinished parts of the 2D profile. Current boxes keep their authored angle; 3D mechanisms cannot be attached to planar bodies.
- Shared continuous walk-to-push needs further work: the player motor reports zero velocity when blocked, so a nudge can stop. Use Interact for repeated shared pushes. Qualify opposing travelers, body piles and simultaneous pushes.
- Sweep iterations and stable body ordering prioritize bounded, nonpenetrating motion; qualify momentum/energy behavior in box chains and tight corners.
- Cache/broad-phase tile geometry before qualifying maximum 32×32 maps with 32 bodies. Review allocations, frame budgets, restored untrusted poses, live occupied revisions, duplicate placement and prefab authoring.
- Qualify Postgres/room-process restart, trusted deployment, host handoff and mobile/hardware graphics. This increment's browser reload and native room fork do not substitute for those checks.
- Retain the directional-animation browser issue above and the final character, environment and arrival art pass. The neutral box and current map presentation are functional placeholders, not approved final artwork.
#Pressure plates and responses
Create a flat, non-solid object in a tile world and choose 2D pressure plate…. Enable it, choose any movable box or one specific box, choose the object and color for its response, and optionally select pickups, conversations or gateways to unlock while occupied. Save and publish. Moving the box off the plate restores the starting color and closes the gate again; already collected pickups stay collected. Multiple plates assigned to one interaction must all be occupied.
Format 44 stores sensor2d with a versioned profile, a unique condition name,
an optional body identity and up to eight gated interactions. The plate uses its
object's rotated X/Z rectangle. It is non-solid and detects positive overlapping
area, including a box that only partially covers it. Up to 16 plates are allowed.
The appearance response uses the existing compiled material/condition path.
The plate and response edit form one reversible authoring transaction.
Occupancy is derived from body positions rather than saved as a separate switch. Local saves/checkpoints retain it through those positions. Published clients use the room's body stream; interaction admission checks the corresponding frame. The development relay rechecks accepted gated actions before committing, and the persistent ledger checks its admitted body frame for actions and travel.
Review items for the final pass:
- General sensor shapes, traveler detection, enter/exit script callbacks, latching switches and automatic door movement remain unfinished. This increment supplies box pressure plates, color responses and conditional interaction access.
- Qualify rapid enter/exit, late or reordered frames, simultaneous use at the boundary, live edits/removal, and trusted/Postgres restart and travel. Clients can briefly display different occupancy during normal body interpolation; admission uses the room frame rather than trusting that display.
- Sprite artwork does not use material tint, so the response picker currently offers objects without sprite artwork. Plate duplication/prefab capture and response ownership across multiple plates need richer authoring support.
- Preserve the previously listed dynamic-body, directional-animation and final character/environment/arrival artwork work. These are still unfinished.
Pressure-plate delivery record: three focused native checks pass for atomic
save/undo, invalid references, entry/exit, material changes, interaction admission,
portable saves and exact checkpoints in both backends. Type/import checks pass
(253 files). The final packaged two-player browser check passes authoring,
undo/redo, publication, activation on both clients and occupied reload; the editor
and active shared plate were visually reviewed. Twenty of 21 selected existing
checks pass. The Rapier variant of tests/floating-room.test.ts times out waiting
for an accepted push receipt, including one isolated retry; its owned variant
and live-addition restart check pass. The cause is not established and remains a
final-qualification item, not a passed persistence gate. Logs:
/tmp/sensor-regression.log, /tmp/sensor-room-retry.log,
/tmp/sensor-browser-final.log. No broader diagnostic campaign was run.
#Rotating silhouettes and pin joints
Open 2D collision… and choose Rotating silhouette, Sliding silhouette
or Pinned silhouette. Choose a rectangle, diamond, triangle, beveled rectangle
or custom convex outline. Rotating bodies spin when pushed off-centre; sliding
silhouettes retain their angle. A pinned body rotates around an authored world
anchor. Pin X/Z use the object's local −0.5 to 0.5 footprint: (0, 0) pins the
centre and (-0.5, 0) pins the left edge. Save, publish and push with E from
one side. Collision outlines do not replace artwork; use a matching sprite or
model for the visible silhouette.
World format 45 adds body.planar profile rigid-planar.1, carrying 3–16 convex
points, free/locked rotation and an optional pin. The older planar: true box
profile remains supported. The pure planar solver carries X/Z velocity and Y
angular velocity through the existing native state tables, ECS projection,
shared-room frames, portable saves and exact checkpoints. Off-centre interaction
impulses are calculated from the admitted actor position and nearest silhouette
edge; clients do not submit torque. Pins keep their original world position.
Pressure plates and player collision now use the body's current rotated outline.
Changing shape or pin policy resets that body's authored pose on revision.
Nine focused native checks pass: versioned publication and shape-policy rejection, free and pinned motion in both adapters, anchor retention, exact checkpoint continuation, portable save restoration, room authority fork/continuation, a spinning body's thin-wall collision, and adding nonoverlapping convex neighbours whose rectangular native storage proxies overlap. The latter caught and fixed live revision admission incorrectly using those proxies instead of planar shapes. Existing planar-box, pressure-plate and static-collision suites pass. Type/import checks pass (256 files). The packaged two-player journey passes pinned-body creation, save/undo/redo, publication, matching shared rotation and reload; editor controls and the rotated player view were visually reviewed.
Return for review and remaining implementation:
- Pins currently attach to the world. Body-to-body joints, joint motors/limits, analytic circles, concave/compound outlines and richer joint authoring remain unfinished. General sensor/script events remain on the same 2D milestone.
- Translation uses continuous sweeps; rotation uses bounded substeps and contact bisection. Qualify extreme spin, tiny features, body piles, pinned-body contact chains, simultaneous travelers and maximum-budget maps. Do not infer full rotational CCD or physical energy conservation from the focused thin-wall test.
- Inertia uses the polygon's moment around its authored origin. Review off-centre mass properties, contact manifolds, settling and friction against the full physics fixtures before final qualification. Broad-phase caching/allocation work remains recorded above.
- Rapier may renormalize a quaternion slightly when loading a portable save; tested components stay within 1e-6 while other body state is retained exactly. Native checkpoint continuation remains exact. Qualify pinned interpolation, persistent/trusted deployments and live occupied revisions more broadly.
- The earlier Rapier room-push receipt timeout, directional-animation browser issue and final character/environment/arrival artwork pass remain open.
#Body-to-body 2D joints
Select a movable body in a tile world and open 2D joints…. Choose another body and a Distance link to preserve the current centre-to-centre span, or a Hinge for adjacent parts that share a pivot. Fit to current arrangement sets centre anchors and distance, or a shared midpoint for a hinge. Hinge anchors must lie inside both objects; move the objects together before fitting if needed. Preview, save and publish as usual. Both players see the same linked motion after a push with Interact. Select Unlinked to detach a part before independently moving or deleting its neighbour. Copying a whole selected assembly remaps its internal links; copying only one part detaches that copy.
Joints use world format 46 / rigid-planar.2. Anchors are normalized local X/Z
coordinates, bounded to −0.5…0.5; distance spans are 0.05…10 metres. One outgoing
link per body and an acyclic graph keep this first profile bounded. A source
cannot also have a world pin, but its target may be pinned. Directly connected
neighbours do not collide with each other. Shape editing preserves a body link;
choosing a world pin replaces it. Existing body snapshots and room frames retain
all motion state, and geometry revisions reset the connected assembly.
Focused acceptance (2026-10-26): six native checks pass for publication, endpoint
validation, assembly/individual copies, both backend hinge/distance motion,
anchor accuracy, exact checkpoint continuation, portable reload and authority
fork continuation. Existing rigid-planar, pushable-body, sensor and static-shape
suites pass. The software-WebGPU two-player browser journey passes authoring,
save, undo/redo, publish, connected push, matching resting frames and reload
(34.2 s test / 38.7 s total). Type/import checks pass. Editor and shared-player
screenshots were visually reviewed in test-results/planar-link-{editor,shared}.png.
Deferred review: long chains, mass ratios, wall wedging, worst-case budgets, rotational CCD, energy drift and hardware/production deployment qualification. Projection prioritizes avoiding walls over correcting every millimetre of joint error, so blocked assemblies may stretch. Breakable or closed-loop joints are not implemented in this 2D profile. Add visible joint/anchor markers and optional connecting artwork, a hinge-specific browser journey, assembly transform assistance and prefab import/export coverage in the later pass. Distance links are physical constraints, not automatically drawn rods. Keep the earlier directional-animation browser issue and Rapier push-receipt failure open; neither was requalified here. The required final character, environment and arrival art review is still unfinished.
#Powered 2D hinges
In 2D joints…, select Hinge, fit the anchors and enable Turn this hinge automatically. Set the relative rotation speed in radians per second (negative reverses direction) and maximum torque, then preview, save and publish. The motor drives the two connected bodies; pin the other body to the world for a fixed base. The same authored motor runs in solo and room authority, and motor settings are part of the saved world. World format 61 distinguishes these worlds from older engines that cannot read the motor. Existing unpowered joints retain their earlier format and behavior.
Focused checks cover publishing and world-format admission, motion on both
physics backends, deterministic checkpoint continuation and a room authority
fork. The editor controls were visually reviewed. On October 27, the complete
tests/browser/planar-motor.spec.ts journey passed on the physical Intel xe-3lpg
adapter in one Chromium process: save, undo/redo, publication, both travelers,
shared motion and second-player reload. The shared view
was visually reviewed. Software Chromium still stalls during second-player
adapter startup; that qualification issue remains open in render placement. Active
motors now keep their connected bodies awake, preserving slow rotation. The
fitted-anchor editor also rounds floating-point noise
at the permitted boundary. Review long-running, obstructed and high-load mechanisms, live edits,
hosted persistence and device performance during final qualification. Breakable
joints and closed loops remain unimplemented.
#2D hinge travel limits
For a hinge, enable Limit travel from the starting angle and set lower and upper angles in degrees. Zero is the authored starting pose; the lower angle must be nonpositive and the upper angle nonnegative. Limits also work with a powered hinge, allowing a rotating mechanism to stop at its chosen end. Save and publish as usual. Limit-enabled worlds use format 62; unbounded hinges keep their earlier formats. Hinge motion is shared through the existing room owner.
Focused checks exercise both stops on both physics backends, world-format admission, checkpoint continuation and room-authority fork continuation. A software-WebGPU browser run authored, saved, published and entered a world with a powered, limited hinge; its controls were visually reviewed. Broader review still includes unpowered impacts, wall-obstructed mechanisms, high forces, long-running simulation and hosted/multiplayer visual qualification. The second-browser graphics startup issue documented above remains open.
#Player-controlled 2D motors
For a powered hinge, check Let players switch the motor on and off, save and publish. It starts on; approach the powered part and use E (or Interact) to switch it off or back on. The mechanism coasts when switched off. A room owner commits the switch state with the body, and solo saves and checkpoints retain it. World format 63 identifies switchable motors; existing automatic motors do not change behavior.
Focused checks exercise switching and checkpoint restoration in room authority on both physics backends, plus solo checkpoint and portable-save restoration. A software-WebGPU browser journey authored and published a switch, entered the room, displayed the interaction and switched the motor off; both editor and player views were visually reviewed. Two-player rendered observation remains unverified because of the second-browser graphics startup issue above. Review simultaneous interactions, hosted process restart and live revisions during qualification.
#The turning garden
In the editor choose New world → The turning garden, name it, then save and publish. The new world includes a golden reversible gate, a path and a garden light to collect. Approach the gate and press E to reverse its motor. Its pivot, gate, tilemap and colors remain editable. Creating a template remaps the planar link to the new pivot identity along with the objects themselves.
Focused checks cover template creation, identity remapping, motor switching and room checkpoint restoration on both physics backends. A software-WebGPU browser test created, published and entered the world, then switched its motor off; the template and player views were visually reviewed. The garden uses provisional geometric art; the final character and environment art pass remains open. The two-player software-renderer startup issue above, hardware review and hosted restart remain to qualify.
#Reversible 2D motors
In 2D joints…, enable the motor and player control, then choose Reverse direction. Interact changes the motor direction rather than switching it off; with travel limits the mechanism can return from either end. Existing switchable motors remain on/off. Reversible worlds use format 64, and the direction is retained by the same room checkpoint and solo-save state as a motor switch.
Focused room tests drove the turning-garden gate to each stop, restored the room while reversing, and drove it forward again on both physics backends. Browser checks created and operated the turning-garden gate, and authored and operated a separate reversible hinge; the editor control was visually reviewed. Review simultaneous player interaction, hosted process restart, high-load mechanisms and the two-player rendered journey in the final qualification pass.
#Pressure-controlled 2D motors
Create a pressure area with 2D sensors…, then select a powered hinge in 2D joints…, enable motor control and choose Follow a pressure area. Choose the area and save. While the area's configured travelers or bodies occupy it, the motor turns in its authored direction; when empty, it reverses. Travel limits make it return between two stops. The room derives occupancy from the admitted body and traveler poses and publishes the resulting motor state. World format 65 identifies this behavior; copying a world remaps the area link.
For a ready-to-play example, choose New world → The garden threshold, save and publish. Step onto the rose stone to turn the gate; step away for its return. Focused checks cover traveler and body activation, both physics backends, room checkpoint restoration and missing-area rejection. A browser journey created, published and operated the example, and reviewed the editor selection and player view. A second journey used separate software Chromium processes: one traveler entered and left the pressure area while the other observed the gate turn and return. The shared view was visually reviewed. Its geometric art remains provisional. Same-browser-process graphics startup, hosted process restart, rapid entry/exit, complex assemblies and hardware/device qualification remain open.
#Scripted 2D sensor responses
Create a static, nonsolid object in a tile world, open Behavior…, and choose 2D sensor response. Its starting script lights the object while at least one connected plate is occupied and counts occupancy changes. Save it, then open a plate's 2D pressure plate… settings and select that object under Run these sensor responses. No direct color response lets the script own the finish; a plate may still gate actions or color a different object. Save and publish, then push a moving body onto the plate with Interact. All relay-room travelers see the script's resulting finish, including after rejoining.
World format 47 / planar-sensor.2 adds up to eight response targets per plate,
within the existing 16-plate/16-behavior budgets. Targets must be sensor scripts
in the same place. The pinned engine.sensor-script@1 adapter accepts exactly
one onEvent hook. Each response receives one aggregated occupancy-change event:
type: "sensor2d", occupied: boolean, and active, entered, exited arrays
of plate flags. An entering body activates a plate; exchanging bodies while it
remains occupied does not emit another edge. Scripts keep lit and count and
may select their own active/inactive material. They do not receive arbitrary
JavaScript execution or structural world-write capabilities.
The engine owns the occupancy cursor and commits it in the same behavior transaction as the response. A failed response rolls back cursor, state and appearance; three failed attempts park it. Native checkpoints retain the cursor. The relay persists body motion, private script state/cursor and public appearance in one snapshot before broadcasting; reconnecting does not replay a successful entry. Removing a connected plate produces an exit on the next update. Unlink a response from its plates before deleting its behavior. Lightweight solo player saves still reset behavior state, as documented for other custom responses.
Focused acceptance (2026-10-26): five native checks pass for publication/undo,
invalid targets, body entry/exit on both physics backends, exact checkpoint
continuation, relay cursor deduplication/revision and failed-script rollback.
The existing script/object/simulation/room-behavior and pressure-plate suites pass
26 checks. Type/import checks pass. The software-WebGPU two-player author →
connect → save/undo/redo → publish → push → shared response → reload test passes
(54.4 s test / 58.8 s total). Editor/script/player screenshots in
test-results/sensor-events-*.png were visually reviewed.
Remaining implementation: traveler detection, general sensor silhouettes, per-body contact identities, swept transient contacts, broader script effects and persistent/trusted-host behavior execution. This increment runs in solo simulations and the file-backed shared relay; it does not add script execution to the PostgreSQL persistent service. Remaining qualification: full relay-process restart of sensor worlds, rapid transitions, simultaneous plate edges, maximum budgets, hardware and deployment checks. Review the behavior panel's touch-centric helper copy and sensor-specific labels in the polish pass. Keep the earlier animation/push-receipt issues and required final art pass open.
#Traveler-aware shaped sensors
Open 2D sensors… on a static, nonsolid tile-world object. Detect chooses moving bodies, travelers, or either; a body filter remains available for the body-containing modes. Choose Rectangle, Diamond, Triangle, Round (16 sides) or Custom convex polygon. The preview shows the local footprint, and its X/Z scale and Y rotation follow the object. A traveler sensor needs no movable bodies in the scene. Connect scripts, color changes or gated actions as with pressure plates.
These settings use world format 48 / planar-sensor.3. Custom shapes contain
3–16 strictly convex normalized vertices. Round is explicitly a polygonal
approximation, not an analytic circle. Traveler overlap uses the same 0.48-metre
square footprint as the tile movement controller. Travelers in another place
cannot activate the area. Body filters do not exclude travelers in Either mode.
Entry/exit remains aggregated occupancy: the last matching occupant leaving
produces the exit, and a disconnected traveler stops activating the relay sensor.
Solo simulations evaluate the local traveler. Shared relay scripts evaluate admitted room poses; local color/flag presentation uses the local traveler and admitted remote actors. Action reducers and the relay recheck current occupancy; persistent action/travel admission receives the available admitted pose context. The PostgreSQL service's script execution gap remains open; this change does not claim to close it. Network delay and interest changes can briefly separate local color prediction from the relay's authoritative scripted finish.
The walking browser check exposed a wire bug in the preceding sensor-event
increment: the relay emitted system.sensor.<revision> commits but the client
accepted only coordinator item-return commits. The client now accepts the exact
sensor commit identity only for sensor-capable worlds and retains the other
strict checks. Both sensor browser journeys now fail on rejected room messages,
so reconnecting to a correct baseline cannot mask this problem.
Focused native acceptance: six checks pass for authoring/undo/publication,
malformed shapes, convex corner/place filtering, walking entry/exit and exact
checkpoint continuation on both physics backends, peer action gating/removal,
relay multi-occupancy and strict sensor packet admission. Existing sensor, sensor
script and behavior-script suites pass. The remote-actor suite has seven passing
checks and one existing stale assertion at tests/remote-actors.test.ts:86, which
expects schema version 4 while the current component is version 6. Record that
migration-fixture update for final qualification; it is not a passed suite.
Focused browser review (2026-10-26): the body-triggered two-player journey passes
(49.3 s), including reload and an assertion that no room messages were rejected.
The traveler journey passes authoring, undo/redo, publication and walking into
the shaped area, with both clients observing the scripted finish and the remote
client observing the sensor flag. The browser then closes during the shared-view
screenshot (41.0 s); its cause is not established. Traveler reload, exit and
disconnect browser assertions therefore remain unverified, and the test remains
enabled. Retain test-results/traveler-sensors-*/trace.zip and
/tmp/traveler-sensors-browser-final.log for review. The editor screenshot was
visually reviewed at 1440×900; shared-view visual review is still outstanding.
Type/import/package checks pass (257 source files). This is an early-testing
increment, not a fully qualified browser pass.
Remaining review: analytic circles/capsules and compound body shapes, swept transient contacts, per-occupant events, narrow/mobile sensor-panel layouts, in-world shape outlines, rapid join/travel/interest transitions, maximal scenes, PostgreSQL/trusted execution and hardware qualification. The earlier final art, directional-animation and push-receipt review items remain open.
#Compound 2D bodies
Open 2D collision…, choose Rotating, Sliding or Pinned silhouette, then select
L · elbow, T · crossbar, U · open cradle or Custom solid parts.
The preview and the published player render the separate solids. Custom rows use
X, Z, width, depth in the object's normalized coordinates. Use 2–8 rectangles,
size 0.05–1, wholly inside −0.5…0.5; edges may touch, but interiors cannot overlap.
Object X/Z scale and rotation apply to all parts. Parts move as one body, and
existing pins and body-to-body links remain available. Copying a single linked
body removes the link while retaining its compound shape.
World format 49 / rigid-planar.3 retains the old convex profile's envelope
points for compatibility with editing tools, but physical queries use the solid
parts. Traveler movement, spawn validation, moving-body contacts, interaction
reach and body-triggered sensors all retain gaps. Mass uses occupied volume;
rotational inertia sums part moments about the authored origin. This follows the
existing origin-based planar rotation model: automatic center-of-mass recentering
for asymmetric shapes is still a physics review item. The native Rapier box is
storage only for this planar profile, with mass adjusted to the occupied volume;
the shared pure planar solver handles contacts on both backends.
Focused native acceptance (2026-10-26): five checks pass for publication and copy, invalid parts/profile rejection, gap clearance for travelers and other bodies, no sensor activation through a hole, motion and exact checkpoint continuation on Rapier and owned backends, local save recovery, same-world revision recovery and room authority continuation. The browser exposed missing compound schema registration during room recovery; revision snapshots now retain that schema. The existing planar-body, rigid-planar, planar-link and sensor2d suites pass, as do five authored 3D-compound checks. Type/import/package checks pass (257 files).
The software-WebGPU author → save/undo/redo → publish → two players → push →
shared pose → reload journey passes (30.5 s test / 34.8 s total), with no rejected
room updates or cargo recovery errors. Editor and shared-player screenshots
(test-results/compound-planar-{editor,shared}.png) were visually reviewed.
The player visibly retains the U-shaped opening after rotation. The first review
also caught and fixed custom-part field visibility/styling in the dialog.
Remaining implementation/review: analytic circles and capsules, arbitrary convex compound parts, automatic mass-center offsets, rotated individual parts, dense contact/energy and maximum-part performance qualification, mobile custom-part editing, compound/joint combinations in the browser, live revision/prefab journeys, process restart and hosted deployment. Preserve all earlier review items and the required final character/environment/arrival art pass.
#Analytic circles and capsules
Open 2D collision…, choose Rotating, Sliding or Pinned silhouette, then Circle · smooth contact or Capsule · rounded ends. A circle fits the shorter X/Z dimension. A capsule uses that dimension as its diameter and extends along the longer axis; equal dimensions produce a circle. Object rotation turns the capsule. The editor preview uses normalized object space; the published player shows the shape with its actual dimensions. Existing pins and connections remain available. Round shapes are independent bodies in this increment, not compound parts or analytic sensor areas.
World format 50 / rigid-planar.4 stores the round kind. Collision uses a point or
segment expanded by an exact circular radius: it does not use the visible mesh's
facets. Traveler clearance, sensors, body contacts and bounded conservative
translation sweeps use that support geometry. Bounds derive from the round shape,
independently of the legacy polygon field. Mass uses the occupied area times
height and density; inertia uses circle/capsule area moments. Contact normals on
circles act through their center. Rendering uses cylinder primitives and a central
box for a capsule, so the visual edge retains the renderer's finite tessellation.
PlanarRoundShape is authored presentation state and survives room revision
recovery and checkpoints.
Focused acceptance (2026-10-26): nine native checks pass, covering exact arc
clearance between polygon vertices, circle/capsule contacts, true-radius sweeps,
normal contact torque, thin-wall high-speed motion, publication and profile
validation, occupied-volume mass, same-world revision, exact checkpoint/local
save recovery on both backends, and room authority continuation. Six existing
planar/compound/sensor suites pass. The software-WebGPU author → save/undo/redo →
publish → two players → push → shared pose → reload journey passes (32.1 s /
36.5 s total), with no rejected room messages. Editor and shared-player views were
reviewed in test-results/round-planar-{editor,shared}.png. Subsequent contact-point
and analytic-bound corrections are covered by the focused native checks; the
browser journey preceded those two corrections. Final type/import/package checks
pass (259 source files).
Remaining review: maximal rounded-body scenes, multi-contact stacks and grazing contacts, full rotational CCD, energy/friction comparison, browser pin/joint and live editing coverage, mobile controls, high-DPI visual seams at capsule joins, hardware and hosted deployment. Conservative advancement has a 40-iteration budget and may stop conservatively in difficult grazing cases. Compound convex and round parts, analytic sensor areas and the final art pass remain open.
#Mixed shaped compounds
In 2D collision… → Rotating / Sliding / Pinned silhouette, choose Rounded handle · mixed parts, Garden trowel · convex head, or Custom shaped parts. A body can contain 2–8 boxes, circles, capsules and convex polygons. Each part has its own position, size and angle. The preview uses the same part definitions as collision and rendering; copying, publishing and saving keep all parts together. Existing body links and world pins remain available.
The custom field is a JSON array of {kind, position, size, angle} objects;
convex parts also have points containing 3–16 normalized X/Z vertices. Positions
use −0.5…0.5, sizes use 0.05…1, and editor angles use degrees (−180…180). Vertices
are relative to their individual part. The saved angle uses radians. Parts must
fit inside the body after rotation and may touch without overlapping. Resize or
reposition parts when the preview reports an overlap or boundary error. Material
finishes apply to the whole body; sprite-tile artwork is not supported on these
shaped compounds.
World format 51 / rigid-planar.5 stores pieces. Part rotation takes place in
physical object space after scaling its dimensions, preserving circles under
nonuniform parent scales. Circle/capsule parts retain analytic collision support;
convex parts retain their full outline. Mass sums occupied volume, and inertia
sums moments about the authored origin. Automatic center-of-mass recentering
remains open. PlanarPiecesShape preserves authored presentation state across
room revisions and checkpoints. Convex rendering triangulates the exact outline
into extruded prisms; presentation format 25 admits the internal prism mesh and
older wire formats reject it. Ill-conditioned triangles and the shaped-part draw
budget are checked before publication; combined imported-model/tile budgets still
need qualification.
Focused native acceptance (2026-10-26): seven checks pass for publication/copy,
profile/overlap/bounds rejection, nonuniform scale and rotated round-part
render/collision agreement, empty-space traveler/sensor queries, positive convex
render transforms and wire compatibility, both physics backends' motion/revision/
checkpoint/local-save continuation, and shared room authority continuation.
Type/import/package checks pass (261 files). Five existing round/compound/joint/
sensor/presentation suites pass. The software-WebGPU author → save/undo/redo →
publish → two players → shared push → reload journey passes (33.6 s / 38.0 s total)
without rejected room updates. Editor and shared-player screenshots in
test-results/planar-pieces-{editor,shared}.png were visually reviewed.
Remaining review: a direct-manipulation part editor instead of JSON, mobile field layout, per-part artwork/materials, convex seam/shadow quality at high zoom, compound pin/joint and live editing browser journeys, mass-center offsets, maximal geometry/performance, multi-contact/rotational qualification and hosted restart. Analytic sensor areas, broader sensor-script effects, persistent/trusted script execution and the required final art pass remain unfinished.
#Analytic sensor areas
Open an object's 2D sensor… dialog and choose Circle · analytic or Capsule · analytic under Area shape. Choose travelers, moving bodies or either, then select a color response, sensor script or action to unlock. Circle uses the shorter X/Z dimension as its diameter; Capsule extends along the longer axis. Object yaw rotates the area. The editor previews the trigger boundary; the object's visible mesh remains independently authored. Existing Round · 16 sides continues to mean a polygon.
World format 52 / planar-sensor.4 stores the round kind and detection mode.
Circle/capsule sensors reuse exact-radius support geometry, including against
rounded and mixed compound bodies. Existing admitted traveler poses, shared
occupancy aggregation, scripts and action gates consume the same sensor shape.
Script events still represent aggregate entry/exit, not each occupant separately.
Focused acceptance (2026-10-26): eight native checks pass for profile/publication/
undo validation, exact curved boundaries beyond the old 16-gon, rotated capsule
contacts, circle and capsule entry/exit/checkpoint continuation on both backends,
peer action gates/removal, and relay multi-occupant deduplication. Type/import/
package checks pass (261 source files); five existing sensor/round-body/mixed-part
suites pass. The software-WebGPU author → save/undo/
redo → publish → two players → enter → reload → leave → reenter → disconnect
journey passes (33.9 s / 38.2 s total), without rejected room or cargo messages.
Editor and shared-player views in test-results/round-sensors-{editor,shared}.png
were visually reviewed. This capsule journey does not retroactively close the
older convex traveler-sensor browser interruption.
Deferred review: narrow/mobile layout and shape-preview aspect presentation, maximum sensor/body scene performance, broader live editing and process-restart journeys, hardware and hosted deployment. Broader script effects and authored behavior execution on persistent/trusted hosts remain implementation work. Preserve earlier review items and the required final character/environment/arrival art pass; current character art remains unapproved.
#Sensor puzzle responses
In Behavior… → 2D sensor response, select the pickups, conversations, inspect actions or gateways under Unlock while this response is active. Choose a starting recipe and click Use recipe: remain active while occupied, stay active after the first entry, or stay active after three entries. The generated source remains editable. Save the response and connect it from an area's 2D sensor… → Run these sensor responses field.
A response's active finish unlocks its selected actions. Every response attached to an action must be active. Direct sensor locks and ordinary item/flag requirements still apply as additional conditions. For a remembered puzzle, select the action on the response and leave the area's direct Unlock while occupied selection empty. A new entry means at least one connected area became occupied; additional travelers entering an already occupied area do not count. A latched response can remain active after every traveler leaves.
World format 53 pins this author-selected capability. Up to eight distinct actions in the response's place are allowed. Scripts cannot choose arbitrary action identities. Gameplay admission derives from the accepted public material result, so appearance, private state, entry cursor and shared unlocks commit together. Missing response views keep actions locked. Local interactions, shared reducers, relay acceptance and persistent travel admission all check the same condition. The relay retains its existing fence against browser-authored behavior views.
Focused native acceptance (2026-10-26): six checks pass for publication/undo,
invalid and legacy-format target rejection, both physics backends' latched
unlock after exit and checkpoint recovery, three-entry relay snapshot restoration,
shared collection admission, multiple required responses, occupied relocking,
unchanged-behavior revision retention and failure rollback. Type/import/package checks and
five existing sensor/object-behavior/script suites pass. The software-WebGPU
journey passes authoring, save/undo/redo, publication, two-player entry, exit,
disconnect, unlocked collection and reload (37.6 s / 41.9 s total), without
rejected room/cargo messages. Editor and collected-player screenshots in
test-results/sensor-unlocks-{script,collected}.png were visually reviewed.
Remaining implementation/review: PostgreSQL/trusted hosts still need authored behavior execution; their gated actions remain locked without accepted response views. Portable solo saves do not yet retain private script progress (native checkpoints and relay snapshots do). Review mobile recipe editing, resetting a completed puzzle, complex multi-area recipes, browser gateway/dialogue journeys, actual relay process restart, live target edits and hosted/hardware qualification. The required final character/environment/arrival art pass remains open.
#Portable solo behavior progress
Ordinary solo saves now retain authored object responses: puzzle counters, latched unlocks, current finish, previous sensor occupancy, random state and fault/parking status. No extra save action is required. Reloading while inside an area does not count a second entry. This applies to installed touch-toggle, custom material and sensor responses; custom host-supplied programs still need their native checkpoint path.
Player-save format 6 binds progress to the compiled world hash and stores only five allowed components per authored behavior. Restoration checks the binding, configuration, material selection, cursor and runtime component contracts before committing the rows atomically. World/entity/geometry components cannot enter through behavior progress. Moving-body state, route phases and cargo membership remain in the same save. Shared replicas do not export private room behavior state into this portable format. Older saves remain readable and initialize behaviors at their defaults because they never contained that progress.
Focused native acceptance (2026-10-26): seven checks pass for three-entry puzzle
continuation on both physics backends, no duplicate occupied entry, invalid/
injected state and wrong-world rejection, atomic rollback, parked-script
retention, legacy defaults, shared-replica exclusion, streamed body/membership
coexistence, and random-state continuation. Four existing sensor-unlock,
object-behavior, cargo-streaming and round-body suites pass. Type/import/package
checks pass (262 source files). The software-WebGPU browser journey completes
three visits across separate reloads, unlocks and collects the reward, then
reloads with that reward retained (41.5 s / 45.9 s total). The restored player
view in test-results/behavior-saves-restored.png was visually reviewed.
Remaining review: maximum-size save/worker-frame cost, storage quota failures,
browser development-revision recovery, multi-place/ragdoll/route combinations and
hardware/mobile qualification. PostgreSQL and trusted-host authored behavior
execution remains the next implementation task. It must also close the alternate
durable pickup-command admission path, which currently omits sensor/response
locks; do not treat the existing travel and act checks as covering that path.
The required final character/environment/arrival art pass remains open.
#Hosted behavior execution
PostgreSQL cooperative and trusted rooms now execute installed authored responses,
including remembered sensor puzzles. Use an exported world with
DW_WORLD_DOCUMENT, a new room ID and a fresh schema-9 database as described in
PERSISTENT_ROOMS.md.
Ordinary solo saves and the local relay retain their existing completed paths.
Room creation initializes private behavior snapshots and public views together; restart rejects disagreement. Body simulation saves include sensor evaluation in the same SQL transaction. Sensor-only worlds evaluate admitted traveler poses on the owner's queue. Every changed cursor, script fault or output advances the room sequence and writes a bounded sensor outbox event. No-op occupancy consumes no sequence. Touch responses use ordinary idempotent action receipts. Release upgrades retain compatible private state; source/configuration changes use the existing binding rules. Backup table manifests include the new durable event stream. Trusted motor replicas consume public behavior views without executing private scripts during prediction.
Focused acceptance (2026-10-26): five PostgreSQL checks pass for rollback, expired owner fencing, occupancy deduplication, both pickup paths, ordered outbox acknowledgement, touch idempotency, sensor fault parking, cooperative/trusted shared entry and restart, atomic body/output saves and release-upgrade retention. The existing backup suite (two checks) and upgrade suite (five checks) pass. Six of eight trusted-room regression checks pass; slow inventory commitment and private-award isolation were blocked at admission by the combined test process's 512 MiB RSS limit (observed 544219136 bytes at the first failure). Those two checks remain qualification items; their behavior was not exercised in that run. Type/import/package checks pass (262 source files).
The packaged trusted two-player software-WebGPU journey passes locked collection,
entry/exit, host process stop/start, retained unlock, shared collection and browser
reload (21.1 s / 23.3 s total). The restored view in
test-results/persistent-behaviors-restored.png was visually reviewed.
Run it with node tools/cli/test-persistent.mjs --behaviors --trusted.
Remaining review: sensor-specific process-kill boundaries, storage failure during host drain, maximum script/occupancy load, parked touch responses over browser transport, a backup round trip containing non-default private script state, process/network physics owners with scripts, browser release upgrades, mobile/ hardware and Coolify qualification. Cross-schema migration of retained rooms is still unsupported; preserve the existing startup guard. Final character, environment and arrival art remain required and unapproved.
#Visual puzzle wiring
Open a tile world in the editor and choose Puzzle wiring… in the inspector. Choose an existing sensor response or a static object without another interaction. Check the areas on the left and the actions on the right; gold lines show the connections. Choose occupied, remembered first entry or remembered three entries, then Preview connections, Save, and Publish or Apply for shared play. Create and shape areas first with 2D sensors…. Edit one response at a time; preview and save its connections before choosing another response.
Existing scripts and finishes are preserved by default. Choosing a named recipe explicitly replaces the response logic. Unchecking an area removes only that response's connection; its geometry, direct color/action locks and other response links remain intact. Multiple responses controlling an action must all be active. Direct sensor locks still require occupancy even when a remembered response is active. A response without connected areas receives no area events. Wiring, behavior creation and action locks share one transaction and one undo entry. Older rectangular areas are promoted to the response-capable sensor profile.
Focused acceptance (2026-10-26): two native checks pass for atomic creation,
preserved unrelated links, disconnection, complete inverse restoration, invalid
area/action rejection and occupied response objects. Type/import checks pass
(263 source files). The software-WebGPU browser journey passes visual authoring,
save, undo/redo, editor reload, publication, two-player activation, exit,
disconnection, unlocked collection and player reload (47.3 s / 51.6 s total).
test-results/puzzle-wiring-editor.png and the collected-player view were visually
reviewed. Run tests/browser/puzzle-wiring.spec.ts with the isolated editor relay.
Remaining review: narrow/mobile layouts and keyboard/screen-reader navigation, maximum-area graphs, simultaneous creator edits, richer branching/boolean recipes, visual recipe customization and hosted publication combinations. The final character/environment/arrival art pass and accumulated physics/hosting qualification remain open. This is a recipe-based wiring view, not a general node-programming language.
#Named traveler actions (F69)
World format 72 adds four-way.2 traveler animation. In Tilemap → Sprite artwork
& animation, select a four-row traveler sheet and enable directional animation.
“Add action” exposes an ID, player button label, first column, frame count, speed
and loop switch. Up to 12 actions share the sheet's four facing rows. Preview
movement includes each authored action. Stage, Save changes and publish normally.
The player shows authored action buttons and Rest while playing that map.
Action requests carry a unique token and facing through the ordinary movement input stream. Trusted motors accept only actions authored in the current map. Local and remote presentation use the named range; one-shots return to idle/walk, loops continue until another action or Rest. Remote sampling keeps the received phase/facing while interpolating and extrapolating motion. Tokens prevent a held input from restarting a completed one-shot. This is presentation animation; actions do not create additional attack, damage or inventory rules.
Local saves/checkpoints and durable player poses retain action name, token, phase and facing. Existing room presence and reconnect carry the locomotion state. Room-host transfer retains a source action when the destination authors the same name. Moving to an incompatible map drops the action from the player save. Old four-way.1 sheets and worlds retain their idle/walk contract.
Focused delivery check: tests/sprite-actions.test.ts passes source save/undo,
format promotion, shared-motion validation, remote row/frame selection, durable
save reconstruction and exact checkpoint continuation. Type, package boundary
and generated wire checks pass. The actual editor was visually reviewed;
screenshot.
Deferred until the feature inventory is complete: a full two-browser routed-host journey with one-shots/loops, disconnect/recovery timing, touch/controller review, custom artwork review and the broader regression/performance matrix.
#Integrated action journey — October 28
The physical Intel Xe-3LPG browser journey passes actual editor sheet import, Wave/Work authoring, save/publish, two independent travelers, local and remote motion/action presentation, pickup agreement and reload persistence. Default binary input now carries structured action requests; overhead play keeps the mouse free so the visible action buttons can be clicked. Local presentation also supplies the required motion stamp. This closes the demonstrated integration failures; routed-host action transfer, controller/touch review and final 2D art remain separate. The arrow sheet in this check is deliberately diagnostic art.

Reproduce with the isolated editor environment used by test:browser:editor and
playwright test tests/browser/tilemap.spec.ts. The complete native suite has
1,446 passes, zero failures and 259 environment-dependent skips in this pass.