A minimal terminal-based MUD kernel in C# / .NET 8 inspired by lpMUD: world objects are C# source files that are compiled and loaded at runtime, and can be unloaded/reloaded without restarting the server.
- World-as-code:
.csfiles underWorld/are objects in the world - Dynamic load/unload: compile and load objects on demand (Roslyn)
- Collectible load contexts: best-effort unload via
AssemblyLoadContext(isCollectible: true) - Hot reload: edit a world file, then
reload <blueprintId> - Blueprint/instance model (v0.2): clone blueprints to create unique instances with state
- Driver hooks (v0.3): IOnEnter, IOnLeave, IHeartbeat, IResettable, IOnReload
- Messaging (v0.3): Tell, Say, Emote via IMudContext
- Callouts (v0.4): CallOut, Every, CancelCallOut for scheduled method calls
- Persistence (v0.5): Save/load world state to JSON, auto-save on shutdown, auto-load on startup
- Multi-user (v0.6): Telnet server, multiple concurrent players, sessions
- Security (v0.7): Sandboxed world code with blocked dangerous APIs, execution timeouts
- Living objects (v0.8): ILiving interface, HP/damage/heal system, World/std/living.cs base class
- Player as world object (v0.9): IPlayer interface, cloneable player blueprints, level/XP system
- Items & Inventory (v0.10): IItem/ICarryable interfaces, get/drop/inventory commands, weight limits
- Equipment System (v0.11): IEquippable/IWeapon/IArmor interfaces, equip/unequip commands, stat bonuses
- Combat System (v0.12): ICombatant interface, kill/flee/consider commands, automatic combat rounds
- NPCs & AI (v0.13): MonsterBase/NPCBase classes, ISpawner interface, aggressive monsters, friendly NPCs
- Mudlib Polish (v0.14): Command registry, social commands (shout/whisper/emotes), help system, RoomBase class
- Configuration (v0.15): appsettings.json for driver settings (port, paths, combat, security, player defaults)
- Player Accounts (v0.16): Login/registration with SHA256 passwords, persistent player data (state, inventory, equipment, location)
- Wizard Tools (v0.17): Filesystem navigation (pwd, ls, cd, cat, more, edit), teleportation (goto), wizard homes, performance diagnostics (perf)
- Unified Commands (v0.18): All commands use single CommandRegistry system, consistent behavior between console and telnet modes
- LLM-Powered NPCs: AI-driven NPC behavior via OpenAI-compatible APIs (configurable), context-aware reactions to room events
- Persistent NPC Goals + Memory: optional PostgreSQL-backed per-NPC memory/goals with shared world knowledge base (pgvector-ready)
- Rich Terminal Output: ANSI colors via Spectre.Console, toggleable per-session with
colors on|off - Command History: Up/down arrows navigate command history, with full line editing (left/right, home/end, Ctrl+K/U)
- Item Aliases: Items can be referenced by multiple names (e.g., "sword", "blade", "weapon")
- Object Details: All livings (players, NPCs, monsters) and items support "look at X" with descriptions and HP
- Command Shortcuts:
lfor look,n/s/e/w/u/dfor directions - Local Commands: Context-sensitive commands from rooms/items (e.g.,
buy/sellin shops) - Coin System: Stackable coin objects (GC/SC/CC) with auto-merge, shop transactions,
exchangecommand
- .NET SDK 8.0+
JitRealm runs on Windows, Linux, and macOS — anywhere .NET 8 runs.
# Build for current platform
dotnet build
# Publish self-contained for specific platforms
dotnet publish -c Release -r win-x64 --self-contained
dotnet publish -c Release -r linux-x64 --self-contained
dotnet publish -c Release -r osx-x64 --self-contained
dotnet publish -c Release -r osx-arm64 --self-contained # Apple Silicondotnet restore
dotnet run # Single-player console mode
dotnet run -- --server # Multi-player server (port 4000)
dotnet run -- --server --port 23 # Custom portdotnet run # Interactive login prompt
dotnet run -- --player mats # Auto-login as player "mats"
dotnet run -- --player mats --password secret # Auto-login with password
dotnet run -- -u mats -pw secret # Short form| Option | Short | Description |
|---|---|---|
--player <name> |
-u |
Auto-login with specified player name |
--password <pw> |
-pw |
Password for auto-login (skips prompt) |
dotnet run -- --server # Start server on port 4000
dotnet run -- --server --port 23 # Custom port
dotnet run -- -s -p 2323 # Short form| Option | Short | Description |
|---|---|---|
--server |
-s |
Enable multi-player telnet server mode |
--port <num> |
-p |
Server port (default: 4000) |
To connect as a player, use telnet: telnet localhost 4000
look/l— show current roomlook at <target>/l <target>— examine room details, items, NPCs, or playersgo <exit>— move via an exit (triggers IOnLeave/IOnEnter hooks)n/s/e/w/u/d— direction shortcuts (north/south/east/west/up/down)quit/q— disconnect and save player data
get <item>/take <item>— pick up an item from the room (items have aliases, e.g., "sword" or "blade")drop <item>— drop an item to the roominventory/inv/i— list carried items with weightsexamine <item>/exam/x— show item's detailed descriptionread <object>— read signs, books, scrollsscore— show player stats (HP, Level, XP, Wealth)
equip <item>/wield/wear— equip an item from inventoryunequip <slot>/remove— unequip item from a slotequipment/eq— show equipped items with stats
kill <target>/attack— start combat with a targetflee/retreat— attempt to escape combat (50% chance)consider <target>/con— estimate target difficulty
say <message>— speak to the roomshout <message>/yell— shout to adjacent roomswhisper <player> <message>/tell— private messagewho— list online playersemote <action>/me <action>— custom emote (e.g., "emote looks around")bow,wave,laugh,smile,nod,shrug,sigh,cheer,think,cry,dance,yawn— pre-defined emotes
help/?— show command help (wizard commands shown only for wizards)score/sc— show detailed player stats (HP bar, XP, level, wealth)time— show server time and playtimecolors on|off— toggle ANSI color codes for terminal outputexchange <amount> <coin> to <coin>— convert between coin types (e.g.,exchange 1 gold to silver)
get 50 gold/get all copper— pick up specific coin amountsdrop 25 silver— drop specific coin amounts- Coins auto-merge when placed in same container
- Exchange rates: 1 GC = 100 SC = 10000 CC
These commands are visible in help and executable only for wizard users:
blueprints— list loaded blueprintsobjects— list loaded instancesclone <blueprintId>— create a new instance in current roomdestruct <objectId>— remove an instancestat <id>— show blueprint or instance inforeset <objectId>— trigger IResettable.Reset on an objectreload <blueprintId>— recompile and update all instances (preserves state)unload <blueprintId>— unload blueprint and all its instancespatch <objectId> [key] [value]— view or modify object state at runtimegoto <home|room-id>— teleport to home room or any room by IDpwd— print current working directory (within World/)ls [path]— list directory contentscd <path>— change working directorycat <file>— display file with line numbersmore <file> [start] [lines]— display file with pagingedit <file>— nano-style in-game file editor (Ctrl+O save, Ctrl+X exit)ledit <file> [line# [text]]— line-based editor (no ANSI required, see below)perf— show driver loop timings and performance statswhere <id|name|alias>— find where an object is located (aliases: locate, find)trace <npc>— watch NPC AI decisions live (off to stop)create <type> <name> [variant]— scaffold new world objects from templatesforce <npc> <command>— make an NPC execute a commandlink <dir> <room> [--oneway]— link current room to an existing roomunlink <dir> [--both]— remove an exit from the current roomdig <dir> <room> [outdoor] [--oneway]— create a new room and link itsave— save world state tosave/world.json(also auto-saves on shutdown)load— restore world state from save file (also auto-loads on startup)goal <npc> [type [importance] [target]]— view or set NPC goalskb <get|set|search|delete> ...— manage world knowledge basestory <prompt>— generate lore/story text using LLMheal <target> [amount|full]— restore HP to a targetzap <target> [--force]— instantly kill a targetecho [to <room>] <message>— send message to room without attributionmove <object> to <dest>— move object to another containersummon <target>— bring player or NPC to your locationusers— list connected sessionsban <player> [reason]/unban <player>— manage player bansshutdown [delay]— initiate graceful server shutdown
Wizards can navigate the World/ directory using Unix-like commands:
- Root
/=World/ - Paths support
.(current) and..(parent) - Wizards cannot navigate outside
World/
The ledit command provides line-based file editing for terminals without full ANSI support:
ledit <file>— display file with line numbersledit <file> <line#>— show specific lineledit <file> <line#> <text>— replace line with textledit <file> +<line#> <text>— insert text after line (use +0 for beginning)ledit <file> -<line#>— delete lineledit <file> append <text>— append line at end (creates file if needed)
Examples:
ledit start.cs # Show start.cs with line numbers
ledit start.cs 5 # Show line 5
ledit start.cs 5 // comment # Replace line 5 with "// comment"
ledit start.cs +5 new line # Insert "new line" after line 5
ledit start.cs -5 # Delete line 5
ledit start.cs append } # Append "}" at end
The create command scaffolds new world objects from templates in World/templates/:
create room <name>— create indoor room (Rooms/name.cs)create room <name> outdoor— create outdoor room (shows time/weather)create npc <name>— create simple NPC (no AI)create npc <name> llm— create LLM-powered NPC with AI behaviorcreate monster <name>— create simple aggressive monstercreate monster <name> llm— create LLM-powered monster with AIcreate item <name>— create basic stackable itemcreate weapon <name>— create equippable weaponcreate armor <name>— create equippable armor
Templates use placeholders ({{NAME}}, {{CLASS_NAME}}, {{DESCRIPTION}}) that are replaced when creating the file.
These commands manage room connections by editing source files:
dig — Create a new room and link it:
dig north tavern— create Rooms/tavern.cs with bidirectional exitsdig east dungeon/cell1— create in subdirectorydig up tower outdoor— create outdoor room (shows time/weather)dig down basement --oneway— one-way exit only
link — Add exits to existing rooms:
link north Rooms/tavern— bidirectional link (creates exits in both directions)link east Rooms/shop --oneway— one-way exit only
unlink — Remove exits from rooms:
unlink north— remove exit from current room onlyunlink north --both— remove both this exit and the reverse exit
All commands edit room source files directly and trigger hot-reload.
Wizards can have personal home rooms at World/Rooms/Homes/{letter}/{name}/home.cs:
goto hometeleports the wizard to their home room- Example: Wizard "Mats" has home at
World/Rooms/Homes/m/mats/home.cs
For ANSI-capable clients, the server provides readline-style line editing:
- Up/Down arrows: Navigate command history
- Left/Right arrows: Move cursor within line
- Home/End or Ctrl+A/Ctrl+E: Jump to start/end of line
- Ctrl+K: Delete from cursor to end of line
- Ctrl+U: Clear entire line
- Backspace: Delete character before cursor
Edit appsettings.json to customize driver settings:
{
"Server": {
"Port": 4000,
"MaxConnections": 0,
"WelcomeMessage": "Welcome to JitRealm, {PlayerName}!",
"MudName": "JitRealm",
"Version": "0.28"
},
"Paths": {
"WorldDirectory": "World",
"SaveDirectory": "save",
"SaveFileName": "world.json",
"PlayersDirectory": "players",
"StartRoom": "Rooms/start",
"PlayerBlueprint": "std/player"
},
"GameLoop": {
"LoopDelayMs": 50,
"DefaultHeartbeatSeconds": 2,
"AutoSaveEnabled": false,
"AutoSaveIntervalMinutes": 15
},
"Combat": {
"RoundIntervalSeconds": 3,
"FleeChancePercent": 50
},
"Security": {
"HookTimeoutMs": 5000,
"HeartbeatTimeoutMs": 1000
},
"Player": {
"StartingHP": 100,
"CarryCapacity": 100,
"RegenPerHeartbeat": 1,
"XpMultiplier": 1.5,
"BaseXpPerLevel": 100
},
"Memory": {
"Enabled": false,
"ConnectionString": "",
"UsePgvector": true,
"EmbeddingDimensions": 1536,
"MaxWriteQueue": 10000,
"MaxWritesPerSecond": 200,
"CandidateLimit": 500,
"DefaultMemoryTopK": 10,
"DefaultKbTopK": 5
}
}Command-line arguments override config file settings (e.g., --port 23).
- High-level roadmap: docs/ROADMAP.md
- Detailed implementation plan: docs/DRIVER_PLAN.md
MIT — see LICENSE.