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.
8 new verbs (table now 115): find_model (DISTINCT ids, not ranked duplicates),
find_palette (matched set from one pack), model, kits, cast, road_network,
town, dungeon. game.find was ALREADY TAKEN by entity-by-tag lookup — the
duplicate-name test caught the clash before it shipped, and find_model/
find_palette now match the agent TOOL names, so the model's knowledge
transfers between the tool it calls and the verb it writes.
Verbs run synchronously (search and layout are pure CPU); only GLB load and
draw need a host, so placements queue through the same mechanism as audio and
particles — which also means a scene composes headlessly with no renderer
attached. Tiles carry their own collider from the kit pitch, so scripted props
are as solid as hand-placed ones.
THE MOST IMPORTANT EDIT WAS A DELETION. splashgame.md said "Everything is
procedural... No image, model, or audio files" — the doc was actively telling
the model it had no models, which is why generated games were bare primitives
while 4,442 models sat unused. Replaced with an instruction to reach for the
library before game.box, three rules (never place result #1 five times; one art
pack per region; generate layouts rather than hand-placing) and a wrong-vs-
right example. A test asserts that claim cannot come back.
Two bugs found by probing the REAL library rather than reasoning:
- town() would have placed ZERO buildings, silently: it selects
TileRole::Building, but every role-less model mapped to Prop — and
city-kit-suburban is 40 whole buildings with no parsed roles. A role-less
model is genuinely ambiguous (a building on a lot, or a cone at a kerb), so
kit_from_index now takes a KitUse hint. Against the real library: 104
buildings, 136 road tiles, 0 adjacency errors
- the index folds crossroads and T-junctions into one `junction` role, but a
4-way cell needs four open edges; a T standing in for a crossroad leaves a
road stub pointing at nothing. Disambiguated by name
village.splash is the scenery counterpart to racing.splash: a town, a wood of
four different conifers, a dungeon, a playable character — and not one model id
written by hand.
NOT BOUND, and why: game.tree/rock/blob and game.scatter generate MESHES, and
set_models takes an asset id, not geometry — there is no mesh-upload path for
generated meshes yet, so binding them would have meant faking it. Additive once
a generated-mesh queue exists.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>