feat(examples): Basic, a ball simulation with a bug to find

The example was a placeholder that printed which build it was. It is
now a headless simulation of five balls dropped onto a 10 cm floor
slab at 60 ticks a second, with a bug planted the way such bugs are
written: collision is checked only where each step lands, so the ball
dropped from 60 m, at 34 m/s, steps over the slab and falls forever.

It shows the consumer side end to end:
- Basic.DebugShim forwards Pump, Advance, QuitRequested, Log, Check,
  Emit and Sample to Crafter.Debug in debug builds and does nothing in
  plain ones, so the simulation and main have no #ifdef but the
  session's.
- Basic.DebugCommands, compiled only when Debug::Use returns true,
  registers World_Spawn, World_Reset, World_Clear and Ball_Get, and
  watches for the physics, the floor and the balls.
- The simulation checks each ball stays above the floor, emits Bounce
  and samples the fastest ball, so `pause --on-check`, `wait --event`
  and `trace --history` have something to show.

Driven over the real transport, it shows the whole loop: `log --level
warn` names the ball, `pause --on-check` stops the frame it fails,
`set physics.substeps 4` and `call World_Reset` show the fix holds
before any code changes. The plain build simulates ten seconds and
prints that one ball fell through. Its agent notes describe the app
without the bug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-11-01 03:22:17 +01:00
commit 4a0d911e69
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
8 changed files with 292 additions and 9 deletions

View file

@ -1,3 +1,17 @@
# Basic
A Crafter.Debug example. Build with `crafter-build --debug-api` to include the debug server.
A Crafter.Debug example: a headless simulation of balls dropped onto a floor slab, 60 ticks a second.
- **Plain build:** `crafter-build`, run with `crafter-build -r`. It simulates ten seconds as fast as it can and prints how many balls ended up below the floor.
- **Debug build:** this project's debug flag is `--debug-api` and its define `BASIC_DEBUG_API`. The build adds Crafter.Debug, and the app runs in real time until an agent tells it to quit.
## Layout
- `interfaces/Basic.World.cppm`, `implementations/Basic.World.cpp`: the simulation.
- `interfaces/Basic.DebugShim.cppm`: Crafter.Debug's frame-loop and timeline calls, in every build. In the plain build they are stand-ins that do nothing, so the simulation and `main` need no `#ifdef`.
- `interfaces/Basic.DebugCommands.cppm`, `implementations/Basic.DebugCommands.cpp`: the commands and watches, compiled only when `Debug::Use` added Crafter.Debug.
- `implementations/main.cpp`: the loop, with the session under the define.
## Working on Crafter.Debug from here
`project.cpp` loads Crafter.Debug from this checkout (`#pragma crafter dependency "../.."`). Crafter.Network's callback API, which the transport needs, may not be on Network's `master` yet. If it isn't, build with `CRAFTER_DEBUG_NETWORK=<a Network checkout that has it>/project.cpp`.