[{"data":1,"prerenderedAt":39},["ShallowReactive",2],{"se-doc-agent-guide":3},{"html":4,"toc":5},"\u003Cblockquote>\n\u003Cp>Use this guide when a coding agent (Claude Code, Codex, Cursor, Copilot, Gemini CLI or any agent with a shell) builds, runs or changes a SimEngine project. It is written for agents first and humans second.\u003C/p>\n\u003C/blockquote>\n\u003Cp>Last updated: 2026-10-29. Engine state: pre-release, M1 foundations done, M2 in progress.\u003C/p>\n\u003Ch2 id=\"read-this-first\">Read this first\u003C/h2>\n\u003Cul>\n\u003Cli>\u003Cstrong>SimEngine is a local C++20 / Vulkan 1.3 game engine driven from the command line.\u003C/strong> There is no hosted API, no API key, no account and no MCP server. Every tool is a local executable that prints one JSON document per command.\u003C/li>\n\u003Cli>\u003Cstrong>The repository is not public yet.\u003C/strong> It opens with the first distributable milestone (MIT OR Apache-2.0). Until then, this guide documents the interface so you can evaluate it; you can only run it with access to a checkout.\u003C/li>\n\u003Cli>\u003Cstrong>You cannot ship a game with SimEngine today.\u003C/strong> What works: seeded headless scenarios of point entities, offscreen PBR capture to PNG, a Windows scene playground and offline cooking of a strict static glTF/GLB subset. What does not exist yet: supported physics or collisions, a game loop, input for gameplay, audio, textured materials, shadows, terrain or orbital propagation. Do not promise or attempt these.\u003C/li>\n\u003Cli>\u003Cstrong>The runtime never calls an LLM.\u003C/strong> You drive development; the engine never waits for you.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"how-you-work-with-simengine\">How you work with SimEngine\u003C/h2>\n\u003Cp>The loop the engine is optimized for. Every step is a command you run and a document you parse.\u003C/p>\n\u003Col>\n\u003Cli>\u003Cstrong>Discover\u003C/strong>: \u003Ccode>simengine_host --capabilities\u003C/code> prints the scenario schema, units, frames, the components and commands of exactly the compiled-in modules, limits, the determinism scope, every exit and error code, and an example scenario valid for this build. Read it instead of guessing from documentation.\u003C/li>\n\u003Cli>\u003Cstrong>Author\u003C/strong>: edit versioned text. A scenario (\u003Ccode>simengine.scenario\u003C/code>, version 1) declares a seed, a tick schedule, entities, scheduled commands and expectations. Every position states its value, unit and frame.\u003C/li>\n\u003Cli>\u003Cstrong>Run headless\u003C/strong>: \u003Ccode>simengine_host --run scenario.json --out RUN_DIR\u003C/code> loads, steps and checks expectations, then writes the result and artifacts.\u003C/li>\n\u003Cli>\u003Cstrong>See\u003C/strong>: \u003Ccode>simengine_capture --scene scene.sescene --out-dir CAPTURE_DIR\u003C/code> renders offscreen through Vulkan and writes a PNG plus a manifest. A black, empty or background-only image is a failure (exit 12), never a pass.\u003C/li>\n\u003Cli>\u003Cstrong>Prove\u003C/strong>: a change is done only when its expectations pass, the \u003Ccode>final_state_sha256\u003C/code> changed as intended and the capture shows what you meant. Compiling, surviving one tick or printing a success boolean is not acceptance.\u003C/li>\n\u003C/ol>\n\u003Ch2 id=\"setup\">Setup\u003C/h2>\n\u003Cp>From a SimEngine checkout, read \u003Ccode>AGENTS.md\u003C/code> first, then use the maintained, rerunnable setup scripts that humans and CI also use:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Linux\u003C/strong>: \u003Ccode>./tools/setup.sh --install-missing\u003C/code> detects the environment, installs only missing recorded prerequisites (Ubuntu/Debian), configures and builds the \u003Ccode>linux-release\u003C/code> preset, runs the test suite and the host smoke check.\u003C/li>\n\u003Cli>\u003Cstrong>Windows 11\u003C/strong>: install Visual Studio 2022 (C++ x64), CMake 3.28+, Ninja and Python 3.12+, then run \u003Ccode>tools/setup.ps1\u003C/code>. No Vulkan SDK is needed: the pinned Khronos headers are fetched and the loader is opened at run time.\u003C/li>\n\u003C/ul>\n\u003Cp>Expect zero failures among the selected CTest tests; report skips separately. The final smoke check prints one JSON summary naming the Vulkan device, or a structured \u003Ccode>BLOCKED\u003C/code> outcome on a machine without a Vulkan 1.3 driver. Report failures verbatim with the exit code. Do not work around a failure silently.\u003C/p>\n\u003Ch2 id=\"implementation-contract\">Implementation contract\u003C/h2>\n\u003Col>\n\u003Cli>\u003Cstrong>Start from capabilities.\u003C/strong> Run \u003Ccode>--capabilities\u003C/code> before writing a scenario. Use only the commands, components and modules it lists; a disabled module’s commands do not exist and are rejected.\u003C/li>\n\u003Cli>\u003Cstrong>Keep your project outside the engine checkout.\u003C/strong> Never edit engine sources, tests or \u003Ccode>examples/\u003C/code> to get a pass.\u003C/li>\n\u003Cli>\u003Cstrong>Be explicit.\u003C/strong> Positions are \u003Ccode>{ &quot;value&quot;: [x, y, z], &quot;unit&quot;: &quot;m&quot;, &quot;frame&quot;: &quot;world&quot; }\u003C/code>. Frames are right-handed, \u003Ccode>+y\u003C/code> up. Durations are nanoseconds (\u003Ccode>&quot;unit&quot;: &quot;ns&quot;\u003C/code>).\u003C/li>\n\u003Cli>\u003Cstrong>Validate before you run.\u003C/strong> \u003Ccode>--load FILE\u003C/code> validates all-or-nothing and prints the initial state; \u003Ccode>simengine_capture --check-scene FILE\u003C/code> validates a scene without a GPU.\u003C/li>\n\u003Cli>\u003Cstrong>Use new or empty output directories.\u003C/strong> Existing content is never overwritten.\u003C/li>\n\u003Cli>\u003Cstrong>Classify outcomes by exit code, then by \u003Ccode>error.code\u003C/code>.\u003C/strong> Do not parse stderr prose. Diagnostics on stderr are JSON Lines (\u003Ccode>simengine.diagnostic\u003C/code>, version 1).\u003C/li>\n\u003Cli>\u003Cstrong>Do not retry blindly.\u003C/strong> A failed expectation (exit 12) is a result, not a flake: read which expectation failed and why. Timeouts (exit 11) mean your \u003Ccode>--max-wall-ms\u003C/code> bound was reached.\u003C/li>\n\u003Cli>\u003Cstrong>Missing GPU is BLOCKED, not PASS.\u003C/strong> Exit codes 3 to 5 mean no usable Vulkan device. Report \u003Ccode>BLOCKED_ENVIRONMENT\u003C/code>; never fake a capture.\u003C/li>\n\u003Cli>\u003Cstrong>Report evidence.\u003C/strong> Finish with the commands run, exit codes, \u003Ccode>final_state_sha256\u003C/code> values, PNG paths and what SimEngine could not do.\u003C/li>\n\u003C/ol>\n\u003Ch2 id=\"scenario-format-simengine-scenario-v1\">Scenario format (simengine.scenario v1)\u003C/h2>\n\u003Cp>This is the scenario of the \u003Ccode>first_scene\u003C/code> example, abridged:\u003C/p>\n\u003Cpre class=\"code\" data-lang=\"json\">\u003Cspan class=\"code__bar\">\u003Cspan class=\"code__lang\">json\u003C/span>\u003Cbutton type=\"button\" class=\"code__copy\" data-copy>Copy\u003C/button>\u003C/span>\u003Ccode>\u003Cspan class=\"tk-punc\">{\u003C/span>\n  \u003Cspan class=\"tk-key\">\"schema\"\u003C/span>: \u003Cspan class=\"tk-str\">\"simengine.scenario\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"schema_version\"\u003C/span>: \u003Cspan class=\"tk-num\">1\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"name\"\u003C/span>: \u003Cspan class=\"tk-str\">\"first_scene\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"seed\"\u003C/span>: \u003Cspan class=\"tk-num\">20261027\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"time\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"tick_duration\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-num\">16666667\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"ns\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"ticks\"\u003C/span>: \u003Cspan class=\"tk-num\">120\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"id\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"kind\"\u003C/span>: \u003Cspan class=\"tk-str\">\"cartesian\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"handedness\"\u003C/span>: \u003Cspan class=\"tk-str\">\"right\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"up_axis\"\u003C/span>: \u003Cspan class=\"tk-str\">\"+y\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"entities\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\n    \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"id\"\u003C/span>: \u003Cspan class=\"tk-str\">\"table\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"position\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\u003Cspan class=\"tk-num\">0\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">0\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">-1\u003C/span>\u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n    \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"id\"\u003C/span>: \u003Cspan class=\"tk-str\">\"ball\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>  \u003Cspan class=\"tk-key\">\"position\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\u003Cspan class=\"tk-num\">2\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">0.25\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">1.5\u003C/span>\u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\n  \u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"generators\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\n    \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"kind\"\u003C/span>: \u003Cspan class=\"tk-str\">\"scatter_box\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"id_prefix\"\u003C/span>: \u003Cspan class=\"tk-str\">\"barrel_\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"count\"\u003C/span>: \u003Cspan class=\"tk-num\">3\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n      \u003Cspan class=\"tk-key\">\"min\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\u003Cspan class=\"tk-num\">1.5\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">0\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">-3.5\u003C/span>\u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n      \u003Cspan class=\"tk-key\">\"max\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\u003Cspan class=\"tk-num\">3.5\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">0\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">-2\u003C/span>\u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\n  \u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"commands\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\n    \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"at_tick\"\u003C/span>: \u003Cspan class=\"tk-num\">60\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"command\"\u003C/span>: \u003Cspan class=\"tk-str\">\"simengine.entity.set_position\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"version\"\u003C/span>: \u003Cspan class=\"tk-num\">1\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n      \u003Cspan class=\"tk-key\">\"args\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"entity\"\u003C/span>: \u003Cspan class=\"tk-str\">\"ball\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"position\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\u003Cspan class=\"tk-num\">0.25\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">1\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">-1\u003C/span>\u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\n  \u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n  \u003Cspan class=\"tk-key\">\"expect\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\n    \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"name\"\u003C/span>: \u003Cspan class=\"tk-str\">\"ball_on_table\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"entity\"\u003C/span>: \u003Cspan class=\"tk-str\">\"ball\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"quantity\"\u003C/span>: \u003Cspan class=\"tk-str\">\"position\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n      \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-punc\">[\u003C/span>\u003Cspan class=\"tk-num\">0.25\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">1\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-num\">-1\u003C/span>\u003Cspan class=\"tk-punc\">]\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"frame\"\u003C/span>: \u003Cspan class=\"tk-str\">\"world\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span>\n      \u003Cspan class=\"tk-key\">\"tolerance\"\u003C/span>: \u003Cspan class=\"tk-punc\">{\u003C/span> \u003Cspan class=\"tk-key\">\"value\"\u003C/span>: \u003Cspan class=\"tk-num\">0\u003C/span>\u003Cspan class=\"tk-punc\">,\u003C/span> \u003Cspan class=\"tk-key\">\"unit\"\u003C/span>: \u003Cspan class=\"tk-str\">\"m\"\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span> \u003Cspan class=\"tk-punc\">}\u003C/span>\n  \u003Cspan class=\"tk-punc\">]\u003C/span>\n\u003Cspan class=\"tk-punc\">}\u003C/span>\u003C/code>\u003C/pre>\n\u003Cp>The full file is at \u003Ccode>/simengine/examples/first_scene/scenario.json\u003C/code>. Without the optional \u003Ccode>point_mass\u003C/code> module, motion is a sequence of scheduled teleports; with it (\u003Ccode>-DSIMENGINE_MODULES=point_mass\u003C/code>), entities gain \u003Ccode>point_mass.body\u003C/code> (velocity) and the scene \u003Ccode>point_mass.world\u003C/code> (gravity), with the commands \u003Ccode>point_mass.apply_impulse\u003C/code> and \u003Ccode>point_mass.set_velocity\u003C/code>. Always confirm with \u003Ccode>--capabilities\u003C/code>.\u003C/p>\n\u003Ch2 id=\"run-artifacts\">Run artifacts\u003C/h2>\n\u003Cp>\u003Ccode>simengine_host --run FILE --out DIR\u003C/code> writes into DIR:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>scenario.json\u003C/code>: a byte copy of the input\u003C/li>\n\u003Cli>\u003Ccode>initial_state.json\u003C/code> and \u003Ccode>final_state.json\u003C/code> (\u003Ccode>simengine.scene_state\u003C/code>); the result carries the SHA-256 of the final state\u003C/li>\n\u003Cli>\u003Ccode>trace.jsonl\u003C/code> when \u003Ccode>--trace-every N\u003C/code> is set\u003C/li>\n\u003Cli>\u003Ccode>result.json\u003C/code>: the same \u003Ccode>simengine.host.result\u003C/code> document printed to stdout\u003C/li>\n\u003C/ul>\n\u003Cp>Two runs of the same scenario on the same build and configuration give the same \u003Ccode>final_state_sha256\u003C/code>. Cross-platform bitwise determinism is not promised.\u003C/p>\n\u003Ch2 id=\"interactive-control-session\">Interactive control: --session\u003C/h2>\n\u003Cp>\u003Ccode>simengine_host --session [--max-wall-ms MS]\u003C/code> reads JSON Lines requests on stdin and writes one \u003Ccode>simengine.session.response\u003C/code> per request on stdout. Operations: \u003Ccode>load\u003C/code>, \u003Ccode>step\u003C/code>, \u003Ccode>inspect\u003C/code>, \u003Ccode>command\u003C/code> (with dry run and an expected state version), \u003Ccode>expectations\u003C/code>, \u003Ccode>capabilities\u003C/code> and \u003Ccode>quit\u003C/code>. Use it when you need to step and inspect without re-running a whole scenario.\u003C/p>\n\u003Ch2 id=\"the-first-scene-example-and-its-skills\">The first_scene example and its skills\u003C/h2>\n\u003Cp>\u003Ccode>examples/first_scene\u003C/code> is the reference project. Its driver \u003Ccode>first_scene.py\u003C/code> calls only the public tools, in separate processes, and verifies what they write:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>python first_scene.py new DEST\u003C/code> creates a project (and copies the three skills into \u003Ccode>DEST/.claude/skills\u003C/code>)\u003C/li>\n\u003Cli>\u003Ccode>python first_scene.py check --project P --build B\u003C/code> validates engine compatibility, scene and scenario without a GPU\u003C/li>\n\u003Cli>\u003Ccode>python first_scene.py run --project P --build B\u003C/code> runs the full journey: load, run twice, capture, verify, manifest\u003C/li>\n\u003Cli>\u003Ccode>python first_scene.py verify [MANIFEST]\u003C/code> re-verifies a finished journey from its files\u003C/li>\n\u003C/ul>\n\u003Cp>Expected outcome for an unchanged project: \u003Ccode>PASS\u003C/code>, 3 of 3 expectations, three PNG captures and a \u003Ccode>manifest.json\u003C/code>. The driver stops with \u003Ccode>incompatible_engine\u003C/code> (exit 21) if the engine reports interface versions the skills were not written for.\u003C/p>\n\u003Cp>Agent skills (load them; they are the procedures this guide summarizes):\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/simengine/docs/create-project\">simengine-create-project\u003C/a>: create, check, run and verify a project\u003C/li>\n\u003Cli>\u003Ca href=\"/simengine/docs/modify-scene\">simengine-modify-scene\u003C/a>: add an object, move it, add an expectation, prove the change\u003C/li>\n\u003Cli>\u003Ca href=\"/simengine/docs/run-capture-diagnose\">simengine-run-capture-diagnose\u003C/a>: run, capture, and diagnose failures by exit code\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"exit-codes\">Exit codes\u003C/h2>\n\u003Cp>\u003Ccode>simengine_host\u003C/code> (also in the JSON \u003Ccode>exit_code\u003C/code>; \u003Ccode>error.code\u003C/code> names the failure):\u003C/p>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Code\u003C/th>\n\u003Cth>Name\u003C/th>\n\u003Cth>Meaning\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>0\u003C/td>\n\u003Ctd>ok\u003C/td>\n\u003Ctd>Success\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>1\u003C/td>\n\u003Ctd>internal_error\u003C/td>\n\u003Ctd>Unexpected exception inside the host\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>2\u003C/td>\n\u003Ctd>usage_error\u003C/td>\n\u003Ctd>Invalid command line\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>3\u003C/td>\n\u003Ctd>vulkan_loader_unavailable\u003C/td>\n\u003Ctd>No Vulkan loader library on this machine\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>4\u003C/td>\n\u003Ctd>vulkan_driver_unavailable\u003C/td>\n\u003Ctd>Loader present, no driver supporting Vulkan 1.3\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>5\u003C/td>\n\u003Ctd>no_vulkan_device\u003C/td>\n\u003Ctd>Instance created, zero physical devices\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>6\u003C/td>\n\u003Ctd>no_suitable_device\u003C/td>\n\u003Ctd>Devices exist, none meets the requirements\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>7\u003C/td>\n\u003Ctd>backend_initialization_failed\u003C/td>\n\u003Ctd>Other instance or device creation failure\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>8\u003C/td>\n\u003Ctd>validation_errors\u003C/td>\n\u003Ctd>Backend opened, the validation layer reported errors\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>9\u003C/td>\n\u003Ctd>runtime_self_check_failed\u003C/td>\n\u003Ctd>Backend fine, core runtime self-check failed\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>10\u003C/td>\n\u003Ctd>scenario_invalid\u003C/td>\n\u003Ctd>Validation failed; nothing ran\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>11\u003C/td>\n\u003Ctd>scenario_timeout\u003C/td>\n\u003Ctd>The wall-time bound stopped the run or session\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>12\u003C/td>\n\u003Ctd>scenario_expectation_failed\u003C/td>\n\u003Ctd>Run completed, an expectation failed\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>13\u003C/td>\n\u003Ctd>scenario_io_error\u003C/td>\n\u003Ctd>Input unreadable or output directory unusable\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>14\u003C/td>\n\u003Ctd>simulation_fault\u003C/td>\n\u003Ctd>A tick produced non-finite state (rolled back)\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>15\u003C/td>\n\u003Ctd>module_startup_failed\u003C/td>\n\u003Ctd>Optional modules could not be initialized\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\n\u003Cp>Codes 3 to 5 all mean “no usable Vulkan device”. A process killed by a signal prints no document; your supervisor must classify it as a crash. Capture exit codes are in the \u003Ca href=\"/simengine/docs/cli\">CLI reference\u003C/a>.\u003C/p>\n\u003Ch2 id=\"what-not-to-do\">What not to do\u003C/h2>\n\u003Cul>\n\u003Cli>Do not invent commands, flags, components or modules. If \u003Ccode>--capabilities\u003C/code> does not list it, it does not exist in this build.\u003C/li>\n\u003Cli>Do not edit engine code, tests or examples to make a check pass.\u003C/li>\n\u003Cli>Do not treat “it compiled” or exit 0 from a partial step as done.\u003C/li>\n\u003Cli>Do not fake or reuse a capture when the GPU is unavailable.\u003C/li>\n\u003Cli>Do not add an LLM call, network call or API key to a game or to the runtime.\u003C/li>\n\u003Cli>Do not claim physics, collisions, input, audio, textures or a game loop: they are not supported yet.\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"links\">Links\u003C/h2>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/simengine/llms.txt\">llms.txt\u003C/a> and \u003Ca href=\"/simengine/llms-full.txt\">full context\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"/simengine/docs/cli\">CLI reference\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"/simengine/agent-prompt.txt\">Copy-ready agent prompt\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"https://indiega.me/simengine\">What SimEngine is\u003C/a> and \u003Ca href=\"https://indiega.me/ai-game-engine\">why it is an AI game engine\u003C/a>\u003C/li>\n\u003C/ul>\n",[6,9,12,15,18,21,24,27,30,33,36],{"id":7,"text":8},"read-this-first","Read this first",{"id":10,"text":11},"how-you-work-with-simengine","How you work with SimEngine",{"id":13,"text":14},"setup","Setup",{"id":16,"text":17},"implementation-contract","Implementation contract",{"id":19,"text":20},"scenario-format-simengine-scenario-v1","Scenario format (simengine.scenario v1)",{"id":22,"text":23},"run-artifacts","Run artifacts",{"id":25,"text":26},"interactive-control-session","Interactive control: --session",{"id":28,"text":29},"the-first-scene-example-and-its-skills","The first_scene example and its skills",{"id":31,"text":32},"exit-codes","Exit codes",{"id":34,"text":35},"what-not-to-do","What not to do",{"id":37,"text":38},"links","Links",1793299074004]