A modern MUD (Multi-User Dungeon) driver inspired by LDMud, built with Node.js and TypeScript.
MudForge brings the architectural elegance of classic LPMud drivers into the modern era. It replaces the traditional LPC scripting language with TypeScript, enables real-time in-game scripting without server restarts, and provides browser-based connectivity via WebSocket.
- TypeScript Scripting - Write game content in TypeScript with full IDE support, type safety, and modern syntax
- Runtime Hot-Reload - Create and modify objects while the game is running without server restarts
- Modern Web Client - Clean, Linear.app-inspired browser interface with dark theme and 256-color support
- Graphical Stats Panel - Floating, draggable HP/MP/XP/gold bars with real-time updates
- Interactive Map Panel - Floating, resizable map showing explored areas
- LDMud-Inspired Architecture - Everything is an object with consistent inheritance hierarchy
- Multi-Guild System - Join up to 3 guilds with skill trees, guild XP, and progression (Fighter, Mage, Thief, Cleric)
- Quest System - MMO-style quests with kill, fetch, deliver, escort, explore, and talk objectives
- Buffs & Debuffs - Temporary stat modifiers with stacking, duration, and visual indicators
- Combat System - Real-time combat with NPCs, death/resurrection, corpse looting, and wimpy auto-flee
- Gold Economy - Currency system with carrying gold, banking, giving, and dropping
- Tiered Permission System - Player, Builder, Senior Builder, and Administrator roles
- Equipment System - Weapons, armor, and shields with slot management and dual-wielding
- Container System - Chests, bags, and lockable containers
- NPC System - NPCs with combat AI, loot drops, autonomous behavior, quest giving, and training
- AI-Powered NPCs - NPCs with dynamic, contextual dialogue powered by Claude AI
- AI Content Generation - Generate room descriptions, NPC definitions, and items with AI builder commands
- World Lore System - Central lore registry that NPCs reference for consistent, immersive dialogue
- Communication Channels - OOC, shout, tell, guild channels, and extensible channel system
- Command Aliases - Player-defined command shortcuts and macro sequences
- Session Reconnection - Seamlessly reconnect to existing game sessions after disconnection
- Link-Dead Handling - Disconnected players fade to a holding area and auto-quit after configurable timeout
- GUI Modal System - Rich client-side dialogs for complex interactions
- Memory Management - Automatic object cleanup and garbage collection
- Mud-Wide Configuration - Persistent ConfigDaemon for game-wide settings adjustable by admins
- File-Based Persistence - Human-readable TypeScript/JSON files that work with version control
Modern dark-themed login interface
Character score with stats, equipment, and guild information
Visual inventory management with item details
Interactive shop interface for buying and selling
Character creation with race selection
Quest tracking with objectives and rewards
Multi-guild system with skill progression
Companion pets that follow and assist players
Hire mercenaries to aid in combat
Rideable vehicles and ferry transportation
Interactive ferry schedule and boarding
Visual area builder for creating game content
Admin snooping for monitoring player activity
Configurable NPC behavior system
Full emoji support in chat and descriptions
Inline GIF support via Giphy integration
In-game sound effects and ambient audio
Following LDMud's proven architecture, MudForge embraces the principle that everything is an object:
- Consistency - All objects respond to the same base protocols
- Flexibility - Any object can be extended, cloned, or replaced at runtime
- Discoverability - Builders learn one object model that applies everywhere
- Hot-reloading - Objects can be updated without restarting the driver
+-----------------------------------------------------------------+
| Web Browser |
| +-----------------------------------------------------------+ |
| | Modern Web Client (Linear.app-inspired) | |
| +-----------------------------------------------------------+ |
+-----------------------------------------------------------------+
| WebSocket
v
+-----------------------------------------------------------------+
| MUD Driver (Node.js) |
| +-------------+ +-------------+ +-------------+ |
| | Connection | | Object | | Scheduler | |
| | Manager | | Registry | | (heartbeat) | |
| +-------------+ +-------------+ +-------------+ |
| +-----------------------------------------------------------+ |
| | Mudlib Execution Context | |
| | +---------+ +-------------+ +---------------+ | |
| | | Master | | Sim Efuns | | Object Pool | | |
| | +---------+ +-------------+ +---------------+ | |
| +-----------------------------------------------------------+ |
+-----------------------------------------------------------------+
|
v
+-----------------------------------------------------------------+
| File System (Mudlib) |
| /mudlib/ |
| +-- master.ts # Master object |
| +-- efuns.d.ts # Global efun type declarations |
| +-- std/ # Standard library |
| | +-- room.ts, living.ts, player.ts, item.ts, ... |
| | +-- weapon.ts, armor.ts, container.ts, npc.ts |
| +-- areas/ # Game world content |
| +-- data/ # Persistent state (JSON) |
+-----------------------------------------------------------------+
MudObject # Root of all objects
+-- Master # World bootstrap, global hooks
+-- Room # Locations
+-- Item # Carryable objects
| +-- Weapon # Melee/ranged weapons with handedness
| +-- Armor # Body slot armor and shields
| +-- Container # Chests, bags (openable, lockable)
| | +-- Corpse # Dead creatures (lootable)
| +-- GoldPile # Dropped gold coins
+-- Living # Entities that can act
| +-- Player # Human players with equipment, guilds, quests
| +-- NPC # Computer-controlled characters
| | +-- Trainer # NPCs that train stats/levels
| | +-- GuildMaster # NPCs that manage guild membership
+-- Daemon # Background services
+-- GuildDaemon # Guild and skill management
+-- QuestDaemon # Quest registration and tracking
+-- CombatDaemon # Combat resolution
+-- ChannelDaemon # Communication channels
+-- SoulDaemon # Emote management
+-- ResetDaemon # Periodic room resets
+-- ConfigDaemon # Game-wide configuration
+-- LoreDaemon # World lore registry for AI
| Component | Technology |
|---|---|
| Runtime | Node.js 22+ LTS |
| Language | TypeScript 5.x |
| WebSocket | ws |
| Web Server | Fastify |
| Compilation | tsx (runtime), esbuild (client) |
| Testing | Vitest |
- Node.js 20+ (LTS recommended)
- npm (comes with Node.js)
# Clone the repository
git clone https://github.com/jasona/mudforge.git
cd mudforge
# Install dependencies
npm install
# Copy environment configuration (optional - defaults work fine)
cp .env.example .env# Development mode (with hot-reload and auto-restart)
npm run dev
# Or for production
npm run build
npm startYou should see output like:
[INFO] MudForge Driver starting...
[INFO] Loading mudlib from ./mudlib
[INFO] WebSocket server listening on http://localhost:3000
-
Open your web browser and go to:
http://localhost:3000 -
The web client loads automatically - you'll see a modern dark-themed terminal interface
-
Create a new character or log in:
- Enter a character name when prompted
- If the name is new, you'll be guided through character creation
- If returning, enter your password
That's it! You're now connected to the MUD.
| Setting | Default | Description |
|---|---|---|
| Port | 3000 |
HTTP/WebSocket server port |
| Host | 0.0.0.0 |
Bind address (all interfaces) |
| Mudlib Path | ./mudlib |
Game content directory |
To change these, edit .env or set environment variables:
PORT=8080 npm run devnpm run dev # Start with hot-reload (recommended for development)
npm run build # Compile TypeScript to JavaScript
npm start # Run compiled production build
npm test # Run test suite
npm run lint # Check code style
npm run typecheck # TypeScript type checkingsrc/
+-- driver/ # Core driver implementation
| +-- driver.ts # Main orchestrator
| +-- object-registry.ts # Object management
| +-- scheduler.ts # Heartbeat and call_out
| +-- efun-bridge.ts # Efuns exposed to mudlib
| +-- command-manager.ts # Command routing with hot-reload
| +-- permissions.ts # Permission system
| +-- persistence/ # Save/load system
+-- network/ # WebSocket server
+-- client/ # Web client UI (Linear.app-inspired)
mudlib/
+-- master.ts # Master object
+-- simul_efun.ts # Simulated efuns
+-- efuns.d.ts # Global efun type declarations
+-- tsconfig.json # Mudlib TypeScript config
+-- std/ # Standard library
| +-- object.ts, room.ts, living.ts, player.ts
| +-- item.ts, weapon.ts, armor.ts, container.ts
| +-- npc.ts, equipment.ts, trainer.ts
| +-- combat/ # Combat system types and utilities
| +-- guild/ # Guild system types and definitions
| +-- quest/ # Quest system types and definitions
+-- daemons/ # Background services
| +-- login.ts, channels.ts, combat.ts, config.ts
| +-- guild.ts, quest.ts, soul.ts, reset.ts
+-- cmds/ # Player commands
| +-- player/ # Commands for all players
| +-- builder/ # Builder-only commands
| +-- admin/ # Admin-only commands
+-- areas/ # Game world
| +-- valdoria/ # Valdoria continent
| +-- guilds/ # Guild halls
+-- data/ # Persistent state
+-- lib/ # Utility libraries
docs/ # Documentation
tests/ # Test suite
get sword # Pick up an item
get all # Pick up all items
get sword from chest # Get item from container
get gold # Pick up gold coins
drop sword # Drop an item
drop sword in chest # Put item in container
drop gold # Drop all your gold
drop 50 gold # Drop specific amount
give sword to bob # Give item to player/NPC
give 100 gold to bob # Give gold to someone
open chest # Open a container
close chest # Close a container
look in chest # See container contents
wield sword # Wield a weapon
wield dagger in left # Dual-wield (off-hand)
unwield # Unwield all weapons
wear armor # Wear armor
remove armor # Remove armor
equipment # View all equipped items
kill goblin # Attack an NPC
flee # Attempt to escape combat
consider goblin # Assess NPC difficulty
wimpy 20 # Auto-flee at 20% health
When defeated, players become ghosts and can resurrect at the resurrection point. Your corpse remains at the death location with your carried gold - return to loot it!
Join up to 3 guilds simultaneously and learn unique skills:
guild list # See all available guilds
guild info fighter # Learn about a specific guild
guild join fighter # Join a guild (must meet requirements)
guild leave fighter # Leave a guild
skills # View your learned skills
skill use bash goblin # Use an active skill
bash goblin # Shorthand for learned skills
advance # See advancement options
advance fighter # Advance guild level (costs guild XP)
advance bash # Advance skill level (costs player XP)
Starter Guilds: Fighter (melee combat), Mage (arcane magic), Thief (stealth & precision), Cleric (healing & divine power)
Accept and complete quests for XP, gold, and quest points:
quest # Show active quests
quest log # Full quest log with progress
quest info <name> # Detailed quest information
quest accept # See available quests from nearby NPCs
quest accept <name> # Accept a specific quest
quest abandon <name> # Abandon an active quest
quest turn-in <name> # Turn in a completed quest
quest history # View completed quests
quest points # Check quest point balance
Quest types include: kill targets, collect items, deliver packages, escort NPCs, explore locations, and talk to characters.
Temporary effects that modify your stats:
buffs # View active buffs and debuffs
Effects can come from skills, potions, equipment, or environmental sources. Multiple effects of the same type stack, and durations are tracked automatically.
score # See your gold (carried and banked)
get gold from corpse # Loot gold from defeated enemies
drop 100 gold # Drop gold on the ground
give 50 gold to merchant # Give gold to NPCs/players
Banks in towns allow you to safely store gold that won't be lost on death.
Players can create colorful, personalized display names:
displayname Sir {blue}$N{/} the {green}Bold{/}
- Use
$Nas a placeholder for your actual name - Use color codes like
{red},{blue},{green},{bold},{/}(reset) - Display names appear in room descriptions and the who list
say <message> # Talk to players in the same room
tell <player> <message> # Private message to a player
reply <message> # Reply to last tell
shout <message> # Broadcast to all players
ooc <message> # Out-of-character chat channel
fighter <message> # Guild channel (if member)
emote <action> # Perform an emote
emote smile at bob # Target someone with an emote
remote bob wave # Emote at someone in another room
Create shortcuts for frequently used commands:
alias # View all aliases
alias k kill # Create alias 'k' for 'kill'
alias atk kill $* # Alias with arguments
unalias k # Remove an alias
do n;n;e;get sword # Execute multiple commands
If you disconnect unexpectedly:
- Your character's form "fades from view" and is moved to a holding area
- Other players in the room see a message about your departure
- You have a configurable timeout (default 15 minutes) to reconnect
- When you reconnect, you "shimmer back into existence" at your original location
- If you don't reconnect in time, your character is automatically saved and logged out
Simply reconnect and log back in to resume your session.
| Role | Capabilities |
|---|---|
| Player | Connect, play the game, customize display name, manage personal settings |
| Builder | Create/modify objects in assigned domains, goto (players or rooms), file commands |
| Senior Builder | Cross-domain building, advanced APIs |
| Administrator | Full access, permission management, mud-wide config, reload objects |
// /mudlib/areas/town/tavern.ts
import { Room } from '../../std/room.js';
export class Tavern extends Room {
constructor() {
super();
this.shortDesc = 'The Rusty Tankard';
this.longDesc = `You stand in a cozy tavern. A fire crackles in the hearth,
and the smell of roasting meat fills the air.`;
}
override async onCreate(): Promise<void> {
await super.onCreate();
this.addExit('south', '/areas/town/market');
this.addAction('order', this.handleOrder.bind(this));
}
private handleOrder(args: string): boolean {
const player = efuns.thisPlayer();
if (!player) return false;
efuns.send(player, 'The bartender pours you a frothy ale.');
return true;
}
}// /mudlib/areas/town/town_crier.ts
import { NPC } from '../../std/npc.js';
export class TownCrier extends NPC {
constructor() {
super();
this.setNPC({
name: 'town crier',
shortDesc: 'the town crier',
longDesc: 'A stout man in a faded blue coat with a brass bell.',
chatChance: 15, // 15% chance per heartbeat to chat
});
// Periodic announcements
this.addChat('Hear ye, hear ye! The castle seeks adventurers!', 'say');
this.addChat('rings his brass bell loudly.', 'emote');
// Fallback response triggers (when AI unavailable)
this.addResponse(/hello|hi/i, 'Good day to you, traveler!', 'say');
this.addResponse(/news/i, 'The castle has posted new bounties!', 'say');
// Enable AI-powered dialogue
this.setAIContext({
name: 'Bartleby the Town Crier',
personality: 'Jovial and theatrical, loves sharing news and gossip.',
background: 'Has served as town crier for 20 years.',
knowledgeScope: {
topics: ['local news', 'town layout', 'merchants'],
worldLore: ['region:valdoria', 'economics:trade-routes'],
},
speakingStyle: { formality: 'casual', verbosity: 'verbose' },
});
}
}MudForge provides global type declarations for all efuns via mudlib/efuns.d.ts. This means you don't need to declare efuns at the top of every file - they're automatically available:
// No need for "declare const efuns" - it's globally available!
export class MyRoom extends Room {
async onCreate(): Promise<void> {
const sword = await efuns.cloneObject('/std/sword');
await sword?.moveTo(this);
}
}Detailed documentation is available in the /docs directory:
- Architecture - System design and components
- Mudlib Guide - Creating game content
- Efuns Reference - Driver API functions
- Commands - Command reference
- Player Features - Display names, channels, who list
- Guilds - Multi-guild system with skills and progression
- Quests - Quest system with objectives and rewards
- Buffs & Debuffs - Temporary stat modifiers
- Colors - Color codes and 256-color support
- Daemons - Background services
- AI Integration - AI-powered NPC dialogue and content generation
- Lore System - World lore registry for consistent AI context
- Permissions - Permission system
- Web Client - Browser client documentation
- GUI Modals - Rich client-side dialogs
- Memory Management - Object cleanup system
- Deployment - Production deployment
docker build -t mudforge .
docker run -p 3000:3000 mudforgepm2 start ecosystem.config.jsJoin the MudForge community:
- Discord: https://discord.gg/GEBatdTCYZ - Chat with developers and other MUD builders
- GitHub Issues: Report bugs or request features
This project is under active development. See tasks/tasks-modern-mud-driver.md for the implementation roadmap.
MudForge draws inspiration from:
- LDMud - The classic LPMud driver
MIT

















