Testing

Test in mock mode first, from the dashboard and from the console client. Every request carries a request ID, so you can find exactly what happened in the server's logs.

Web Conversation Tester

ExampleServer dashboard Conversation page in mock mode, showing player name, session, optional context fields, the Your message box with Send, Cancel and New session buttons, and the Game event test panel below with Event type and Mode fields.
The dashboard Conversation page and its Game event test, in mock mode.
  1. Open Roleplay > Conversation. The default session is dashboard-demo and the NPC is npc_guide.
  2. Type in Your message and press Send. Try follow me: the actions line shows follow_player (target npc_guide).
  3. Press New session to start fresh: shared facts still apply, and the new turn shows 0 history lines.

The tester writes ordinary history and displays actions without running them. No dashboard page runs game actions.

Game Events

On the same page, Game event test sends event.php. Mode Log only stores an event with no model call, history or actions. NPC responds makes the NPC react like a normal turn. From the client folder:

.\example_mod.exe --event location_entered "The player entered the market."
.\example_mod.exe --react item_given "The player gave a lantern. follow me"

Only four types exist: location_entered, item_given, combat_started and combat_ended. The game decides when to send events; the server never triggers anything itself.

Find A Request In Logs

The client prints the ID of every request, for example Trace: turn req-... (ok). Open Control Panel > Logs, filter by Request ID, and open Details.

Logs showsMeaning
turn completeThe server finished, not that a game ran anything. A client report appears under "Client reported (untrusted)".
failed, llm_unavailableThe provider failed. Search the Apache error log for example-ai [<id>].
failed, duplicate_requestThe ID was reused within a day. Use a new ID per request.
cancelled or supersededExpected after a cancel, NPC change, session change or checkpoint restore.
No rowInconclusive: rejected before logging, a filter hides it, or another install. Read the HTTP status the client printed.

Voice, NPC selection, embedding and memory calls appear on Control Panel > Connector calls instead.

Client Actions

The model can only ask for an action. The server returns only names in its allowed_actions, and the client runs one only if it is in its own allowed_actions and has an explicit handler. Nothing maps action names to commands.

  • --say "dance": reply only; the server lists dance in rejected_actions.
  • Client "allowed_actions": []: Rejected action not allowed by this mod: follow_player.

Cancellation And Stale Replies

  1. Set mock_delay_seconds to 3 on Configuration > LLM.
  2. Start the interactive client with .\example_mod.exe and type follow me.
  3. Before it answers, type /cancel, /npc scout, /unload or /session other-save.

The reply and its action are dropped and the server is told to cancel; Logs shows the turn as cancelled or superseded. In the dashboard tester, Cancel or changing the NPC does the same. Cancellation may not stop computation at the provider, and failed requests are never retried automatically.

Server check in WSL, with a mock delay of 2 or more: SMOKE_STALE=1 bash scripts/smoke.sh http://127.0.0.1:19000/ExampleServer, using your own server address. Set the delay back to 0 afterwards.

Troubleshooting

SymptomCheck
health.php 404 or 403The folder must be /var/www/html/ExampleServer or /var/www/html/custom-mods/<id>, and sudo ddistro_custom_mod setup-web must have succeeded.
Nothing answers on port 19000Run sudo ddistro_custom_mod setup-web. If setup-web is unavailable or rejected as an unknown command, run Update Distro in the DwemerDistro launcher, then run it again. See Ports and branches.
setup-web says the port is in useNothing was changed. Choose another CUSTOM_MODS_PORT from 19000 to 19999 in /etc/dwemerdistro_services.conf, run it again, then pair again.
500 server_not_configuredconfig/config.php missing, unreadable, or token still the placeholder. Run the installer again.
503 database_unavailablePostgreSQL running, and the database settings in the config.
503 not_migratedRun sudo bash scripts/install.sh again.
Client WinHTTP error 12029Server not reachable at server_url. After a port change, pair again or edit server_url.
Client 401 unauthorizedToken in config.json does not match the server. Pair again.

Also check that Apache does not serve your Git history. 200 here means anyone who can reach the port can download it. Check port 8081 too, because it also serves /var/www/html:

curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:19000/ExampleServer/.git/HEAD
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8081/ExampleServer/.git/HEAD

When sharing logs for help, include request IDs and error codes, never tokens or keys.

Full reference: START_HERE.md, Troubleshooting by request ID, SETUP.md, Troubleshooting and the ExampleMod smoke checks.

Next step: Port the client to your engine.