MUD on Urbit

Instanced Areas

design

Status: Design Date: 2026-04-02

Instanced areas are dynamically generated solo dungeons. A designer defines a template — room themes, mob pools, item pools, difficulty tiers — and the system generates a unique instance for each player who enters. Instances are temporary, self-contained, and destroyed when the player leaves or goes idle.

Entry

A designer places a normal room in their area JSON with an instance field pointing at a template ID:

{
  "id": 45,
  "name": "Mouth of the Warren",
  "description": "A fissure in the cliff face exhales warm, foul air. Scratching sounds echo from within.",
  "sector": "cave",
  "exits": {"south": 44},
  "flags": [],
  "hooks": [],
  "instance": 100
}

When a player enters this room, they see the room description plus the difficulty choices from the template. Each choice is rendered as a selectable option (same UI as NPC dialogue responses). The player picks one, the system generates their instance, and they’re moved into room 0.

The enter command is not needed — the choices appear automatically on arrival, like hook messages. The player can also leave the entry room without entering the instance.

Instance Template

Instance templates live in the area JSON alongside mob, item, and NPC templates.

{
  "type": "instance-template",
  "id": 100,
  "name": "Goblin Warren",
  "min-level": 8,
  "room-count": [5, 12],
  "topology": "branching",
  "difficulties": [
    {
      "label": "A narrow crack in the wall, echoing with distant chittering",
      "mob-level-offset": -3,
      "reward-multiplier": 0.75
    },
    {
      "label": "A jagged tunnel descending into darkness",
      "mob-level-offset": 0,
      "reward-multiplier": 1.0
    },
    {
      "label": "A reeking pit. Something large moves below.",
      "mob-level-offset": 5,
      "reward-multiplier": 1.5
    }
  ],
  "room-themes": [
    {
      "name": "tunnel",
      "descriptions": [
        "A damp tunnel stretches ahead, water dripping from the low ceiling.",
        "The passage narrows, forcing you to duck beneath jagged stone."
      ]
    },
    {
      "name": "cavern",
      "descriptions": [
        "A wide cavern opens up, its far walls lost in shadow.",
        "Stalactites drip from above, forming pale columns where they meet the floor."
      ]
    },
    {
      "name": "lair",
      "descriptions": [
        "Bones litter the floor. Something has been feeding here."
      ]
    }
  ],
  "mob-pool": [
    {"template-id": 30, "weight": 3, "description-override": null},
    {"template-id": 31, "weight": 2, "description-override": "A goblin shaman mutters over a crude altar"},
    {"template-id": 32, "weight": 1, "description-override": null}
  ],
  "boss": {
    "template-id": 33,
    "description-override": "The warren chief towers over its kin, a jagged blade in each hand",
    "guaranteed": true
  },
  "npc-pool": [
    {"template-id": 10, "chance": 0.3, "description-override": "A half-starved prisoner rattles their chains"}
  ],
  "item-pool": [
    {"template-id": 50, "weight": 3},
    {"template-id": 51, "weight": 1}
  ],
  "completion-rewards": {
    "xp-bonus": 200,
    "gold-bonus": 100,
    "item-id": 55
  }
}

Template Fields

FieldTypeDescription
idnumberUnique template ID, referenced by entry rooms
namestringInstance name, shown in UI
min-levelnumberMinimum player level to enter
room-count[min, max]Range of rooms to generate
topologystring"branching" (tree structure with dead ends and a final boss room)
difficultiesarrayPlayer-facing choices with scaling parameters
room-themesarrayNamed themes with description pools
mob-poolarrayWeighted mob selection
bossobjectBoss mob for the final room
npc-poolarrayOptional NPCs placed with a probability
item-poolarrayWeighted item drops distributed across rooms
completion-rewardsobjectBonus rewards on boss kill

Difficulty Scaling

Each difficulty tier specifies:

  • mob-level-offset: Added to the player’s level to determine mob stats. A level 10 player picking offset -3 fights level 7 mobs. Offset +5 fights level 15 mobs.
  • reward-multiplier: Scales gold drops and XP gains from mobs within the instance. The completion reward is also multiplied.

The designer writes the labels as narrative descriptions. The player never sees numbers — they pick based on flavor text.

Generation

When a player selects a difficulty, the system:

  1. Picks room count — random integer in [min, max] range.
  2. Generates topology — branching tree. Room 0 is the entrance (connected back to the entry room). The tree branches 1-3 ways at each node. The deepest leaf is the boss room.
  3. Assigns themes — each room gets a random theme from room-themes. The boss room always uses the "lair" theme if one exists. A random description is picked from the theme’s pool.
  4. Places mobs — each non-boss room has a chance of containing 1-2 mobs drawn from mob-pool by weight. Mob stats (HP, damage, XP value, gold drop) are scaled to player-level + mob-level-offset. The boss room gets the boss mob, also scaled.
  5. Places NPCs — each room rolls against chance for each NPC in npc-pool. NPCs in instances are non-combat (quest flavor, lore, hints).
  6. Distributes items — items from item-pool are placed in random rooms as ground loot, drawn by weight. Total item count scales with room count (roughly 1 item per 3 rooms). All items created in instances are %protected binding.
  7. Creates exits — rooms are connected per the generated tree. Exit labels use cardinal directions assigned based on tree structure. Dead ends have only one exit back.

Room Keying

Instance rooms are keyed as instance-{instance-id}-{room-number} where:

  • instance-id is a unique @uv generated at creation time
  • room-number is the position in the generated tree (0 = entrance)

Example: instance-0v1a.bc3de-1, instance-0v1a.bc3de-2

These keys exist only in the instance state, not in the world’s persistent room map.

Instance State

instance-state:
  id: @uv
  owner: session-id
  template-id: @ud
  difficulty: @ud              :: index into difficulties array
  entry-room: room-id          :: the persistent room to return to
  rooms: (map @ud instance-room)
  mobs: (map mob-instance-id mob-instance)
  items: (map item-instance-id item-instance)
  boss-defeated: ?
  created: @da
  last-activity: @da

The agent state gains:

instances: (map @uv instance-state)
player-instance: (map session-id @uv)   :: which instance a player is in

Lifecycle

Creation

Player arrives at entry room → sees difficulty choices → selects one → instance generated → player moved to room 0.

Gameplay

  • Player moves between instance rooms normally (north, south, etc.)
  • Combat works identically to the persistent world
  • Items picked up are %protected binding
  • No other players can enter (solo only)
  • The instance does not appear on the world map

Completion

Boss kill triggers completion:

  • Completion rewards (XP, gold, item) given to the player, scaled by reward-multiplier
  • A message indicates the instance is collapsing
  • Player is teleported back to the entry room after a brief delay
  • Instance is destroyed

Death

  • Player dies → normal death flow (corpse, teleport home)
  • Instance is destroyed immediately
  • Corpse items are lost (the instance rooms no longer exist)
  • This is the risk/reward tradeoff: higher difficulty = better rewards but you lose everything on death

Disconnect

  • Player DCs → instance persists for 5 minutes
  • If the player reconnects within 5 minutes, they resume in the instance
  • After 5 minutes idle, the instance is destroyed
  • On reconnect after destruction, player is placed at the entry room

Cleanup

The regen tick checks last-activity on all instances. Any instance idle for 5+ minutes is destroyed. This prevents instance leaks from crashes or ungraceful disconnects.

Commands

No new commands needed. The player interacts with instances through:

  • Difficulty selection — rendered as clickable choices in the entry room (same as NPC dialogue)
  • Movement — standard direction commands within the instance
  • Combat — standard attack/kill/cast commands
  • recall — exits the instance, returns to entry room, instance destroyed (voluntary exit)

Restrictions

  • Solo only. One player per instance. Group instances are a future extension.
  • No portal access. Players cannot use portals or recall to another world from inside an instance. recall exits the instance.
  • No instance stacking. A player can only be in one instance at a time.
  • Level gated. Player must meet min-level to see difficulty choices. Below minimum, they see a message like “You are not experienced enough to venture within.”
  • No saving. Instance progress is not saved. If you leave, it’s gone.
  • No summoning. Other players cannot be summoned into an instance. Admin goto works for debugging.

Frontend

The entry room renders difficulty choices as large buttons (same component as NPC dialogue responses). Each button shows the difficulty label text.

While inside an instance, the UI shows:

  • Instance name in the room header (e.g., “Goblin Warren — Room 3”)
  • A “Leave Instance” button or reminder that recall exits
  • The map panel shows only instance rooms (disconnected from the world map)

Impact on Existing Systems

SystemChange
Room lookupCheck player-instance first; if set, look up room in instance state instead of world rooms
MovementIf in instance, resolve exits from instance room data
CombatNo changes — mob instances work the same way
DeathDestroy instance on player death
Regen tickAdd instance idle check to combined scan
recallIf in instance, exit instance instead of normal recall
Admin gotoAllow entering instances for debugging
Map panelRender instance rooms as isolated graph when player is in one
Save/loadInstances are ephemeral — not persisted across agent restarts