Urbit MUD Considerations
Why Urbit for a MUD?
Natural Advantages
Decentralized by default: No single server to maintain, pay for, or become a single point of failure. Each player’s ship IS their game client and can host game state.
Built-in identity:
@paddresses provide unique, persistent, unforgeable player identities. No account system needed — your Urbit IS your account. Identity is tied to reputation and social graph.Persistent state without external DB: Urbit’s noun-based state model persists automatically. A Gall agent’s state survives restarts natively. No need for MySQL, PostgreSQL, or flat file serialization.
Networking is native: Ames provides encrypted, authenticated peer-to-peer communication. No need to manage TCP connections, TLS certificates, or authentication tokens.
Composability: A MUD agent can interact with %groups for chat, %furum for forums/lore, or custom agents for external integrations. The MUD becomes part of the Urbit ecosystem, not an isolated silo.
Self-hosting philosophy: Aligns perfectly with MUD culture — players own their data, their identity, and their experience.
Philosophical Alignment
MUDs and Urbit share DNA:
- Both are text-first, command-driven interfaces
- Both value ownership and persistence
- Both attract communities that prefer depth over polish
- Both are fundamentally about building digital spaces for human connection
Architecture Mapping
MUD Concept → Urbit Primitive
| MUD Concept | Urbit Equivalent | Notes |
|---|---|---|
| Player identity | @p (ship address) | Unique, persistent, cryptographic |
| Player connection | Ames subscription | Encrypted P2P |
| Game server | Gall agent on host ship | Or distributed across ships |
| Game state | Agent state (noun) | Persisted automatically |
| Command input | Poke (from client) | JSON or custom mark |
| Game output | Subscription updates (facts) | Pushed to subscribed clients |
| Game tick/timer | Behn timer | Kernel-level timer service |
| Read-only queries | Scry | Fast, no side effects |
| Chat/channels | %channels or custom | Reuse existing infra |
| World data | Part of agent state or separate agent | Depends on scale |
Gall Agent Structure for a MUD
A Gall agent has exactly ten arms:
|_ =bowl:gall
++ on-init :: startup initialization
++ on-save :: serialize state for upgrade
++ on-load :: deserialize state after upgrade
++ on-poke :: handle incoming commands (player actions!)
++ on-watch :: handle subscription requests (player connects!)
++ on-leave :: handle unsubscription (player disconnects!)
++ on-peek :: handle scry requests (read game state!)
++ on-agent :: handle responses from other agents
++ on-arvo :: handle kernel responses (timers!)
++ on-fail :: handle crash notifications
--
Game loop mapping:
on-poke: Player commands (move north, attack goblin, get sword)on-watch: Player joins game / subscribes to room updateson-leave: Player leaves gameon-peek: Client queries game state (room contents, inventory, stats)on-arvo: Game tick timer fires → process combat rounds, regen, mob AI, resets
Potential Architectures
Option A: Centralized Host Ship
Host Ship (~your-ship)
├── %mud-engine (Gall agent)
│ ├── World state (rooms, mobs, items)
│ ├── Player state (stats, inventory, position)
│ └── Game logic (combat, quests, progression)
│
└── Players connect via Ames subscriptions
├── ~player-one subscribes to room updates
├── ~player-two subscribes to room updates
└── Commands sent as pokes to host
Pros: Simple, consistent state, traditional MUD model Cons: Single point of failure, scaling limits, host bears all compute
Option B: Distributed World
Ship A hosts Continent 1 (areas 1-100)
Ship B hosts Continent 2 (areas 101-200)
Ship C hosts Continent 3 (areas 201-300)
Players:
├── Connect to the ship hosting their current area
├── "Zone transfer" = resubscribe when moving between continents
└── Character state lives on player's own ship
Pros: Scales horizontally, load distribution, area hosts can be different builders Cons: Complex state synchronization, cross-zone interactions (combat, chat), consistency challenges
Option C: Player-Hosted Characters
Each player's ship:
├── %mud-character (local agent)
│ ├── Character stats, inventory, progression
│ └── Local game client / UI
│
World host ship(s):
├── %mud-world (shared agent)
│ ├── Room state, mob state, item spawns
│ └── Validates player actions, resolves combat
│ └── Sends room updates to subscribed players
Pros: Players own their character data, distributes storage, natural backup Cons: Trust issues (how to prevent character stat cheating?), state sync complexity
Recommended Starting Architecture
Start with Option A (centralized host). It maps most directly to traditional MUD architecture and avoids distributed systems complexity while you’re building core gameplay.
Add distribution later — Urbit’s networking makes it relatively straightforward to split the world across ships once the core engine works.
Hoon/Nock Considerations
Data Structures for MUD Concepts
:: Room definition
+$ room
$: id=@ud
name=@t
description=@t
sector=?(%city %forest %mountain %water %underground %indoor)
exits=(map direction @ud) :: direction → room-id
contents=(set item-id)
mobs=(set mob-id)
players=(set @p)
flags=(set room-flag)
==
:: Direction type
+$ direction ?(%north %south %east %west %up %down)
:: Player character
+$ character
$: owner=@p
name=@t
race=race-type
class=class-type
level=@ud
stats=stat-block
hp=@ud
max-hp=@ud
mana=@ud
max-mana=@ud
moves=@ud
max-moves=@ud
inventory=(list item-id)
equipment=(map wear-slot item-id)
position=room-id=@ud
experience=@ud
gold=@ud
==
:: Stat block
+$ stat-block
$: str=@ud int=@ud wis=@ud
dex=@ud con=@ud luck=@ud
==
Performance Considerations
Potential issues:
- Game tick frequency: Behn timers have kernel-level overhead. Sub-second ticks may stress Arvo. Target 1-4 second ticks (standard for MUDs).
- State size: Large world state (300+ areas × rooms × mobs × items) as a single noun could be unwieldy. Consider lazy loading or area segmentation.
- Combat resolution: Per-round calculations are lightweight individually but multiply with concurrent fights.
- Parser overhead: Command parsing in Hoon is natural (pattern matching on text) but complex natural-language parsing could be expensive.
Mitigations:
- Keep game ticks at 2-4 second intervals (totally fine for MUDs)
- Segment world state by area for efficient updates
- Use scry for read-only operations (no state mutation overhead)
- Pre-compute combat tables rather than calculating per-hit
- Use threads for expensive operations (pathfinding, area resets)
Hoon Strengths for MUDs
- Pattern matching: Excellent for command parsing
- Immutable state: No race conditions in game logic
- Type system: Catches bugs at compile time (invalid room references, etc.)
- Persistent state: Agent state survives restarts without explicit save/load
- Kelvin versioning: Core stability guarantees
Hoon Challenges for MUDs
- Learning curve: Hoon is… Hoon. Builders/scripters won’t learn it casually
- String handling: Text manipulation in Hoon is verbose compared to Python/Lua
- Performance ceiling: Nock is not fast for compute-heavy operations
- Debugging: Hoon stack traces are legendary for their opacity
- Hot reloading: Updating a running agent requires careful state migration
Frontend Approaches
Option 1: Web UI (Recommended Starting Point)
React/Sail frontend served by the ship’s HTTP server:
- Rich HTML/CSS interface: room display, sidebar stats, clickable commands
- WebSocket connection via Eyre for real-time updates
- Can embed mapping, inventory management, equipment panels
- Mobile-friendly
- Reference: %groups and %furum both use this pattern
Option 2: Terminal Client
A terminal-based interface that connects to the ship:
- Traditional MUD feel
- Could use
%shoelibrary for terminal agent interaction - ANSI colors, text formatting
- Familiar to MUD veterans
- Lower barrier to entry for Urbit users already in the terminal
Option 3: Telnet Bridge
Bridge traditional MUD clients (Mudlet, TinTin++) to Urbit:
- Separate process: TCP telnet server ↔ Urbit pokes/subscriptions
- Could implement GMCP, ANSI, etc. for full client compatibility
- Lets existing MUD players connect without Urbit knowledge
- Most complex option but widest reach
Option 4: Hybrid
Web UI as primary + telnet bridge for traditional clients. This is the ideal end state but not where you should start.
Integration Opportunities
With Existing Urbit Apps
- %groups/%channels: Use for OOC communication, clan chat, game announcements
- %furum: Game forums, lore posting, area guides, player-generated content
- %pals: Social graph for friend lists, group-finding
- Custom agents: Weather systems, economy simulators, world events
With External Systems
- poke-remote-agent MCP tool: You already built this! Could enable external services to interact with the MUD (posting achievements, triggering events)
- RSS feeds: Game news, update logs
- Discord/Telegram bridges: Cross-platform communication for the community
Challenges and Risks
Technical Risks
| Risk | Severity | Mitigation |
|---|---|---|
| State size growth | Medium | Area segmentation, pruning old data |
| Tick performance | Low-Medium | 2-4 sec ticks are fine; profile early |
| Player capacity | Medium | Start small, architect for distribution |
| Latency (Ames) | Low | P2P latency is fine for turn-based MUD combat |
| Kelvin versioning | Low | MUD state is application-level, survives kernel updates |
| Builder tooling | High | Hoon is hard; may need simplified building interface |
| Hot updates | Medium | State migration between agent versions needs care |
Community Risks
- Small initial player base (Urbit users who want to play a MUD)
- Need content creators willing to write area descriptions
- Ongoing maintenance/development commitment
Design Risks
- Trying to build too much at once
- Over-engineering distributed architecture before basic gameplay works
- Underestimating content needs (a MUD needs LOTS of rooms and areas)
Recommended MVP Scope
Phase 1: Core Engine
- Single host ship
- Room navigation (move between rooms, look, exits)
- Basic combat (auto-attack + a few skills)
- Character creation (race, class, stats)
- Leveling (kill mobs → gain XP → level up)
- Simple web UI (room description, compass, status bar)
Phase 2: Depth
- Equipment system (wear, wield, inventory)
- Multiple areas with level ranges
- NPC shops
- Basic quest system
- Communication channels (say, tell, gossip)
- ANSI color in descriptions
Phase 3: Social
- Clan system
- Player housing (manor)
- Helper channel / new player experience
- Player trading
Phase 4: Scale
- Distribute world across multiple ships
- Builder tools (in-game or web-based area editor)
- Scripting system for dynamic mob behavior
- GMCP protocol support for traditional client compatibility