* chore(build): upgrade three.js to r186 and ship rolldown at runtime
- three 0.158 -> 0.186.1 (+ @types/three) for WebGPURenderer support
- move rolldown to dependencies and unpack its native binding from asar:
the editor now compiles game scripts and the player runtime at runtime
- tsconfig: type-check player/; ignore dist-player/
- editor CSP: allow linden-game: frames (Play in the viewport)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(runtime): script runtime, fixed-timestep simulation and script compiler
- Script and HtmlUI components; ScriptRuntime runs IGameScript classes with
props, lifecycle (init/fixed/update/late/destroy), collision hooks, events,
ctx.input/physics/ui/scene, per-script error isolation and hot reload
- GameSimulation: one game loop for player and headless play, 1/60 fixed
timestep independent of refresh rate, kinematic/dynamic body sync
- ScriptCompiler (rolldown): scripts/*.ts -> browser ESM with source maps,
'three'/'linden' as runtime globals, bare npm imports rejected with file:line
- RapierBackend: velocity/impulse API, KCC slope/step from CharacterController,
raycast excluding a body, sensors no longer block characters
- SceneBridge.syncTransforms; shared MIME table, play protocol schemas,
minimal source map reader
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(player): Linden Player with scripts, HTML UI, scene camera and WebGPU
- LindenPlayer runs the shared GameSimulation, loads compiled scripts,
renders from the scene's active Camera, supports pause/step/time scale,
scene switching and per-frame stats
- HtmlUiLayer: sanitized HTML fragments in shadow roots, screen overlay or
CSS3D world labels, ctx.ui bind/on/show/hide, hot reload of fragments
- createRenderer: WebGPURenderer (three/webgpu, lazy chunk) with automatic
WebGL2 fallback; shared renderer configuration
- player runs embedded in the editor (postMessage channel, console/error
forwarding with .ts locations) or standalone in web builds
- HTML Game bridge (linden-bridge.js): pause/step via rAF + virtual clock,
console, stats, input actions
- editor: edit-mode HtmlUI preview, JSON editor for Script props
- build-player builds game.js and linden-bridge.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(play): run Play inside a sandboxed linden-game:// Game Frame
- linden-game:// protocol serving one Play session: player runtime,
compiled scripts and read-only project files; path traversal, dot folders
and symlinks outside the project are refused; strict CSP per session
- PlaySession: compiles scripts, watches scripts/ and ui/ (hot reload) and
HTML Game folders (live reload); dev runtime rebuilt when sources change
- GameFrame: cross-origin iframe (no preload access), aspect presets, reload,
devtools, Shift+F1 focus release, stall overlay, touch-controls toggle and
layout picker; the editor world stays untouched during Play
- viewport shows game stats and backend, hides edit tools while playing
- IPC: play:start/stop/openDevTools/readUiFragment, project:saveInput
- e2e: tests/e2e/playViewport.e2e.mjs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(export): HTML5 web build with scripts, UI and HTML Game projects
- WebBuildRunner: copies the player runtime (never a stale dist-player),
compiles scripts/ into game-scripts/, ships ui/; fails with file:line on
script errors
- runtime "html" projects: ship the entry folder as-is, inject the linden
bridge, redirect index.html, warn on missing references
- "HTML Game (three.js)" template with a local copy of three.js
- template projects use CharacterMovement for the player
- hierarchy/viewport placeholders for HTML Game projects
- export dialog and project creation wired to the new options
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(input): Input Actions v2 with composites, analog sources and default map
- several key sets per direction (WASD + arrows), axis actions with
negative/positive keys (Q/E), button pressThreshold for analog sources
- full standard gamepad mapping (sticks, bumpers, analog triggers),
touch joystick/look/buttons as virtual sources, mouse look via pointer lock
- analog magnitude kept past a remapped radial deadzone; taps shorter than a
frame still count as one frame; lastDevice; scripted action overrides
- default control map: Move, Turn, Vertical, Look, Jump, Sprint, Crouch,
Interact (F), Attack
- normalizeInputActions migrates the three historical action shapes
- InputMap marked deprecated in favour of Input
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(movement): CharacterMovement component for keyboard, gamepad and touch
- walk/sprint/crouch with analog speed, acceleration and air control
- jump with coyote time, jump buffer and multi-jump; fly and topdown modes
- Q/E turn, fly up/down or strafe (qeMode); camera-relative movement,
face-movement, first-person when the camera rides on the character
- lockAxis for 2D side-scrollers
- runs on Rapier's character controller, a dynamic body or a bare transform
- onJump/onLand/onStartSprint hooks and ctx.movement for scripts
- e2e: tests/e2e/movement.e2e.mjs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(touch): developer-customizable mobile action buttons
- buttons connect to actions through TouchButtonDef.action (value -1/+1 for
axis actions); renaming or removing buttons no longer breaks actions;
v1 layouts are migrated automatically
- behaviors hold/tap/toggle/repeat, cooldown with radial sweep, badges,
built-in SVG icons or asset images, shapes and colors
- auto scale for phones and tablets, px or % positions, 44 px touch targets
- named layouts (e.g. vehicle) and ctx.touch / linden.touch API:
show/hide/setEnabled/setLabel/setIcon/setBadge/setCooldown/setLayout
- editor "Kontrol Sentuh" tab: buttons per action, layouts, device preview,
validation (overlap, off-screen, missing action, small targets)
- e2e: tests/e2e/touchButtons.e2e.mjs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(ecs): keep EventFields when loading serialized scenes
World.addComponent applied scene data with Object.assign, so the listener
arrays written by SceneSerializer replaced onTriggerEnter/onCollisionEnter
and the other EventFields. Scenes loaded from .lscene files (and the scene
the editor sends to Play) never delivered trigger or collision events to
scripts. EventFields are now kept and only their listeners are restored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(agent): prompt-to-game agent with live progress and Linden tools
- OpenCode-backed agent host, MCP server for Linden tools and a turn
tracker/reducer that streams reasoning, text and tool steps live
- Agent panel and "Prompt to Game" wizard in the Project Manager
- tools: scene apply/read, script_write with attachTo, ui_write, web_write,
input_actions (v2, merge), touch_button, play with inputScript (characters,
touch calls and layout issues), export_web
- agent prompt covers scripts, HTML UI, HTML Games, default controls,
CharacterMovement and mobile buttons
- PRD and live-progress spec
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: asepjumadi <asep@asepjumadis-MacBook-Air.local>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>