Hazel reports · ^report(33) · Messed Up Dress Up's scripts · 2026-10-25 · work in progress

Game Scripts in Hazel, a Case Study

Abstract. This is a case study of game scripts written in Hazel. Messed Up Dress Up, a game made with M and N, lets five of its rooms hand their events to Hazel rules, each a function on_event : (Globals, Event) -> Cmd. The case shows what such a rule meets: its Globals is not the game's state but a view the game builds fresh for each room, that room's few fields filled and the rest at defaults, with which castle, house or lever is meant decided by context, out of the rule's sight. No one designed it so; it is what waves of features left, each added the day the kids asked, each with its own words and numbers for where (a background, a square, a room, an inside, a list index), none reworked after.

From these experiences, we (Matthew, Claude, and M and N) reflect, and now present a more holistic model: every place, thing and person gets one readable name, a Symbol of names, numbers and Fumola's binary call, like world(start)(square(E4))(castle(N))(room(3)); a thing keeps its name as it moves or is set aside, as Adapton's names keep their identity; and the rules' types, a RuleState per room, a whole-game Globals and a Cmd that names what it acts on, are built on those names. An appendix lists every name in the game's first world, with its settings as a Hazel record and every picture the game's archive has of it.

This is written for readers who know Hazel and want to see what writing a game's rules in it involves. Part 1 shows the rules and their types as they run today, in the game at eee9446 (0.0.429); Part 2 tells how they came to be that way; Part 3 proposes what to change, in Hazel. The game's own guide for its young players is a different document.

Part 1 How it works today

Piecemeal: each part works on its own terms, and they do not yet share a model.

A rule, today#

The game is plain JS. Five of its rooms can hand an event to a rule written in Hazel (or Fumola, or left to the game's own JS), chosen room by room in its 📜 Scripting tab. The Hazel program is one file of modules: Common (shared helpers) and one module per room, each with an on_event. The game loads Hazel's JS library (hazelgrove/hazel#2711), builds the program once per edit, and calls a room's function when its event happens (scriptEvent).

the game (JS)a lever pulled, a door,a way off the square→ EventPullHatch(1)the room's viewSCRIPT_ACTS[room].globals()16 fields, most atdefaults; for the treeroom: hatch onlythe rule (Hazel)TreeRoom.on_event : (Globals, Event) -> CmdSetHatch(1, false, Done)the game actsact.SetHatch(n, shut)hatchSet(...)swings, walks, waitsthen the event ends🪵 1 pre event🪵 2 post rule🪵 3 post eventthe log keeps the view three times: built before the call, with the answer applied to a copy, rebuilt when the event is over
Figure 1. One event, end to end. The game builds the room's view of its state, the Hazel rule answers a Cmd, and the game acts it out, one command at a time. The event log keeps the view three times, which is how the 📜 tab shows what an event changed.

The types, as the game declares them at the top of the program (25-scripting.js:98-102), and one room's whole rule:

type Event =
  + Pull(Side) + PullBoulder(Side) + PullHatch(Int) + PullThing(Int)
  + FallPit(Int) + WayOut(Int) + Way(Dir)

type Cmd =
  + Done + Flip(Side, Cmd) + Say(String, Cmd) + SetPit(Int, Bool, Cmd)
  + DropBoulder(Int, Cmd) + LiftBoulder(Int, Cmd) + SetHatch(Int, Bool, Cmd)
  + OpenDoor(Int, Bool, Cmd) + DropRock(Int, Bool, Cmd) + Wait(Int, Cmd)
  + GoRoom(Int, Cmd) + GoSquare(Int, Int, Dir, Cmd)

type Thing = (at = Int, uid = String, kind = String, on = Bool, works = [String],
              does = String, open = Bool, boulder = Bool)
type Cell = (col = Int, row = Int, kind = Place, ways = [Dir])

type Globals = (lever_L = Bool, lever_R = Bool, wiring = Wiring, draws = [Float],
                pits_on = [Bool], covered = [Bool], hatch = Bool, things = [Thing],
                rooms = [Room], exits = [Exit], out = Out, at_col = Int,
                at_row = Int, cols = Int, rows = Int, cells = [Cell])

# the tree room's rule, whole #
module TreeRoom = {
  let on_event = fun (g : Globals, e : Event) : Cmd ->
    case e
    | PullHatch(n) => SetHatch(n, !g.hatch, Done)
    | _ => Done
    end
}

A few things a Hazel reader should know about how these meet the game:

Globals is a per-rule view#

Each room registers three functions (SCRIPT_ACTS): here (is this event mine?), globals (build my view) and act (how my commands change the game). The view is a Globals with the room's own fields filled from the game and every other field at a default (scriptNoGlobals):

lever_Llever_Rwiringdrawspits_oncoveredhatchthingsroomsexitsoutat_colat_rowcolsrowscellsTrapRoomTreeRoomSquareWorldCastlefilled from the game: 16 of 80 cells; every other field is scriptNoGlobals' default (false, 0, [], "auto")
Figure 2. Which of the 16 fields each room fills. Purple: filled from the game for that room; grey: a default the rule should not read. No field is filled for two rooms.
moduleits eventsits commandsGlobals fields it fillswhich instance
TrapRoomPull(L|R), PullBoulder(side)Flip, SetPit, DropBoulder, LiftBoulderlever_L, lever_R, wiring, draws, pits_on, coveredthe trap room of the castle shown, room n
TreeRoomPullHatch(n)SetHatch(n, shut)hatchthe house the friend is in: hatchHouse(), 0 for the top
SquarePullThing(i)OpenDoor(at, open), DropRock(at, down)thingsthis place's levers and trap doors, at = index in its list
WorldWay(d)GoSquare(col, row, side)at_col, at_row, cols, rows, cellsthe world shown, every square
CastleFallPit(0|1), WayOut(n)GoRoom(r)rooms, exits, outthe castle shown, room n's way out

The tree room shows it best. A tree has up to six houses and a round room at the top, each with its own trap door (hatchShut1 to hatchShut6, hatchShutTop). The rule gets one hatch : Bool: the door of the house the friend is in, picked by the game (hatchHouse). The event carries the house's number, PullHatch(1), and the command repeats it, SetHatch(1, false, Done), but the state does not: the game checks the number matches and refuses the command if not. So the rule's hatch is "this hatch", resolved by context, and a rule cannot ask about any other.

The other rooms work the same way. The trap room's levers are the trap room of the castle shown; the square's things are the list of the place the friend is in, each known by its index in that list (at); the castle's out is the way out of the room the friend is in. Nothing in Globals says which castle, square or house: the game knows, and the rule is written as if there were only one.

Two things the game's own guide says otherwise: pits_on is whether each pit is there at all, not whether it is open (that the rule works out from the levers and the wiring), and "17 fields" counts the JS object, not what the rule sees.

Where, today: eleven words, and numbers for names#

Read from the game itself (its default world and its tables of insides, castles and room styles, in node at eee9446), with every trap door, hatch and passage open:

ABCDEF1234567A1deepseaB1seaC1seaD1seaE1seaA2deepseaB2witch+1 insideC2beachD2mountainsE2treehouse+5 insideA3deepseaB3forestC3crossingD3woodpathE3fairyforestA4deepseaB4crossingC4lake+1 insideD4clearing+1 insideE4castle+5 insideA5waterfall+2 insideB5campsite+2 insideC5crossingD5house+1 insideE5treehouse+5 insideF5forestA6forestB6crossingC6cemeteryD6lake+1 insideE6castle+5 insidethe default world, "start"31 squares on a 6 × 7 grid140 ways between them (lines)60 places counting the insides+ 4 off the grid: imagination, emptyroom, bubblespace, bubbleroomstart: D4
Figure 3. The default world. Each square is a place of some kind; 140 ways lead between squares (the lines); 29 more places are inside squares: castle rooms, tree houses, tents, the cave, the living room and the rest. The world can grow to 12 × 12 and hold more worlds; this is the one a new game starts in.
wordin the codein the game's UI
backgroundstate.background (the place and the friend's spot in it), backgroundSvg🏞️ Background tab
kindB.kind and cell.kind (a place); ROOM_KINDS (castle room styles); thing.kind"kind of place" (a group)
placePLACES, placeKey, objPlace, person.place; castlePlaces (table seats)"🗺️ the place", "not in any place"
sceneSCENES, *Scene functions, SCENE (stage geometry)hardly
square / cellsquareName, Square (script), GoSquare / W.cells, cellKeyssquare, D4 / never "cell"
roomcastle rooms; treeroom; ROOMS (furnishing); NORTH_ROOMS (indoor); hutRooms (huts); SCRIPT_ROOMS (modules)"🚪 room n is", "🦇 cave room"
insideINSIDES; B.inside (= the tree house's number)"inside the castle", "🚪 off the grid"
houseB.houses, data-house (tree houses); kind "house" (the family's)"🏡 house n" vs "🏠 house and yard"
homeworldHome, passageHome"🏠 home" (a group of places)
worldstate.world (one grid), worldsAway🗺️ World design, "🌍 world N"

"Place" is the code's word and never the UI's; the UI says background, square and room. And the ids are positions: a placed thing is its index in its place's list (and only a trap door or a cave passage has a uid, a random string); a pit is 0 or 1; a house is 1 to 6; a castle room 1 to 13; a square is "c,r" in code and D4 on screen. A 1 in a command can be a house, a pit, a room or a list index, depending on the command. Several keys already work like addresses, spelled differently each time: placeKey is castleroom:N:3, worldHome is off:w1:tent:2, a person's place is {world, key} with no room part, and a setting's key spells its owner into its name (castleLeverL_3N).

Part 2 How it got this way

Waves of features and game experiences, each with its own words and keys.

Waves of features#

Messed Up Dress Up was made with M and N, a feature at a time, each released the day it worked, as they asked for it (the game's own rule: features first, released at once). Each wave brought its own experience and, with it, its own way to say where the friend is, and none went back to rework the ones before:

  1. Dressing up, in front of a picture. The first game was a friend to dress; state.background.kind was the picture behind them, one of a list (PLACES, its group chips kind of place). A place was a picture, and a picture had no inside.
  2. Places you can walk into. Doors came next, each door a data-to naming a kind: the house's living room, the witch's room, the cave. An inside was just another kind, reached by a door; "back" was a stack of where you had been (trips).
  3. Castles and their rooms, for N's and M's castle designs: three castles by whose they are, rooms by number (1 to 13) with styles (ROOM_KINDS), and each room's settings spelled into its keys (castleLeverL_3N). The trap room's levers and pits came with them, numbered 0 and 1.
  4. Tree houses: up to six houses by number, a round room on top, bridges, ladders and hatches; B.inside became "which house".
  5. A world to walk: a grid of squares, each a place kind (W.cells["c,r"], D4 on screen), ways between squares, then other worlds, insides kept "off the grid", cave passages that link any two places, and people placed in squares (person.place {world, key}, no room).
  6. Things placed in places: rocks, levers, trap doors, each an entry in its place's list, known by its index; a trap door and a passage got a random uid so a lever and its twin could find them.
  7. Rules in Hazel and Fumola, for five rooms: each rule needed some of the game's state, and the simplest thing that worked was one record type with every room's fields, filled per room. That is Globals.
10-09backgroundstate.background.kind: the picture behind the friend10-12kind / sceneSCENES, backgroundSvg; a 'kind of place' in the picker10-14castle, roomcastleRoom n; ROOM_KINDS styles; 'room' for 6 more things10-15tree house nB.inside = the house; hatchShut{n}10-17world, squarestate.world, W.cells["c,r"], D4 in the UI; cells in code10-18inside, off the gridINSIDES, ELSEWHERE, W.off[placeKey]10-19placePLACES, placeKey, person.place: in code, never in the UI's words10-21Room (scripts)SCRIPT_ROOMS: TrapRoom, TreeRoom, Square, World, Castle
Figure 4. The words for where, roughly as they came in (October 2026), and what each means now in the code.

Each step was the right size for its day, and the game kept working. The cost is what Part 1 shows: eleven overlapping words, ids that are positions, and a rule's state that is shaped for the game's convenience rather than the rule's. Nothing in it is wrong for one room; it does not add up for a game that a rule, a log, or a second game should be able to read as a whole.

Part 3 A more holistic approach

One model of where everything is, and rule types built on it.

RuleState, and a real Globals#

The fix the view asks for is to say what it is. Each room's rule takes its own state type, named for it: the tree room a hatch, the trap room its levers and pits, the world its squares. No default fields, nothing for a rule to misread, and a rule's type says what it depends on. Matthew's name for the sum of them is RuleState.

A real Globals is then the whole game, read-only to rules. For a rule that wants to look further (is the other castle's trap set? where is the friend?), for diagnostics, and for the log: the same addresses in every rule's state and in Globals let a tool show a change anywhere. Rules still change the game only through commands, so the game stays the one place state changes.

Both need a way to say which hatch, lever or room, in one keyspace. That is the next three sections.

Every place, as a path#

Every move between places the game allows is a move along this tree or across it: the ways between squares; a door to an inside and back; a ladder, bridge or hatch between tree houses; a pit from the trap room to a dungeon; a cave passage, which may lead to any place in any world; a picture you step into. Each lands in exactly one node, so one path from the world down names any place a walk can reach:

world(start)state.world (id w1, name "start")(square(E4))W.cells["4,3"], kind castle(castle(N))B.castle = "N" (from the square's own settings)(room(3))B.castleRoom = 3, style castleRoom3N = "trap"(lever(L))B.castleLeverL_3N (no id: a key spelled from parts)(pit(1))B.castlePitOn0_3N, the left pit: 0 in code, 1 here(square(E2))W.cells["4,1"], kind treehouse(house(1))B.inside = 1 (treeroom), room1 = its furnishing(hatch)B.hatchShut1 (the script sees hatch = Bool)(top)kind treetop; hatchShutTop; PullHatch(0)where it lives in the game today
Figure 5. Two squares' places as addresses, each beside where the game keeps it today.

Names that can't collide#

CallCallCallcastle(N)square(E4)world(start)CallText("castle")Text("N")world(start)(square(E4))(castle(N)): one binary form, Call(S1, S2), makes both a step (castle(N)) and the path (an owner applied to what it owns)
Figure 6. A game symbol is text, a number, or one symbol applied to another, S1(S2). A step is a call (castle(N)), and so is a path: the owner applied to what it owns, left to right.

In Fumola, the same symbol, as it stands (its Call):

`world(`start)(`square(`E4))(`castle(`N))(`room(3))(`lever(`L))

In Hazel, a symbol is written as that text and parsed to the tree: parentheses, names and numbers, nothing else, and no constructor names in a rule:

let lever_L = parse_sym("world(start)(square(E4))(castle(N))(room(3))(lever(L))") in
let room_3 = parse_sym("world(start)(square(E4))(castle(N))(room(3))") in
print_sym(lever_L) == "world(start)(square(E4))(castle(N))(room(3))(lever(L))"

Human readable: as text, each step is a word and a name a player would use (square(E4), castle(N), lever(L)). Unambiguous: the kind is part of every step (the first half of its call), and a name only has to be unique among its owner's children of that kind, so places, things and people share one keyspace with no global counter.

This is Fumola's symbol, as it stands. In Fumola, names are values: an identifier is a symbol, a number is a symbol, and symbols compose by application and nest, `adapton(`settings); Fumola's Symbol has exactly these cases (Id, Nat, Call, and others besides); a game symbol needs only those three: names, numbers and parentheses. And its space is the same move an address makes: a cell `x named inside the region `region is `region(`x), so a callee names freely without colliding with its caller, as a room names its levers without knowing which castle it is in.

Identity, not position. Adapton names a node so it keeps its name when its contents change; the alternative, naming by content, cannot say "same node, new value" (Fumola's notes, What is a cache key a function of?). Names derived from position are worse than either: an address survives only as long as the shape it addresses, which in Fumola's mergeSort measurements turned a repair of 23 to 25 nodes into 139. The game's list indexes are such names: delete the first thing in a place and every PullThing(i) after it means a different thing. So:

templatea kind, placed nowhere:lever, `ninja, room(trap)placedowned by a place:...room(3).lever(L)set asidein the world's buffer,still itself, no ownermaketake output backmove: a new owner, the same namea thing keeps the name it was made with; where it is (owner, or the buffer) is a field that changes
Figure 7. An instance's life. It is made from a template and placed, may move to another owner, and may be set aside and put back, with the same name throughout. The game does this for people today (state.peopleAway, each with an optional place); a thing taken out of a place is simply gone.
Fumola's storea cell is named by space and by time, both nesting symbols:space `region(`x) (a callee names freely)time a revision: a read answers the greatest comparable earlier writeso one name carries a history, not one valueMUDU's state, as proposedthe space half only: every place, thing and personat a nested address, world(start)(square(E4))...no symbolic time, for now: one current state; thelog's three snapshots per event are the nearestthing to time, and where it would come in
Figure 8. Fumola has a store whose cells are named by space and by time, each a nesting symbol. The game's state would use the space half: the current state, at nested addresses. It needs no symbolic time yet; the event log's three snapshots per event are where time would come in.

Globals, RuleState and Cmd, proposed#

In Hazel. First the addresses and what they name:

# a game symbol, as Fumola's: text, a number, or one applied to another #
type Symbol = + Text(String) + Num(Int) + Call(Symbol, Symbol)

# supposed: Hazel parses a symbol from its text and prints it back, so
   rules, saves and logs write world(start)(square(E4)) #
# parse_sym : String -> Symbol    "a(b)(c)" is Call(Call(a, b), c) #
# print_sym : Symbol -> String    print_sym(parse_sym(t)) == t #

# lever(L) is Call(Text("lever"), Text("L"));
   world(start)(square(E4)) is Call(world(start), square(E4)):
   an owner applied to what it owns, as Fumola's `region(`x) #

type Where = + Placed(Symbol) + SetAside + Carried(Symbol)

type Setting = + B(Bool) + I(Int) + F(Float) + S(String) + A(Symbol)

# a placed thing or person: its name for good, its template, where it is now #
type Instance = (id = Symbol, template = String, where = Where,
                 settings = [(String, Setting)])

# a place: its address, its template, its ways, and what it owns #
type Way = (dir = Dir, to = Symbol, via = + Open + Door(Symbol) + Shut(Symbol))
type PlaceState = (id = Symbol, template = String, ways = [Way], owns = [Symbol])

Then the whole game, each room's own state, and commands and events by address:

# the whole game, as any rule may read it #
type Globals = (
  friend = (id = Symbol, at = Symbol),      # the person being played, and where #
  places = [PlaceState],
  instances = [Instance],               # every thing and person made #
  set_aside = [Symbol],                   # the world's buffer, re-placeable #
  random_numbers = [Float]              # the event's random numbers (today's draws) #
)

# what each room's rule is about: its own, named, typed #
type TrapRoomState = (here = Symbol,
  levers = [(id = Symbol, up = Bool)], wiring = Wiring,
  pits = [(id = Symbol, there = Bool, covered = Bool)])
type TreeRoomState = (here = Symbol, hatch = (id = Symbol, shut = Bool))
type SquareState = (here = Symbol, levers = [Instance], doors = [Instance])
type WorldState = (here = Symbol, squares = [PlaceState])
type CastleState = (here = Symbol, rooms = [PlaceState], out = Out)

type RuleState =
  + Trap(TrapRoomState) + Tree(TreeRoomState) + Square(SquareState)
  + World(WorldState) + Castle(CastleState)

# the event names what happened to, by address #
type Event = + Pull(Symbol) + Fall(Symbol) + Leave(Symbol, Dir) + Arrive(Symbol)

# commands name what they act on, by address #
type Cmd =
  + Done + Say(String, Cmd) + Wait(Int, Cmd)
  + Flip(Symbol, Cmd)                     # a lever #
  + Swing(Symbol, Bool, Cmd)              # a hatch, a pit's lid, a door: open? #
  + Set(Symbol, String, Setting, Cmd)     # any setting of any instance #
  + Move(Symbol, Where, Cmd)              # an instance to a new owner, or aside #
  + Go(Symbol, Cmd)                       # the friend, to a place #

# a rule: its room's state, the whole game to read, the event #
let on_event : (RuleState, Globals, Event) -> Cmd

The commands get fewer and more general: one Swing for every hatch, lid and door, one Set for any setting, and Move, which today's rules cannot do at all. Each names its target, so the game's act no longer has to check that a number means what the rule meant. Today's, beside them:

todayproposed
PullHatch(1)Pull(world(start)(square(E2))(house(1))(hatch))
SetHatch(1, false, Done)Swing(…house(1).hatch, true, Done)
Pull(L) in the trap roomPull(world(start)(square(E4))(castle(N))(room(3))(lever(L)))
Flip(L, Done)Flip(…room(3).lever(L), Done)
SetPit(0, true, …)Swing(…room(3).pit(1), true, …)
PullThing(4) (the 5th thing in the list)Pull(…square(B6).lever(2)) (a name kept when the list changes)
OpenDoor(7, true, …)Swing(…square(B6).trapdoor(1), true, …)
GoRoom(0, …) (0 = out of the castle)Go(world(start)(square(E4)), …)
GoSquare(3, 3, S, …)Go(world(start)(square(D4)), …)
(none: a rule cannot move a thing)Move(…lever(2), SetAside, …)

The tree room's rule becomes | Pull(h) => Swing(h, !s.hatch.shut, Done) with s : TreeRoomState: the same one line, now saying which hatch.

What next#

How this was put together#

Written on 2026-10-25 by Claude, for Matthew, from ^ticket(609). The game was read at eee9446 (Messed Up Dress Up 0.0.429). The default world, the insides, castles and room styles were read from the game's own tables, run in node (data/places.json); Figure 4 and the appendix are drawn from that file. The rooms' fields and types were read from dress-up/js/25-scripting.js and 25-fumola.js. The pictures in the appendix are the game's own drawings, from the dress-up-pictures archive's newest run; things got a folder of their own there for this report.

Appendix: every address#

Every place and placed thing of the default world, then the templates: places, castle room styles and people. Open a row to see the game's drawing of it (fetched from the archive only then). A thing's number here is its order among its kind in that place, as a name would be minted; the game today knows it only by its index in the place's list.

places (64)#

world(start)(square(A1))a square: deepsea
world(start)(square(B1))a square: sea
world(start)(square(C1))a square: sea
world(start)(square(D1))a square: sea
world(start)(square(E1))a square: sea
world(start)(square(A2))a square: deepsea
world(start)(square(B2))a square: witch
world(start)(square(B2))(witchroom)witchroom
world(start)(square(C2))a square: beach
world(start)(square(D2))a square: mountains
world(start)(square(E2))a square: treehouse
world(start)(square(E2))(house(1))tree house 1's room
world(start)(square(E2))(house(2))tree house 2's room
world(start)(square(E2))(house(3))tree house 3's room
world(start)(square(E2))(house(4))tree house 4's room
world(start)(square(E2))(top)the round room at the top
world(start)(square(A3))a square: deepsea
world(start)(square(B3))a square: forest
world(start)(square(C3))a square: crossing
world(start)(square(D3))a square: woodpath
world(start)(square(E3))a square: fairyforest
world(start)(square(A4))a square: deepsea
world(start)(square(B4))a square: crossing
world(start)(square(C4))a square: lake
world(start)(square(C4))(underwater)underwater
world(start)(square(D4))a square: clearing
world(start)(square(D4))(healerroom)healerroom
world(start)(square(E4))a square: castle
world(start)(square(E4))(castle(N))(room(1))N's castle, room 1: king
world(start)(square(E4))(castle(N))(room(2))N's castle, room 2: greenhouse
world(start)(square(E4))(castle(N))(room(3))N's castle, room 3: trap
world(start)(square(E4))(castle(N))(room(4))N's castle, room 4: dungeon1
world(start)(square(E4))(castle(N))(room(5))N's castle, room 5: dungeon2
world(start)(square(A5))a square: waterfall
world(start)(square(A5))(cave)the cave behind the falls
world(start)(square(A5))(cave)(room)the cave's room
world(start)(square(B5))a square: campsite
world(start)(square(B5))(tent(1))tent 1
world(start)(square(B5))(tent(2))tent 2
world(start)(square(C5))a square: crossing
world(start)(square(D5))a square: house
world(start)(square(D5))(livingroom)livingroom
world(start)(square(E5))a square: treehouse
world(start)(square(E5))(house(1))tree house 1's room
world(start)(square(E5))(house(2))tree house 2's room
world(start)(square(E5))(house(3))tree house 3's room
world(start)(square(E5))(house(4))tree house 4's room
world(start)(square(E5))(top)the round room at the top
world(start)(square(F5))a square: forest
world(start)(square(A6))a square: forest
world(start)(square(B6))a square: crossing
world(start)(square(C6))a square: cemetery
world(start)(square(D6))a square: lake
world(start)(square(D6))(underwater)underwater
world(start)(square(E6))a square: castle
world(start)(square(E6))(castle(N))(room(1))N's castle, room 1: king
world(start)(square(E6))(castle(N))(room(2))N's castle, room 2: greenhouse
world(start)(square(E6))(castle(N))(room(3))N's castle, room 3: trap
world(start)(square(E6))(castle(N))(room(4))N's castle, room 4: dungeon1
world(start)(square(E6))(castle(N))(room(5))N's castle, room 5: dungeon2
world(start)(elsewhere(imagination))off the grid
world(start)(elsewhere(emptyroom))off the grid
world(start)(elsewhere(bubblespace))off the grid
world(start)(elsewhere(bubbleroom))off the grid

things (68)#

world(start)(square(A1))(shell(1))a shell, the 1st placed here
world(start)(square(A1))(shell(2))a shell, the 2nd placed here
world(start)(square(A1))(shell(3))a shell, the 3rd placed here
world(start)(square(A1))(shell(4))a shell, the 4th placed here
world(start)(square(A1))(shell(5))a shell, the 5th placed here
world(start)(square(A1))(shell(6))a shell, the 6th placed here
world(start)(square(A1))(shell(7))a shell, the 7th placed here
world(start)(square(A1))(shell(8))a shell, the 8th placed here
world(start)(square(A1))(shell(9))a shell, the 9th placed here
world(start)(square(A2))(seagrass(1))a seagrass, the 1st placed here
world(start)(square(A2))(seafan(1))a seafan, the 1st placed here
world(start)(square(A2))(sealettuce(1))a sealettuce, the 1st placed here
world(start)(square(A2))(coral(1))a coral, the 1st placed here
world(start)(square(A4))(chest(1))a chest, the 1st placed here
world(start)(square(A4))(chest(2))a chest, the 2nd placed here
world(start)(square(A4))(chest(3))a chest, the 3rd placed here
world(start)(square(A4))(chest(4))a chest, the 4th placed here
world(start)(square(A4))(kelp(1))a kelp, the 1st placed here
world(start)(square(A4))(kelp(2))a kelp, the 2nd placed here
world(start)(square(A4))(kelp(3))a kelp, the 3rd placed here
world(start)(square(A4))(kelp(4))a kelp, the 4th placed here
world(start)(square(A4))(kelp(5))a kelp, the 5th placed here
world(start)(square(A4))(kelp(6))a kelp, the 6th placed here
world(start)(square(A4))(starfish(1))a starfish, the 1st placed here
world(start)(square(A4))(seafish(1))a seafish, the 1st placed here
world(start)(square(C4))(pine(1))a pine, the 1st placed here
world(start)(square(C4))(pine(2))a pine, the 2nd placed here
world(start)(square(A5))(rock(1))a rock, the 1st placed here
world(start)(square(A5))(rock(2))a rock, the 2nd placed here
world(start)(square(A5))(rock(3))a rock, the 3rd placed here
world(start)(square(A5))(rock(4))a rock, the 4th placed here
world(start)(square(A5))(rock(5))a rock, the 5th placed here
world(start)(square(A5))(rock(6))a rock, the 6th placed here
world(start)(square(A5))(tree(1))a tree, the 1st placed here
world(start)(square(A5))(pine(1))a pine, the 1st placed here
world(start)(square(A5))(pine(2))a pine, the 2nd placed here
world(start)(square(A5))(pine(3))a pine, the 3rd placed here
world(start)(square(A5))(pine(4))a pine, the 4th placed here
world(start)(square(F5))(rock(1))a rock, the 1st placed here
world(start)(square(F5))(rock(2))a rock, the 2nd placed here
world(start)(square(F5))(rock(3))a rock, the 3rd placed here
world(start)(square(F5))(rock(4))a rock, the 4th placed here
world(start)(square(F5))(rock(5))a rock, the 5th placed here
world(start)(square(F5))(rock(6))a rock, the 6th placed here
world(start)(square(F5))(rock(7))a rock, the 7th placed here
world(start)(square(F5))(rock(8))a rock, the 8th placed here
world(start)(square(F5))(rock(9))a rock, the 9th placed here
world(start)(square(F5))(rock(10))a rock, the 10th placed here
world(start)(square(F5))(rock(11))a rock, the 11th placed here
world(start)(square(F5))(rock(12))a rock, the 12th placed here
world(start)(square(F5))(rock(13))a rock, the 13th placed here
world(start)(square(F5))(rock(14))a rock, the 14th placed here
world(start)(square(F5))(rock(15))a rock, the 15th placed here
world(start)(square(A6))(rock(1))a rock, the 1st placed here
world(start)(square(A6))(rock(2))a rock, the 2nd placed here
world(start)(square(A6))(rock(3))a rock, the 3rd placed here
world(start)(square(A6))(rock(4))a rock, the 4th placed here
world(start)(square(A6))(rock(5))a rock, the 5th placed here
world(start)(square(A6))(rock(6))a rock, the 6th placed here
world(start)(square(A6))(rock(7))a rock, the 7th placed here
world(start)(square(A6))(rock(8))a rock, the 8th placed here
world(start)(square(A6))(rock(9))a rock, the 9th placed here
world(start)(square(B6))(rock(1))a rock, the 1st placed here
world(start)(square(B6))(rock(2))a rock, the 2nd placed here
world(start)(square(B6))(rock(3))a rock, the 3rd placed here
world(start)(square(B6))(rock(4))a rock, the 4th placed here
world(start)(square(B6))(tree(1))a tree, the 1st placed here
world(start)(square(B6))(tree(2))a tree, the 2nd placed here

templates: places (51)#

place(emptyroom)🔲 empty room
place(bubblespace)🫧 bubble space
place(bubbleroom)🫧 the bubble room
place(imagination)💭 our imagination
place(forest)🌲 forest
place(underwater)🐠 underwater
place(deepsea)🪸 deep sea
place(beach)🏖️ beach
place(sea)🌊 open water
place(witch)🧙 witch's woods
place(cemetery)🌿 cemetery
place(lake)🦆 lake
place(house)🏠 house and yard
place(farmyard)🚜 farm yard
place(treehouse)🌳 tree house
place(treeroom)🪜 inside the tree house
place(treetop)⭕ the round room at the top of the tree
place(livingroom)🛋️ living room
place(witchroom)🧙 inside the witch's hut
place(clearing)🌲 forest clearing
place(healerroom)🌿 inside the healer's hut
place(fairyforest)🧚 fairy forest
place(mountains)⛰️ mountain trail
place(waterfall)💦 jungle waterfall
place(campsite)🏕️ camp site
place(tent)⛺ inside a tent
place(cave)🪨 cave behind the falls
place(caveroom)🦇 cave room
place(woodpath)🥾 path through the woods
place(pasture)🌾 pasture
place(crossing)🛤️ forest crossing
place(castle)🏰 castle
place(castleroom)🚪 inside the castle
place(hut)🛖 grass hut
place(hutroom)🛋️ inside the grass hut
place(hutbed)🛏️ the grass hut's bedroom
place(hutpotion)🧪 the grass hut's potion room
place(hutcenter)🔥 the grass hut's center
place(desert)🏜️ desert
place(castleroom)(style(king))👑 king's room, exits: side
place(castleroom)(style(greenhouse))🌿 greenhouse, exits: all
place(castleroom)(style(trap))🕳️ trap room, exits: trap
place(castleroom)(style(dungeon1))🗝️ dungeon, exits: ladder
place(castleroom)(style(dungeon2))⛓️ deep dungeon, exits: ladder
place(castleroom)(style(hallway))🕯️ hallway, exits: hall
place(castleroom)(style(catroom))🐈 cat room, exits: side
place(castleroom)(style(stable))🐴 stable, exits: side
place(castleroom)(style(dining))🍽️ dining room, exits: long
place(castleroom)(style(kitchen))🍲 kitchen, exits: side
place(castleroom)(style(smithy))⚒️ smithy, exits: side
place(castleroom)(style(spiral))🌀 spiral staircase, exits: spiral

templates: people (36)#

person(friend)the friend at the defaults, no costume
person(costume(tiger))a person in the tiger costume
person(costume(cat))a person in the cat costume
person(costume(lion))a person in the lion costume
person(costume(bear))a person in the bear costume
person(costume(falcon))a person in the falcon costume
person(costume(raccoon))a person in the raccoon costume
person(costume(bobcat))a person in the bobcat costume
person(costume(leopard))a person in the leopard costume
person(costume(eagle))a person in the eagle costume
person(costume(cheetah))a person in the cheetah costume
person(costume(jaguar))a person in the jaguar costume
person(costume(moth))a person in the moth costume
person(costume(falconsuit))a person in the falconsuit costume
person(costume(eaglesuit))a person in the eaglesuit costume
person(costume(wolf))a person in the wolf costume
person(costume(deer))a person in the deer costume
person(costume(dragon))a person in the dragon costume
person(costume(sasquatch))a person in the sasquatch costume
person(costume(witch))a person in the witch costume
person(costume(fairy))a person in the fairy costume
person(costume(ghost))a person in the ghost costume
person(costume(gnome))a person in the gnome costume
person(costume(wizard))a person in the wizard costume
person(costume(monk))a person in the monk costume
person(costume(robin))a person in the robin costume
person(costume(knight))a person in the knight costume
person(costume(queen))a person in the queen costume
person(costume(king))a person in the king costume
person(costume(robot))a person in the robot costume
person(costume(cowgirl))a person in the cowgirl costume
person(costume(cowboy))a person in the cowboy costume
person(costume(ninja))a person in the ninja costume
person(costume(giraffe))a person in the giraffe costume
person(costume(scuba))a person in the scuba costume
person(costume(diver))a person in the diver costume

The data#