This app can be driven while it runs: call its commands, read and set its state, pause and step it, wait for conditions, read its log, take screenshots. It is only in debug builds, under this project's debug flag (the notes above name it, usually `--debug-api`).
-`debugger` prints how to attach lldb or gdb for breakpoints and memory.
### Coding with it
Missing a command or watch for the task at hand? Add it. It is debug-only code.
- **Where it goes:**
- The hook points sit in `main`, under the project's debug define, or in a shim module: `Debug::Session debug({ .name = "..." });` after `ThreadPool::Start()`, and `Debug::Pump()` once per frame on the app's thread.
- Registrations go in debug-only sources, which `project.cpp` adds only when the flag is on.
- **Pause and step** hold only what is gated on them. In a frame loop: `while (acc >= dt && Debug::Advance()) { Tick(); acc -= dt; }`. In a fixed-step loop: `Debug::Paused()` and `Debug::TakeSteps()`.
Debug::Sample("solver.residual", residual); // hot code, any thread; `trace --history`
Debug::Check(mass > 0, "physics", "body {} has mass {}", id, mass); // a soft assert; also Log, LogWarn, LogError, Emit
```
- **Rules:**
- **Threading:** handlers, getters and setters run on the app's thread inside `Pump`, so they read state without locks, but must not block. For a result that takes frames (a GPU readback, a network round trip), return `Debug::Async<T>` with a poller.
- **Reuse the app's own paths:** call the same code the UI or game uses, rather than re-implementing it in the command, because a re-implemented command drifts from the real behaviour.
- **Errors** are `Debug::Error{ "Code", "message" }`, with the message saying what to do next.
- **Names:** commands are `Area_Verb`; watches are dotted paths.
- **Per-object state** goes through a `Debug::Group` member, `Debug::Group debug{ std::format("fort{}", slot) }`, which prefixes paths and unregisters with its owner. It can't be moved, so keep such objects in `std::unique_ptr` or `std::deque`.
- **Types:** arguments and results are aggregates (public fields with default initializers), scoped enums, strings, numbers or std containers. For anything else, specialize `Debug::Codec<T>`.
- **Screenshots:** `Debug::SetCapture` makes them work. Crafter.Debug's README has the Crafter.Graphics version.