Reintroduce apps/arcade and the ten game crates that were ripped out of
the fork (assets, audio, blocks, coedit, gen, net, pkg, render, script,
session), from makepad-internal/dev. Reconcile against the fork's layout:
- makepad-game-sim/math come from the fork's existing libs/sim + sim/math;
the copied internal libs/game/{sim,math} are dropped and the kept game
crates plus arcade point at ../../sim and ../../sim/math.
- arcade AI is rewritten off the removed makepad-ai agent API onto the
makepad-ai-hub headless ChatProvider worker (example/cad pattern):
AiWorker{send,cancel,poll}, ai_worker_loop driving
ClaudeApiChatProvider(ClaudeCli), AiWorkerEvent availability/delta/
done/error mapped into the chat feed and authoring land_edit, with
main.rs send_message/cancel_request/event-drain rebuilt around it.
- the game-script sandbox is adapted to the fork's jailed splash storage:
every isolate gets mod.fs = splash_storage jail; splaes splash_storage
set_root_for_heap is now public so the ScriptHost (or Splash) can grant
a per-game jail root. ENT font: build.rs/dispatch.rs entities fill new
fork sim Entity/Part fields via ..Default::default(); world_raycast now
borrows mutably and returns the material id.
cargo check -p makepad-arcade and the game + arcade test suites pass.
Point the workspace at libs/asset and libs/render. Drop Arcade
frontend, gamemaker, rig, pack registry, physics, and the old
libs/game gameplay crates. Those live in the private sandbox repo.
The directive was that the demo scene become a project template you can make
new worlds from and edit by voice. This is the blocker gone: an authored
splash file can now build the world the demo builds.
`apps/arcade/resources/template.splash` is that world — sky, sun, terrain,
crossroads, two rows of houses, six distinct drivable cars, a bearded hero,
wandering townsfolk and the spiral climb — entirely in `game.*` verbs. It
loads: "eval ok, 28 entities, 5 skinned characters".
Two engine gaps had to close first, and both were the same shape: arcade
owned something the script could not reach.
**The script could not see the asset library.** `ScriptHost::set_assets`
existed and arcade never called it, so every asset verb — find_model, model,
kits, cast — reported "no stock library on this device" on a machine with
4,700 models on disk. arcade built an index for its own Rust demo and kept
it. An authored game therefore could not use any of the art the demo is made
of, which is most of the reason the demo had to stay in Rust. The index is
now built once, lazily, and shared with the host.
**Script characters had no bodies.** The skinned draw path walks
`self.villagers`, which only the built-in Rust world ever filled, so every
character in an authored game rendered as its bare collision box — which is
what a splash world looked like next to the demo. `sync_script_characters`
now builds that list from `blocks.characters` after each eval, matching the
model id the script asked for against the loaded cast and round-robining on a
miss. A wrong-looking character beats an invisible one.
Not yet done, and the template is honest about which parts are which: the
climb's moving lifts and the fireworks still have no verb, and the world is
written out longhand where the Rust version used loops.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>