Commit graph

4 commits

Author SHA1 Message Date
435135ed50 feat(arcade): port makepad game libs + arcade from makepad-internal onto the fork
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.
2026-09-05 05:49:12 +03:00
Admin
f0e1f83831 Close the rik2 land: workspace, splash, and sandbox cleanup.
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.
2026-08-18 14:24:00 +02:00
Admin
6623408a57 Bind the library and composition into script — and tell the model it exists
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>
2026-08-03 12:24:10 +02:00
Admin
cec4f5b380 Arcade M4: voice + AI tiers, game library, /pair key flow, and libs/game/script
- libs/game/script (new): the table-driven game.* binding layer game.md
  called for — 71 verbs in a HashMap built once per isolate, replacing
  gamemaker's 84-arm linear chain. spawn_entity/spawn_terrain ported
  verbatim so fixture terrain matches bit-for-bit; generation-tagged
  callback slots; streaming eval + hot reload. Rollback snapshot is
  GameWorld::clone() — M1a made the world Clone, and a clone cannot forget
  a field, which is the exact bug class that put next_id in M0r's fix list.
  (Gamemaker still runs its own copy; migrating it is a follow-up.)
- Capability tiers: Voice (VAD + Whisper + local judge) -> VoiceUnfiltered
  (push-to-talk, every utterance costs a call) -> Chatbox (typing is the
  gate). Text box in every tier, mic only above Chatbox. The chain sits
  behind the local-llm feature so Quest/mobile never link a backend they
  don't have
- Librarian: the local model is an optional override (None = no opinion),
  never a gate — a flaky or absent model can only sharpen a decision.
  Beneath it, deterministic word-overlap matching for load-by-description,
  restart, and manifest-clamped knob writes. Creative requests deliberately
  do NOT match an existing game (tested). Locally-answerable utterances are
  dropped before they reach the cloud
- /pair: self-contained page (no external URLs, asserted), 4-digit confirm
  code so a room of headsets can't take the wrong key, 0600 config-dir
  storage documented as NOT a keystore — Android/iOS must move to the
  platform one before shipping. Key never enters a log, package, or error
- Racing fixture evals through the new dispatch (28 entities) and renders;
  hot-reload rollback verified live — a bad verb reports with a suggestion
  and keeps the last good world

Found (platform, unfixed — out of this task's scope):
HttpServerHeaders::from_tcp_stream buffers past the headers into a
BufReader, so a body arriving in the same TCP segment is swallowed and
handle_post blocks forever on a body that's already gone. Browsers split
the two, which is why nothing noticed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 02:05:50 +02:00