Porting To A Real Engine

ExampleMod is a console fake game. A real mod keeps its protocol client, threading and safety checks, and replaces the console GameAdapter with your engine's real APIs. Nothing works in a game until you build and test the port there.

Boundaries To Keep

BoundaryRule
GameAdapter (src/game_adapter.h)The only interface that touches the game. Implement it with real engine APIs; the console version is src/console_game.h.
ThreadsOnly the game's main thread calls GameAdapter. Every server call runs on a worker thread or async HTTP; results come back through the mailbox in src/main.cpp. The game never waits on HTTP.
TargetBefore applying a reply, check its request_id and npc_id, and use isSameNpc() to confirm the same NPC instance is still loaded. An action's args.target_id must equal the NPC the request was sent to.
ActionsRun a name only if it is in the client's allowed_actions and has an explicit handler in applyResult(). Never execute raw model text.
AudioOptional. speak.php returns a WAV and listen.php takes one. The console saves WAVs without playing them; a port plays them on the NPC and captures the microphone to WAV. Text always comes first.

Never retry a failed request automatically: a retry could repeat a reply or an action.

Port Checklist

  • A main-thread tick or callback that alone calls GameAdapter.
  • Worker threads or async HTTP for every server call.
  • A stable NPC ID, NPC and player names, and a few context entries.
  • A session_id per save game.
  • Subtitle or message display.
  • isSameNpc() using a real engine handle or instance marker.
  • One explicit handler per allowlisted action, using the engine's own behaviour (for example, follow).
  • Request-ID and stale checks, no automatic retries, and both allowlists unchanged.
  • A private config.json location for the server URL and token.
  • The correct architecture (x64 or x86) for the game, built without warnings.

Coding Agent Handoff

AGENT_PLAYBOOK.md contains a ready prompt. Run your coding agent from a folder with your copies of both repositories and your game's modding SDK, and paste that prompt. It works in five steps and stops after each:

  1. Inspect the game's engine, SDK, threading and APIs, citing sources.
  2. Run the examples unchanged and pass the smoke checks.
  3. Rename to your own project, keeping the licence and notices.
  4. Implement the game adapter with real APIs only.
  5. Validate the build, the mock checks, then the real game.

The agent must not invent SDK functions. An unknown API should become a clearly marked TODO. Ask for mock checks and in-game results to be reported separately.

The playbook also has a warm-up exercise: add a third fictional NPC behind GameAdapter, give it a bio and fact on the server, and check retrieval in Logs, all without touching the protocol.

Add An Action

New actions follow the worked wave exercise. It touches, in your own copies:

  • The server prompt and mock in lib/llm.php, and allowed_actions in the server config.
  • One GameAdapter method, its implementation, and one branch in applyResult().
  • allowed_actions in the client config.json.
  • Both copies of PROTOCOL.md, kept identical.

Then prove each allowlist rejects it on its own. The shipped templates keep follow_player as the only action.

Add A Dashboard Page

Copy ui/examples/blank.php to ui/my_page.php, change its includes from ../common.php and ../tmpl/ to common.php and tmpl/, and set its title and active key:

<?php
require __DIR__ . '/common.php';
$title = 'My page';
$active = 'my_page';
require __DIR__ . '/tmpl/header.php';
?>
<section class="chim-panel">
    <h2>My section</h2>
    <p>Add your content here.</p>
</section>
<?php require __DIR__ . '/tmpl/footer.php'; ?>

Add 'my_page' => ['My page', 'my_page.php'] to a group in ui/navigation.php. Escape output with e($value), check CSRF on every state-changing POST, and never print secrets. UI_GUIDE.md has the full rules and an agent prompt.

Evidence Levels

Report each level separately, and claim only what you actually ran:

  1. Server lint, migrations twice, and scripts/smoke.sh in mock mode.
  2. The console client's smoke checks.
  3. Real provider calls (LLM, voice, NPC selection), each tested on its own.
  4. In game: talk to an NPC, see the subtitle, follow, cancel a slow reply, unload the NPC while a reply is pending, and stop the server, all without a crash or hang.

Until level 4 passes in a specific game, do not describe the mod as working in that game.

Full reference: START_HERE.md, Porting to a real engine, PROTOCOL.md and MAKE_IT_YOURS.md.

Next step: Plan updates and backups.