A Godot 4.6 desktop client for GoMud — Keg's Catacombs.
WebSocket · Full GMCP · RPG equipment UI · Live room map · Portrait art
| Feature | Description |
|---|---|
| RPG Inventory & Equipment | Click-to-equip backpack grid and worn equipment slots — each slot resolves to a local icon |
| Live Room Map | Tile-based map rendered from Room.Info GMCP with persistent session history |
| Character Status Bar | Compact HP / SP / XP / Gold strip updated in real-time from Char.Vitals |
| Skills & Spells | Browseable panels from Char.Skills / Char.Jobs and parsed spell tables |
| Active Effects | Popup from Char.Affects listing all current status effects |
| Kill Statistics | Statistics panel from Char.Kills |
| Room Objects | NPC / mob list per room with portrait images and quick-action buttons |
| NPC Look | Inspect NPCs with full description, health state, and worn equipment grid |
| Item Context Menu | Look · Inspect · Equip · Drink/Eat/Use · Drop — targeting by full GMCP item ID |
| Player & Mob Portraits | Per race/class player portraits; per-mob portraits; extend with a PNG drop |
| GMCP Debug Log | JSON Lines log of all inbound/outbound GMCP traffic |
Drop a PNG at assets/items/by_id/<item_id>.png — no code changes needed.
| Players | NPCs & Mobs |
|---|---|
|
|
Requirements: Godot 4.6.1 or newer.
1. Open this folder in Godot (Project → Import).
2. Set main scene to res://main.tscn and press Run (F5).
3. Click Connect in the status area, or just type a MUD command — the
client connects and queues the command automatically.
| Command | Action |
|---|---|
/connect |
Connect to the default server |
/connect official |
Connect to the official GoMud server |
/connect catacombs |
Connect to Keg's Catacombs |
/connect wss://host/ws |
Connect to a custom server (raw WebSocket URL) |
/disconnect |
Close the active connection |
Website-style URLs are accepted — https://gomud.net/ and gomud.net both normalise to wss://gomud.net/ws.
After login, these commands render from cached GMCP state and trigger a server refresh:
| Command | GMCP Source | Panel |
|---|---|---|
eq · equipment |
Char.Inventory.Worn |
Equipment slots |
i · inv · inventory |
Char.Inventory.Backpack |
Backpack grid |
status · score |
Char + Char.Info + Char.Stats |
Score / attributes |
skills · jobs |
Char.Skills + Char.Jobs |
Skills & job progress |
affects · effects |
Char.Affects |
Active effects |
kills · killstats |
Char.Kills |
Kill statistics |
spells |
Legacy text (GMCP fallback) | Spell browser |
Legacy ANSI text is the fallback for commands without a confirmed GMCP payload.
main.tscn / main.gd Root scene — signal wiring, gmcp_state cache
├── connection.gd WebSocket lifecycle, GMCP / SOUND / text parsing
├── text_processor.gd ANSI → BBCode, MUD layout detection
│ scripts/text/ansi_parser.gd
│ scripts/text/mud_layout_detector.gd
├── scripts/ui/draggable_panel.gd Shared draggable popup base (DraggablePanel)
│
├── map.tscn / map.gd Tile-based room map (Room.Info GMCP)
├── status.tscn / status.gd Compact HP / SP / XP / Gold bar
├── mobs.tscn / mobs.gd Room objects / NPC card list
├── Input.tscn / input.gd Command text input
│
└── Containers.tscn / containers.gd Panel coordinator (ContainersController)
├── BackpackPanel scripts/panels/backpack_panel.gd
├── EquipmentPanel scripts/panels/equipment_panel.gd
├── NpcLookPanel scripts/panels/npc_look_panel.gd
├── AttributesPanel scripts/panels/attributes_panel.gd
├── SkillsPanel scripts/panels/skills_panel.gd
└── SpellsPanel scripts/panels/spells_panel.gd
scripts/panels/inventory_panel_base.gd (shared slot / action logic)
| GMCP Topic | Panel(s) |
|---|---|
Room.Info |
Map + Mobs |
Char.Vitals · Char.Worth |
Status bar |
Char.Inventory.Backpack |
BackpackPanel |
Char.Inventory.Worn |
EquipmentPanel |
Char.Info · Char.Stats |
AttributesPanel |
Char.Skills · Char.Jobs |
SkillsPanel |
Char.Affects |
AttributesPanel |
Char.Kills |
AttributesPanel |
Resolution order at runtime:
assets/items/by_id/<item_id>.pngassets/items/default_item.png
Empty equipment slots use assets/items/empty_slot.png.
No .import file yet? The client falls back to a direct disk PNG load automatically.
See developer_tools/docs/ITEM_ICONS.md for full conventions.
assets/mobs/by_name/<normalized_name>.png — spaces → underscores, all lowercase.
Falls back to assets/mobs/default_mob.png when no match is found.
assets/player_portraits/by_race_class/<race>_<class>.png
— e.g. human_warrior.png, elf_sorcerer.png.
Generate placeholder item icons for all GoMud default-world items:
powershell -NoProfile -ExecutionPolicy Bypass -File .\developer_tools\tools\generate_item_icons.ps1Generate AI image-generation prompts for item PNGs:
powershell -NoProfile -ExecutionPolicy Bypass -File .\developer_tools\tools\generate_item_icon_prompts.ps1Headless smoke check — loads main.tscn, verifies key nodes and signal contracts, confirms no auto-connect to production on startup:
& 'C:\Godot\Godot_v4.6.1-stable_win64_console.exe' --path . --headless --script res://tools/smoke_check.gdEnabled by default in connection.gd.
| Primary path | developer_tools/logs/gmcp_debug.log |
| Fallback path | user://gmcp_debug.log |
| Format | JSON Lines — GMCP inbound/outbound + connection open/close events |
| Mode | Append-only — new sessions do not overwrite existing entries |
| Privacy | Login text and submitted commands are never written; passwords are safe |
- WebSocket clients connect to
/ws; GoMud treats them asWebClient(GMCP-enabled). - Server → client GMCP is text-wrapped:
!!GMCP(<namespace> <json>) - Client → server GMCP uses the same wrapper:
!!GMCP(Room.Info)or!!GMCP(Help train) - Do not send GMCP requests immediately on socket open — GoMud installs the WebSocket GMCP handler after login. Sending
!!GMCP(...)during the login sequence will be treated as prompt input. - Raw telnet GMCP uses IAC/SB option
201; this client follows the WebSocket text protocol only.







