Doom WASM becomes a Rootly incident arena: incidents spawn as severity-coded monsters, labels show incident context, and Codex/Claude can control incident monsters through a local MCP wrapper.
Original project notes are preserved in old-README.md.
Rootly tokens stay server-side.
- Browser never calls Rootly.
ROOTLY_API_TOKENis not written to HTML, WASM, TSV, logs, or browser requests.src/rootly_incidents.local.tsvis generated locally and gitignored.src/rootly_incidents.mock.tsvis committed for demos.
Mock data, no Rootly token:
cd C:\Users\muhha\OneDrive\Desktop\doom-wasm
py scripts\rootly_dev_server.py --port 8000Open:
http://127.0.0.1:8000
Click Load Mock Data.
Live Rootly data from the last week:
cd C:\Users\muhha\OneDrive\Desktop\doom-wasm
$env:ROOTLY_API_TOKEN="your-rootly-token"
py scripts\rootly_dev_server.py --port 8000Open http://127.0.0.1:8000, click Load Last Week, then start the game.
src/rootly_incidents.mock.tsv: demo incident data.src/rootly_incidents.local.tsv: generated Rootly data, gitignored.src/agentic_game_state.local.tsv: exported player and monster state, gitignored.src/agentic_monster_commands.local.tsv: MCP/manual monster commands, gitignored.
Severity mapping:
SEV0 -> MT_BRUISER
SEV1 -> MT_SHADOWS
SEV2 -> MT_SERGEANT
SEV3 -> MT_TROOP
SEV4 -> MT_SHOTGUY
SEV5 -> MT_POSSESSED
If more than 8 incidents load, the game groups by severity, for example SEV3: 7 incidents.
MCP wrapper:
scripts/doom_control_mcp.py
It talks to:
http://127.0.0.1:8000
Tools:
get_game_state
set_monster_command
set_severity_command
clear_all_monster_commands
Commands:
normal -> default Doom AI
hold -> stop incident monster chase movement
chase_player -> target the player
fight_each_other -> target another live incident monster
Codex/Claude MCP config:
{
"mcpServers": {
"agentic-doom": {
"command": "py",
"args": [
"C:\\Users\\muhha\\OneDrive\\Desktop\\doom-wasm\\scripts\\doom_control_mcp.py",
"--server-url",
"http://127.0.0.1:8000"
]
}
}
}Restart the MCP client after adding this.
Example prompts:
Use agentic-doom. Set every severity to chase_player.
Use agentic-doom. Make SEV0 and SEV1 hold.
Use agentic-doom. Set every severity to fight_each_other.
Use agentic-doom. Clear all monster commands.
Read game state:
(Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/agentic/state" -UseBasicParsing).ContentMake all severities chase you:
$body = "target_type`ttarget`tcommand`nseverity`tSEV0`tchase_player`nseverity`tSEV1`tchase_player`nseverity`tSEV2`tchase_player`nseverity`tSEV3`tchase_player`nseverity`tSEV4`tchase_player`nseverity`tSEV5`tchase_player`n"
Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/agentic/commands" -Method POST -Body $body -ContentType "text/tab-separated-values"Clear commands:
$body = "target_type`ttarget`tcommand`n"
Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/agentic/commands" -Method POST -Body $body -ContentType "text/tab-separated-values"After C changes:
wsl -d Ubuntu-24.04 -e bash -lc "cd /mnt/c/Users/muhha/OneDrive/Desktop/doom-wasm && source ~/emsdk/emsdk_env.sh >/dev/null && make"Hard refresh the browser after rebuilding. Existing tabs keep running old WASM until reloaded.
Check commands:
Get-Content C:\Users\muhha\OneDrive\Desktop\doom-wasm\src\agentic_monster_commands.local.tsvCheck exported state:
(Invoke-WebRequest -Uri "http://127.0.0.1:8000/api/agentic/state" -UseBasicParsing).ContentChocolate Doom and this port are distributed under the GNU GPL. See COPYING.md.