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).
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:
- A
Cmdis a list spelled as a sum: every command carries the rest, ending inDone. The game walks it (scriptRun);Wait(ms, rest)holds the rest for later, so a rule can describe a timed sequence without a clock of its own. An unknown command stops the walk. - The boundary is typed both ways. The game's state is JS text and numbers;
scriptTypedGlobalsturns strings into the sums (Wiring,Room,Out,Place,Dir), andscriptUntypedCmdturns commands back. So the JS object has 17 fields and the rule sees 16:outandout_roombecome oneOut. - A rule has no randomness or clock: the trap room's two random draws come in as
draws, drawn by the game from a seed it keeps. - One error anywhere sends every Hazel room back to the JS (the program must be whole to run), and a rule that throws is said in the game and skipped.
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):
| module | its events | its commands | Globals fields it fills | which instance |
|---|---|---|---|---|
| TrapRoom | Pull(L|R), PullBoulder(side) | Flip, SetPit, DropBoulder, LiftBoulder | lever_L, lever_R, wiring, draws, pits_on, covered | the trap room of the castle shown, room n |
| TreeRoom | PullHatch(n) | SetHatch(n, shut) | hatch | the house the friend is in: hatchHouse(), 0 for the top |
| Square | PullThing(i) | OpenDoor(at, open), DropRock(at, down) | things | this place's levers and trap doors, at = index in its list |
| World | Way(d) | GoSquare(col, row, side) | at_col, at_row, cols, rows, cells | the world shown, every square |
| Castle | FallPit(0|1), WayOut(n) | GoRoom(r) | rooms, exits, out | the 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:
| word | in the code | in the game's UI |
|---|---|---|
| background | state.background (the place and the friend's spot in it), backgroundSvg | 🏞️ Background tab |
| kind | B.kind and cell.kind (a place); ROOM_KINDS (castle room styles); thing.kind | "kind of place" (a group) |
| place | PLACES, placeKey, objPlace, person.place; castlePlaces (table seats) | "🗺️ the place", "not in any place" |
| scene | SCENES, *Scene functions, SCENE (stage geometry) | hardly |
| square / cell | squareName, Square (script), GoSquare / W.cells, cellKeys | square, D4 / never "cell" |
| room | castle rooms; treeroom; ROOMS (furnishing); NORTH_ROOMS (indoor); hutRooms (huts); SCRIPT_ROOMS (modules) | "🚪 room n is", "🦇 cave room" |
| inside | INSIDES; B.inside (= the tree house's number) | "inside the castle", "🚪 off the grid" |
| house | B.houses, data-house (tree houses); kind "house" (the family's) | "🏡 house n" vs "🏠 house and yard" |
| home | worldHome, passageHome | "🏠 home" (a group of places) |
| world | state.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:
- Dressing up, in front of a picture. The first game was a friend to dress;
state.background.kindwas the picture behind them, one of a list (PLACES, its group chipskind of place
). A place was a picture, and a picture had no inside. - Places you can walk into. Doors came next, each door a
data-tonaming 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). - 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. - Tree houses: up to six houses by number, a round room on top, bridges, ladders and hatches;
B.insidebecame "which house". - A world to walk: a grid of squares, each a place kind (
W.cells["c,r"],D4on 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). - 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.
- 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.
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:
Names that can't collide#
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:
- Places are named by where they are, and do not move:
world(start)(square(E4))(castle(N))(room(3)). - A thing or person is named once, when it is made, by its owner and a name unique there (
lever(L), or the next freeshell(10)), and keeps that name for good: it is an id, not a location. - Where it is now is a field:
Placed(owner),SetAside(the world's buffer of things taken out, to be put back as themselves), orCarried(person). - A template is a kind, placed nowhere:
place(castleroom).style(trap),lever,person(costume(ninja)). Making an instance from it mints a name; putting a set-aside one back does not.
state.peopleAway, each with an optional place); a thing taken out of a place is simply gone.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:
| today | proposed |
|---|---|
| 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 room | Pull(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#
- Decide the symbol syntax (calls,
world(start)(square(E4)), as above) and the list of kinds, from the vocabulary table: one word each for a world, a square, an inside, a room. - Give every placed thing a name when it is placed (and the default world's 68 things one each), and keep it through moves; a thing's index stops being its id.
- Write
RuleStatefor the tree room first, the smallest, with the game building it from addresses, beside today'sGlobals; then the trap room. - Add the world's buffer of set-aside things, as
peopleAwayis for people. - Parse and print symbols in Hazel (
parse_sym,print_sym, supposed here): a rule writesparse_sym("world(start)(square(E4))")and gets the tree, with no constructor names. - Later, if strings and helper calls wear thin: symbol literals in Hazel, as Fumola has today (
`world(`start)(`square(`E4))): the parser reads the tree directly, soparse_sym("...")becomes a literal, checked when the program is, with its names highlighted in the tiles. - Show addresses in the event log, so a change reads
…house(1).hatch: shut → open.
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#
- The numbers, for programs too: every table in this report, and what its numbers measure, is also in this page as JSON, in its
<script type="application/json" id="report-data">element, so a reader or an agent that fetches the page alone has the dataset. The same, with any raw files that survive, is in033/data/.