Instanced Areas
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
| Field | Type | Description |
|---|---|---|
id | number | Unique template ID, referenced by entry rooms |
name | string | Instance name, shown in UI |
min-level | number | Minimum player level to enter |
room-count | [min, max] | Range of rooms to generate |
topology | string | "branching" (tree structure with dead ends and a final boss room) |
difficulties | array | Player-facing choices with scaling parameters |
room-themes | array | Named themes with description pools |
mob-pool | array | Weighted mob selection |
boss | object | Boss mob for the final room |
npc-pool | array | Optional NPCs placed with a probability |
item-pool | array | Weighted item drops distributed across rooms |
completion-rewards | object | Bonus 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:
- Picks room count — random integer in
[min, max]range. - 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.
- 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. - Places mobs — each non-boss room has a chance of containing 1-2 mobs drawn from
mob-poolby weight. Mob stats (HP, damage, XP value, gold drop) are scaled toplayer-level + mob-level-offset. The boss room gets thebossmob, also scaled. - Places NPCs — each room rolls against
chancefor each NPC innpc-pool. NPCs in instances are non-combat (quest flavor, lore, hints). - Distributes items — items from
item-poolare 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%protectedbinding. - 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-idis a unique@uvgenerated at creation timeroom-numberis 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
%protectedbinding - 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
recallto another world from inside an instance.recallexits the instance. - No instance stacking. A player can only be in one instance at a time.
- Level gated. Player must meet
min-levelto 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
gotoworks 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
recallexits - The map panel shows only instance rooms (disconnected from the world map)
Impact on Existing Systems
| System | Change |
|---|---|
| Room lookup | Check player-instance first; if set, look up room in instance state instead of world rooms |
| Movement | If in instance, resolve exits from instance room data |
| Combat | No changes — mob instances work the same way |
| Death | Destroy instance on player death |
| Regen tick | Add instance idle check to combined scan |
recall | If in instance, exit instance instead of normal recall |
Admin goto | Allow entering instances for debugging |
| Map panel | Render instance rooms as isolated graph when player is in one |
| Save/load | Instances are ephemeral — not persisted across agent restarts |