room
npx skills add https://github.com/simhacker/moollm --skill room
Agent 安装分布
Skill 文档
Room
Rooms are intertwingled navigable activation context maps. Entering = calling. Exiting = returning.
Directories as cognitive spaces where cards come to life.
The Metaphor
| Filesystem | Simulation | Programming |
|---|---|---|
| Directory | Room | Stack frame |
cd room/ |
Enter | Function call |
cd .. |
Exit | Return |
| Files in dir | Active entities | Local variables |
| Links | Exits/doors | Calls to other functions |
Room Anatomy
room-name/
âââ ROOM.yml # Room definition (REQUIRED!)
âââ README.md # Room's voice (optional)
âââ CARD.yml # Card sidecar (optional)
âââ character-*.yml # NPCs embedded in room
âââ object-*.yml # Objects in room
âââ inbox/ # Objects thrown INTO this room
âââ outbox/ # Objects staged to throw OUT
âââ region/ # Sub-region of this room
â âââ ROOM.yml # Region must also declare itself!
âââ nested-room/ # Full sub-room (different location)
âââ ROOM.yml
Regions vs Sub-Rooms
What’s a Region?
A region is a sub-directory that represents a portion of the same room â like the stage area of the pub, or the back corner of a library.
# pub/ROOM.yml
room:
name: "The Rusty Lantern Pub"
# Regions are PARTS of this room
regions:
stage:
path: "stage/"
description: "The performance stage"
visibility: public
back-room:
path: "back-room/"
description: "Private back room"
visibility: private
requires: "bartender approval"
bar:
path: "bar/"
description: "The bar counter area"
Regions Have Rules
Each region can have its own:
# pub/back-room/ROOM.yml
room:
name: "Back Room"
type: region # Marks as region, not full room
parent: "../" # Part of parent room
# Access control
access:
visibility: private # Not visible to everyone
requires: "bartender approval OR staff badge"
who_allowed:
- "characters/staff/*"
- "player if has_flag('vip_access')"
who_denied:
- "characters/troublemakers/*"
# Ethics & behavior
rules:
- "No recording"
- "Confidential conversations"
- "Staff only by default"
# Privacy
privacy:
eavesdropping: false # Can't hear from outside
visible_from_parent: false # Can't see inside from pub
# What happens in the back room...
narrative:
on_enter: "The door closes behind you with a soft click."
on_exit: "You return to the bustling pub."
Visibility Types
| Type | Description |
|---|---|
public |
Anyone can see and enter |
visible |
Can see but may need permission to enter |
private |
Hidden unless you know about it |
secret |
Hidden AND requires discovery |
Region vs Full Sub-Room
| Feature | Region | Sub-Room |
|---|---|---|
| Part of parent? | Yes | No |
| Own identity? | Partial | Full |
| Exit returns to? | Parent | Varies |
| Shares parent context? | Yes | No |
| Type field | type: region |
type: room |
Directory Type Declaration
The Rule
Every directory in an adventure MUST declare what it is.
| Directory Type | Declaration File |
|---|---|
| Room | ROOM.yml |
| Region | ROOM.yml (with type: region) |
| Character | CHARACTER.yml |
| Adventure root | ADVENTURE.yml |
| Personas | ROOM.yml (with type: personas) |
| Storage | ROOM.yml (with type: storage) |
Lint Error: Undeclared Directory
# LINT ERROR: Directory without type declaration
- type: MISSING_TYPE_DECLARATION
severity: WARNING
path: "pub/mysterious-corner/"
message: "Directory has no ROOM.yml, CHARACTER.yml, or other type declaration"
suggestion: "Add ROOM.yml with appropriate type field"
Valid Non-Room Directories
Some directories aren’t rooms and that’s OK:
# These don't need ROOM.yml:
messages/ # Mail storage (system)
inbox/ # Postal inbox (system)
outbox/ # Postal outbox (system)
sessions/ # Session logs (meta)
images/ # Asset storage (meta)
Marking System Directories
# Alternative: mark as system directory
# pub/messages/.meta.yml
meta:
type: system
purpose: "Mail storage for pub"
requires_room_yml: false
Container Directories (Inheritance Scopes)
Some directories are inheritance containers â they provide shared properties to child rooms without being navigable themselves. Like OpenLaszlo’s <node> element.
# maze/CONTAINER.yml â Not a room, but defines inherited properties
container:
name: "The Twisty Maze"
description: "Groups maze rooms with shared grue rules"
inherits:
is_dark: true
is_dangerous: true
grue_rules:
can_appear: true
ambient:
sound: "dripping water"
light_level: 0
All child rooms (room-a/, room-b/, etc.) automatically inherit these properties!
Alternatively, you can make the container into an actual room:
# maze/ROOM.yml â The maze entrance IS a room
room:
name: "Maze Entrance"
description: "Dark passages branch off in every direction..."
exits:
a: room-a/
b: room-b/
# ... etc
DESIGN CHOICE:
- Use
CONTAINER.ymlif you want inheritance without navigation (see container skill) - Use
ROOM.ymlif you want the directory to be a navigable space
Hierarchy Example
adventure-4/
âââ ADVENTURE.yml # Adventure declaration
âââ pub/
â âââ ROOM.yml # Room declaration
â âââ stage/
â â âââ ROOM.yml # Region (type: region)
â âââ bar/
â â âââ ROOM.yml # Region
â âââ back-room/
â â âââ ROOM.yml # Private region
â âââ messages/
â âââ .meta.yml # System directory (no ROOM.yml needed)
âââ characters/
â âââ ROOM.yml # Hall of characters (type: personas)
â âââ don-hopkins/
â âââ CHARACTER.yml # Character declaration
âââ maze/
âââ ROOM.yml # Room declaration
âââ room-a/
âââ ROOM.yml # Sub-room (full room, not region)
ROOM.yml Structure
room:
name: "Debug Session"
purpose: "Hunt down the authentication bug"
context:
- "Bug: Login fails with valid credentials"
- "Suspected: Session cookie handling"
cards_in_play:
- instance: "goblin-001"
card: "Git Goblin"
goal: "Find when bug was introduced"
working_set:
- "ROOM.yml"
- "state/progress.yml"
exits:
parent: "../"
related: "../feature-work/"
# Optional: position in 2D world-space
world_position:
x: 5
y: 12
# Optional: objects with positions in room-space
objects:
- name: "workbench"
position: {x: 3, y: 7}
Spatial Coordinates
Rooms can exist in world-space. Objects can have positions in room-space.
# World-space: where is this room in the world?
world_position:
x: 5
y: 12
# Room-space: where are objects within this room?
objects:
- name: "workbench"
position: {x: 3, y: 7}
Navigation can use coordinates:
NORTHfrom (5,12) â find room at (5,13)- Named exits override coordinates
Not all rooms need coordinates. Abstract spaces can exist outside world-space.
Vehicles: Portable Rooms That Move
A vehicle is a room you can embark, drive, and disembark.
# vehicle-tent.yml
room:
name: "Research Tent"
is_vehicle: true
world_position: {x: 5, y: 12} # Changes when you drive
| Command | Effect |
|---|---|
EMBARK tent |
Enter the vehicle room |
DISEMBARK |
Exit to current world location |
DRIVE NORTH |
Move vehicle (and occupants) to (5,13) |
Riding the Turtle
RIDE the turtle. Move around the room, draw on the floor, jump through doors:
> RIDE turtle
You mount the turtle. The world scrolls beneath you.
> FORWARD 100
The turtle moves forward. A red line appears on floor.svg.
> RIGHT 90
> FORWARD 50
You're near the door-north.
> ENTER door-north
You jump through the door INTO the next room.
The turtle comes with you.
# turtle.yml â a vehicle within room-space
turtle:
position: {x: 100, y: 100}
heading: 90 # degrees, 0 = north
pen_down: true
pen_color: "#e94560"
rider: "the-explorer"
| Command | Effect |
|---|---|
RIDE turtle |
Mount the turtle, move with it |
FORWARD 50 |
Move forward, draw if pen down |
RIGHT 90 |
Turn right |
ENTER door |
Jump through door to connected room |
INTO subroom |
Descend into nested sub-room |
ZOOM OUT |
See the room graph navigator |
Lineage: Papert’s Logo turtle, Rocky’s Boots (1982), Robot Odyssey (1984).
Snap Cursor & Pie Menus
When you approach an object, the cursor snaps to it and shows a pie menu of scored actions:
EXAMINE (80)
â±
REPAIR âââââ USE (95) â default
â²
TAKE (20)
This IS The Sims interaction model:
- Objects advertise their available actions
- Actions are scored based on context, needs, state
- High-scoring actions appear prominently
Lineage: Don Hopkins’ Pie Menus + Will Wright’s SimAntics.
Cursor as Vehicle: Direct Manipulation
The cursor carries tools and applies them to the room floor:
> SELECT pen-tool
Cursor now carries: ðï¸ pen (red)
> CLICK workbench
*snap* Cursor at workbench. Pen ready.
> DRAG to door-north
Drawing line from workbench to door-north...
Line added to floor.svg
| Tool | Icon | Action |
|---|---|---|
pen |
ðï¸ | Draw lines on floor |
eraser |
ð§½ | Remove drawings |
selector |
ð | Pick up and move objects |
linker |
ð | Draw connections between objects |
stamper |
ð | Place copies of cards |
Throwing Objects: Data Flow Programming
Throw objects through exits. They pile up on the other side.
> THROW blueprint door-north
Throwing blueprint through door-north...
blueprint landed in assembly/inbox/
Inbox / Outbox
room/
inbox/ # Objects thrown INTO this room land here
task-001.yml
outbox/ # Stage objects before throwing OUT
result-001.yml
| Command | Effect |
|---|---|
THROW obj exit |
Toss object through exit |
INBOX |
List waiting items |
NEXT |
Process next item (FIFO) |
STAGE obj exit |
Add to outbox |
FLUSH |
Throw all staged objects |
Rooms as Pipeline Stages
Each room is a processing node. Exits are edges. Thrown objects are messages.
# Document processing pipeline:
uploads/ # Raw files land here
inbox/
parser/ # Extract text
script: parse.py
analyzer/ # LLM analyzes
prompt: "Summarize and extract entities"
output/ # Final results collect here
This is Kilroy-style data flow: rooms as nodes, files as messages, the filesystem as the network.
Inventories
Characters carry inventories â portable rooms always with them.
# character/inventory/
sword.card
map.yml
notes/
finding-001.md
| Command | Effect |
|---|---|
GET sword |
Pick up from room â inventory |
DROP map |
Put from inventory â room |
GIVE torch TO companion |
Transfer to another character |
INVENT |
List what you’re carrying |
Your inventory IS a pocket dimension.
Nested Containers
Objects can contain other objects, to arbitrary depth:
> PUT screwdriver IN toolbox
> PUT toolbox IN backpack
> OPEN backpack
backpack contains:
- toolbox (3 items)
- sandwich
Object Paths
Address nested objects with paths:
> EXAMINE backpack/toolbox/wrench
> USE inventory/potions/healing
> TAKE ../chest/gold FROM here
Path syntax:
container/sub/itemâ absolute within scope./toolbox/wrenchâ relative to current../sibling/itemâ parent’s sibling/repo-name/pathâ multi-repo addressing
Tags for Search
> TAG wrench @favorite
> SEARCH backpack @tool
Found in backpack:
toolbox/screwdriver [@tool]
toolbox/wrench [@tool @favorite]
Room Graph Navigator
ZOOM OUT to see the whole world:
> ZOOM OUT
â ROOM GRAPH: moollm-palace â
â [room] [card] [chat] â
â â â
â [â
YOU ARE HERE] â
> LINK room TO card
Connection created. You can now JUMP directly.
| Command | Effect |
|---|---|
ZOOM OUT |
See room graph overview |
ZOOM IN room |
Enter selected room |
LINK a TO b |
Create connection between rooms |
Like Rocky’s Boots: Navigate the structure. Edit while exploring.
Speed of Light vs Carrier Pigeons
Traditional multi-agent: Each agent in isolation. One LLM call per agent. Communication by carrier pigeon. Slow. Expensive. Sad.
MOOLLM: Simulate as many agents together as possible in ONE LLM call. Communication at the speed of light. Multiple simulation steps per iteration.
# In one LLM iteration:
simulation:
- step: 1
papert-001: "Microworlds need low floors"
kay-001: "Yes! Like Smalltalk for children"
- step: 2
papert-001:
responds_to: kay-001
says: "Exactly! Accessible entry, unlimited ceiling"
- step: 3
synthesis:
emerged: "Low floor + high ceiling + prototypes = MOOLLM"
Three characters, three steps, instant cross-talk â ONE LLM call.
This IS The Sims
The Sims: One frame, all Sims simulated, instant interaction
MOOLLM: One call, all cards simulated, instant messaging
Instead of isolated agent prisons, we have a shared microworld.
Room Navigation
| Action | What Happens |
|---|---|
| Enter | Push room’s working_set to context |
| Exit | Pop context, return to parent |
| Look | Read ROOM.yml and README.md |
| Activate card | Clone card template into room |
| Complete card | Card writes return_value, can be removed |
Nested Rooms (Virtual Zones)
Rooms can contain rooms (subdirectories) or virtual zones (no physical directory):
# cat-cave.yml â TARDIS-like nested room
id: cat-cave
type: [room, furniture] # Both!
zones: # Virtual sub-rooms
nap-zone:
description: "Sunny spot, cushions everywhere"
path: "pub/cat-cave/nap-zone" # Virtual path
box-jungle:
description: "Cardboard paradise"
path: "pub/cat-cave/box-jungle"
Characters reference virtual zones:
# cat-terpie.yml
home: pub/cat-cave/
location: pub/cat-cave/nap-zone # Virtual zone
Room Relationships
Rooms can remember visitors:
relationships:
don-hopkins:
visits: 3
reputation: "regular"
memory: "Always nice to the cats"
Home vs Location Protocol
Entities have home (where file lives) and location (where they are):
character:
home: pub/cat-cave/terpie.yml # File never moves
location: pub/ # Currently in pub
Movement updates location, not file. See character/.
Pie Menu Room Topology
Full specification: TOPOLOGY.yml
The eight-direction compass maps to two types of connections:
| Direction | Type | Function |
|---|---|---|
| N/S/E/W | Cardinal | Navigate to major rooms (spiderweb) |
| NW/NE/SW/SE | Diagonal | Expand into storage grids (quadrants) |
4 ways OUT (navigation) + 4 quadrants IN (infinite storage) = Unlimited worlds
Grid naming: {quadrant}-{x}-{y} (e.g., ne-2-3 = 2 east, 3 north in NE)
See: exit skill for PIE-MENU-TOPOLOGY protocol, memory-palace/ for Method of Loci
Codebase as Navigable World
Directories are rooms. Files are objects. Functions are chambers you can enter.
# Location paths with line numbers
location: "@central/apps/insights/pyleela/brain/Schema.py:142"
# Path syntax
- @repo/path/to/file.py # file in repo
- @repo/path/to/file.py:42 # specific line
- @repo/path/dir/ # directory (room)
See character/ for party-based code review, README.md for detailed examples.
NPC Embedding Patterns
| Pattern | When | Example |
|---|---|---|
cat-name.yml |
Embedded NPC | pub/cat-terpie.yml |
name/CHARACTER.yml |
Complex character | characters/don-hopkins/ |
staff-name.yml |
Role-based grouping | pub/staff-marieke.yml |
See naming/ for conventions.
Rooms ARE Logistic Containers!
The Unification: Sims + Factorio
Rooms can participate in a logistics network:
| Feature | Source | MOOLLM |
|---|---|---|
| Action advertisements | The Sims | Objects advertise what they DO |
| Item requests | Factorio | Containers advertise what they NEED |
| Attractiveness scores | Both | Higher score = higher priority |
Room Logistics Mode
room:
name: "The Kitchen"
logistics:
mode: requester # passive-provider, requester, buffer...
request_list:
- tags: ["ingredient"]
count: 10
priority: high
Logistic Advertisements
Rooms advertise their NEEDS with attractiveness scores:
logistic_advertisements:
NEED_INGREDIENTS:
description: "Kitchen needs ingredients"
wants:
- tags: ["ingredient"]
count: 10
score: 70 # Base priority
score_if: "chef_is_cooking" # When to boost
score_bonus: 30 # Total 100 when cooking!
DESPERATELY_NEED_LIGHT:
wants:
- tags: ["light-source"]
count: 1
score: 100 # Very high!
Stacking in Rooms
Rooms can have stacks of items:
room:
name: "Armory"
stacks:
# Fungible (just count)
arrow: 500
bolt: 300
# Instance (individual state)
magic-sword:
count: 3
instances:
- { id: flame-blade, damage: 50 }
- { id: frost-edge, damage: 45 }
stack_limit: 1000
Grid Room Cells
Warehouse rooms can be grid cells:
room:
name: "Iron Ore Storage"
type: grid-cell
grid_cell:
enabled: true
parent: "../"
coordinates: { x: 2, y: 3 }
item_type: iron-ore
stacks:
iron-ore: 2500
The Flow
1. ROOMS advertise logistic needs with scores
2. LOGISTICS ENGINE collects all advertisements
3. Items route to HIGHEST-SCORING requester
4. BOTS or BELTS move items physically
5. ROOM receives items, fires on_item_added
See logistic-container/ and factorio-logistics-protocol.md.
The Philosophy
Spatial navigation IS cognitive navigation.
When you “enter” the debug-session room:
- Your context shifts to debugging
- Relevant cards are already in play
- The room’s knowledge is loaded
- You know where the exits lead
Live Examples
- examples/adventure-3/pub/ â A room with NPCs
- examples/adventure-3/pub/cat-cave/ â Nested room with zones
Dovetails With
Sister Skills
- card/ â Cards live in rooms
- memory-palace/ â Memory Palace IS Room + mnemonic intent
- adventure/ â Adventure IS Room + narrative framing
- data-flow/ â Rooms as processing nodes
- speed-of-light/ â Multi-agent instant communication
Kernel
- kernel/context-assembly-protocol.md â Working set loading