Table of Contents
Advanced Building
When you really want to get creative. This page collects the deeper builder tools — the ones that turn rooms and items from scenery into things players do. Everything here needs a builder role (worldbuilder, implementor, or admin), and builds on the basics in How to Build, All about Items, and All about Mobiles.
Puzzles: hidden things, locks, and secret ways
With a handful of data fields an item stops being mere gear and becomes an interactive prop: something you disturb, a lock you open with the right key, a secret way that appears. There's no scripting – each behaviour is one flat data field (set with item ref data field value), so a puzzle is content you build in-game, not code.
Invisible items
data invisible true – the item is present and you can still refer to it by keyword (look/move/take it if you know the word), but it is not listed when you look at the room. Use it for a prop the room's own description already hints at (so it isn't named twice), or for something that stays hidden until it's revealed. Usually paired with data fixed true so it can't be pocketed.
Searchable objects -- found with **search**
data searchable true – a player who types search in the room turns this item up. Pair it with data invisible true and the item is unlisted until someone searches; on a find its invisible flag is cleared, so it then shows for everyone (a lever you uncover stays uncovered). A bare search only reveals searchable items – an invisible prop that isn't searchable (a grate under leaves, uncovered by its own trigger) is left alone, so searching never shortcuts a puzzle. search item is still free for a verb_search flavour hook. Searching a pitch-black room you have no light for finds nothing.
Verb hooks -- things you can do to a prop
Give an item a custom action with data verb_word message: when a player types “word item”, the message prints.
- e.g. data verb_move, verb_pull, verb_push, verb_count, verb_search, verb_turn, verb_rub …
- Add data verb_word_reveal keyword to make that action reveal a hidden sibling item in the same room (it clears that item's invisible flag) – a one-way uncover.
- Or data verb_word_toggle keyword to flip that sibling hidden ↔ shown each time – leaves you sweep off a grate and rake back over it. Handy so a puzzle resets itself (nothing is ever permanently uncovered for everyone).
- Add data verb_word_exit dir to open a hidden exit (see below) out of the room: the action clears that direction's hidden_dir flag, so a wall slides back and the passage becomes walkable – e.g. a lever with verb_pull_exit west.
- take/get are hookable too (data verb_take message), so a fixed prop can react to being taken instead of just refusing.
- A few interaction words are also ordinary commands. look and read always show an item's description (use those for readable props); the interaction verbs above are free.
Locks and keys
- data lock lockword – the item has a lock identified by that word (any word you pick).
- data locked true – it starts locked.
- On the key item: data key lockword – a key held in hand whose word matches opens it.
Players use unlock item and lock item; unlocking needs the matching key on them.
Openables and state descriptions
- data openable true + data open false – players open item / close item. Opening is refused while it's locked.
- data ground_closed line and data ground_open line – the sentence the item adds to the room description, chosen by whether it's open. (Plain data ground line is the fallback for a prop with no open/closed state.)
Secret ways -- object exits
An open prop can be a way out of the room:
- data exit_to room# – where it leads.
- data exit_verbs phrases – the trigger phrases, separated by commas (e.g. down, enter cellar); type any one, while the prop is open, to go through. The commas are REQUIRED: a single phrase may contain spaces (“enter cellar” is one phrase, not two), so a space-separated list like “down enter cellar” is read as ONE long phrase and will match nothing a player would actually type.
- optional flavour: data exit_self what you see, data exit_leave what this room sees, data exit_arrive what the far room sees.
An openable exit only works once it's open; a prop with no open/closed state is always live.
Hidden exits -- secret passages on the room
A room's own cardinal exits can be hidden: a passage that isn't listed and can't be walked until something opens it. Set it on the room (not an item):
- room data hidden_dir – e.g. hidden_west, hidden_up. That exit vanishes from exits and won't let anyone through (it reads exactly like a wall), even though the exit destination is still wired.
- An item's verb_word_exit dir hook clears the flag and opens it for good – so pulling a lever, turning a stone, or speaking a word slides the passage open.
Because a hidden exit is unwalkable until opened, search deliberately does not disclose it – players find the mechanism (the lever), not the door. To move a room between hidden and open yourself, just set or clear hidden_dir. (A builder can always goto past it.)
Secret exits -- read-the-room passages
Sometimes you want no mechanism at all: the exit should simply be unlisted, and a player who reads the room and takes the hint can just walk it. That is a secret exit – the lighter cousin of a hidden one, where the reading is the whole puzzle. Set it on the room (not an item):
- room data secret_dir – e.g. secret_south, secret_west. The exit vanishes from exits and autoexits, but stays fully walkable: anyone who types that direction walks straight through. Nothing opens it and nothing needs to – it was never sealed, only unlisted.
- The room's own description is the only signpost, so write the clue into the prose (“a draft slides up from somewhere low in the southern web…”) and let the player find the way by reading and trying it.
- Set or clear it like any flag (room data secret_west true / secret_west false). For a two-way secret passage, set the matching flag at each end – secret_west in this room, secret_east in the one it joins.
Contrast with hidden_dir above: hidden is a sealed wall that needs a lever or gate to open; secret is an open doorway you simply can't see listed. Reach for secret_dir when the challenge is noticing the clue, and hidden_dir when it's working a mechanism.
A worked example: a rug, a trapdoor, a cellar
(in a room whose description already mentions a threadbare rug on the floor) item create rug item rug data invisible true (the desc mentions it; don't list it twice) item rug data fixed true item rug data keywords rug carpet item rug data verb_move A trapdoor is revealed beneath the rug! item rug data verb_move_reveal trapdoor item create trapdoor item trapdoor data invisible true (hidden until the rug is moved) item trapdoor data fixed true item trapdoor data keywords trapdoor door hatch item trapdoor data lock cellarhatch item trapdoor data locked true item trapdoor data openable true item trapdoor data ground_closed A heavy trapdoor is set into the floor, locked. item trapdoor data ground_open An open trapdoor gapes, its stairs sinking into the dark. item trapdoor data exit_to 57 (the cellar's room number) item trapdoor data exit_verbs down, enter cellar (and the key, waiting somewhere in the world) item create iron key item iron data key cellarhatch
Now a player who moves the rug reveals the trapdoor; unlock trapdoor (with the iron key in hand), open trapdoor, then down (or enter cellar) drops them into room 57. Extra verb_ hooks – a count, a search – add flavour. Combine the same pieces for levers, hidden doors, sealed chests, and more.
A second example: a hidden lever opens a secret wall
A search-and-pull puzzle: the room has a real west exit, but it's sealed until you find and pull a concealed lever.
(standing in the room, whose west exit already leads somewhere) room data hidden_west true (the west passage is sealed and unlisted) item create lever item lever name hidden lever item lever data invisible true (not listed...) item lever data searchable true (...until someone searches) item lever data fixed true item lever data verb_pull You pull the lever and a passage opens up in the west wall! item lever data verb_pull_exit west (pulling clears hidden_west -> the way opens) drop lever
A player who searches the room finds the lever; pull lever prints the line and opens the west passage (for everyone) so they can walk west. Until then, exits never mentions it and west just says you can't go that way.
Timed events -- gates and doors on the game clock
An object can open and close on its own, by the hour of the game clock – the classic town gate that opens at dawn and bars the road at nightfall. It reuses the openable and object-exit machinery above; you just add a schedule (and, if you like, two announcements):
- data open_at hour – the hour (0-23) it opens. 5 is the crack of dawn (the sun begins to rise); 6 is full daylight.
- data close_at hour – the hour (0-23) it closes. 20 is the sun's final setting (nightfall).
- data open_msg line – announced in the object's room when it opens (optional; a plain default is used if unset).
- data close_msg line – announced in the object's room when it closes (optional).
The clock's hourly tick flips the object's open flag on schedule and prints the message to its room. A daemon restart snaps every timed object to whatever its schedule implies for the current hour, so a gate is never caught mid-cycle. Because it's a normal openable, a shut gate refuses passage through its exit_to (“The town gate is closed.”), and a timed object can't be worked by hand – open / close are refused, since it keeps to its own clock.
Two things worth knowing: the window may wrap past midnight (open_at 20 + close_at 6 is a gate open only through the night); and you almost always want data fixed true (so it can't be picked up) plus ground_open / ground_closed lines (so the room shows its current state).
A worked example: the Eastern Gate
A gate wants a face on both sides, so it's two “town gate” objects – one in each room the gate stands between – each leading through to the other and sharing the same schedule, so they open and shut together. Standing in the town-side room (say room 34, whose east side is the gate):
item create town gate item gate desc A great gate of timber bound with black iron, tall enough to admit a laden hay-cart. item gate data fixed true item gate data openable true item gate data exit_to 95 item gate data exit_verbs east, e, gate item gate data open_at 5 item gate data close_at 20 item gate data open_msg With a groan of timber and iron, the town gate swings open to the dawn. item gate data close_msg The town gate swings shut, barring the road for the night. item gate data ground_open The great town gate stands open to the east. item gate data ground_closed The great town gate is shut, barring the road east.
Then build the twin in room 95 the same way, but with exit_to 34 and exit_verbs west, w, gate (and its ground lines facing west). Finally, undig east here to clear the plain cardinal passage between the two rooms, so the gate is the only way through – otherwise a walker (or a fleeing player, or a wandering mob) could slip past a shut gate by the old exit. From dawn to dusk the road runs open; at nightfall it bars, and anyone caught outside waits for morning.
Day/night schedules -- mobs that keep hours
Just as an object can follow the game clock, so can a mobile. Give it a day_room and a night_room and it keeps to one by daylight and the other after dark – the graveyard caretaker who works his office through the day and shuts himself in his house at night. Set it on the mob with mob ref data field value:
- data day_room room# – where it stays through the daylight hours (dawn through dusk, roughly 05:00-19:59).
- data night_room room# – where it moves for the night (nightfall through pre-dawn, 20:00-04:59).
- data sched_night_leave line – announced in the day room as it heads off for the night (optional).
- data sched_night_arrive line – announced in the night room as it arrives (optional).
- data sched_day_leave line – announced in the night room as it sets off at dawn (optional).
- data sched_day_arrive line – announced in the day room as it returns for the day (optional).
Both rooms are required for the schedule to engage. The mob simply appears in the right room – it doesn't walk the halls between, so the two rooms may sit anywhere in the world. The clock's hourly tick relocates it as the day/night line is crossed, and a daemon restart snaps it straight to wherever the current hour says it belongs (so a restart at midnight finds the caretaker already home). Unlike a timed gate, the four messages have no default – leave one unset and that crossing passes silently.
A worked example: the graveyard caretaker
The caretaker works from his office (room 151) by day and retires to his house (room 150) at night:
mob create caretaker mob caretaker data day_room 151 mob caretaker data night_room 150 mob caretaker data sched_night_leave The caretaker locks up the office and shuffles off toward his house. mob caretaker data sched_night_arrive The caretaker lets himself in and bars his door against the night. mob caretaker data sched_day_leave The caretaker steps out into the grey dawn and shuffles off toward the office. mob caretaker data sched_day_arrive The caretaker unlocks the office, hangs up his lamp, and settles in for the day.
Resetting flags on a zone reset
Zones reset about once an hour on their own, and a builder can force one with zone reset (the whole world, as the hourly timer does) or zone reset zone# (just that one zone's corpses, spawns, and flags). A reset is deliberately light-touch: it replaces anything missing from its spawn template, but it does not tear down or rebuild things that are still there. So by default a prop or mob keeps whatever drifted about it – a lever someone uncovered stays uncovered, a shopkeeper keeps (and goes on selling) items players handed it. Often that persistence is exactly what you want; sometimes it isn't.
When you want a specific flag to snap back to a base state every reset, declare it with an onreset_field directive on the item, mob, or room:
- data onreset_field value – on each reset, data field is set back to value. e.g. data onreset_invisible true re-hides a searched-out prop; data onreset_locked true re-locks a door.
- data onreset_field off (or none / clear) – on each reset, the field is removed – the way to force a flag back off. (A literal onreset_field false won't store: setting any data field to false clears it, so the directive would vanish. Use off instead.)
- The onreset_ directives themselves are never touched – they're the standing definition of the base state, not a one-shot.
Only the named flags are rewritten (and only when they've actually drifted, so it's cheap); everything else the thing has accumulated is left intact. This is the deliberate alternative to deleting and respawning just to fix a flag – ids stay stable, nothing is yanked from a player mid-use, and a mob's gathered inventory survives. A thing with no onreset_ directives simply keeps its flags across resets.
(a wall switch in a room that players flip to open something; reset it each hour) item create switch item switch data fixed true item switch data verb_flip You throw the switch with a heavy clunk. item switch data onreset_flipped off (base state: not flipped) drop switch
On a room, the natural use is re-sealing a secret exit a lever opened (see Hidden exits above): standing in the room, room data onreset_hidden_west true makes the west passage close again every reset, so the search-and-pull puzzle is fresh for the next player.
Multi-room puzzles: zone flags and gates
Everything above happens in one room. For a puzzle that spans an area – light three braziers scattered across the sewers and a stone door grinds open somewhere else – you need a shared scratchpad above the single room. That is the zone blackboard: each zone carries its own set of flags, and props raise them while a gate elsewhere watches for the right combination.
Raising a zone flag
- data verb_word_zoneflag flag – doing word to this prop sets flag on the current zone's blackboard (and prints the prop's verb_word line as usual). Give each source its own flag. e.g. three braziers with verb_light_zoneflag brazier_a, …brazier_b, …brazier_c.
- Raising a flag is one-way and idempotent – lighting an already-lit brazier just says “It is already done.” The flags are cleared on a zone reset, so the puzzle re-arms.
Requiring a tool in hand
Often the action needs an implement – you can't light a brazier bare-handed:
- data verb_word_needs dataflag – the actor must be holding an item whose data has dataflag set, or the action is refused and no flag is raised.
- data verb_word_needs_fail line – the refusal message (optional; a plain default is used otherwise).
e.g. a brazier with data verb_light_needs hasfire can only be lit while you carry something marked data hasfire true (the newbie torch is). “Light” also handles a prop that isn't a carried lamp, so light brazier reaches this hook.
The gate
A gate is a room that opens when the flags line up. It reuses Hidden exits: seal the way with hidden_dir, then –
- room data gate_needs flag,flag,… – the flags that must all be set.
- room data gate_exit dir – the hidden exit to un-seal when they are (one-way).
- room data gate_message line – announced to everyone in the zone (“You hear a stone door grind open, somewhere in the distance.”).
- room data gate_item keyword – optional: a prop in the gate room to flip to its open look at the same moment, so a great stone visibly grinds aside (see below).
A worked example: three braziers and a stone gate
(a brazier in each of three rooms) item create brazier item brazier data fixed true item brazier data verb_light The brazier catches with a roar, flames clawing at the ceiling. item brazier data verb_light_zoneflag brazier_a (b and c in the other two rooms) item brazier data verb_light_needs hasfire (needs a torch in hand) (the gate room, its down stair sealed) room data hidden_down true room data onreset_hidden_down true (re-seals every reset) room data gate_needs brazier_a,brazier_b,brazier_c room data gate_exit down room data gate_message You hear a stone door grind open, somewhere in the distance. room data gate_item gate (the stone prop to slide aside) (the stone itself: a prop that shows its state, flipped by the gate -- not player-openable) item create stone gate item gate data fixed true item gate data ground_closed A colossal stone slab is sunk into the floor here, sealing a stairwell beneath it. item gate data ground_open The colossal stone has ground aside, baring a stair down into the dark. item gate data open false item gate data onreset_open off (re-seals with the exit on reset) drop gate
Now a player with a torch lights all three braziers (in any order); on the third, the down stair un-seals, the stone grinds aside, and the whole zone hears it. An hour later the reset clears the flags, re-seals the exit, and re-closes the stone – fresh for the next party. The open/closed ground text (above) works for any prop, not just gates: give an item both lines and its listing follows its open flag.
See also: How to Build, All about Items, All about Mobiles, How to Play.
