Rooms and runs
Play hand-made rooms as a roguelike run or lay them out as a continuous map with doors, keys and an exit: settings, documents, events, verbs, hooks.
Rooms, runs and maps in your game (world.rooms) #
What it is for #
world.rooms builds hand-made rooms with floors, walls, pillars, braziers and decor, and plays them in one of two layouts. In run (default), rooms are played one at a time and chained by a runs document: doors unlock when the room is cleared and preview the next reward. In map, every room of a maps document is laid out at once, with corridors, doors opened by clearing, by use or by a key, and an exit. It suits dungeons, crypts, houses, stations and castles. Enemies come from the encounter kits, and a bound level model or modular kit can replace the stone boxes.
Turn it on #
gripforge_gamekit_install { project_id: "gkp_…", id: "world.rooms" }
gripforge_gamekit_configure { project_id: "gkp_…", id: "world.rooms",
config: { "layout": "map", "map": "keep", "ceiling": true } }
It requires physics.rigidbody, physics.port and game.engine. A project without rooms plays the shipped Underworld run.
First example #
<!-- test: kits/game_engine/host/tests/world_rooms.rs::the_underworld_run_starts_in_the_vestibule --> In a project without room documents, the run starts in the vestibule:
{ "op": "call", "service": "world.rooms", "method": "run", "args": [] }
It answers { id: "run_descent", index: 1, count: 5 }. The room is 16 by 16 m, with four walls and a start reward; the door stays locked until the reward is picked up, then exit("north") enters room 2. A saved game restarts at room 1.
Settings and defaults #
| Setting | Type | Default | Meaning |
|---|---|---|---|
layout | string | run | run or map. |
run | string | run_descent | Runs document to play. |
map | string | empty | Maps document (the first when empty). |
seed | integer | 1 | Run seed for room pools and rewards. |
wallHeight | number | 3 | Wall height, metres. |
wallThickness | number | 1 | Wall thickness, metres. |
doorRadius | number | 1.4 | Distance from a door that takes the player through. |
pickupRadius | number | 1.3 | Reward pickup reach. |
startReward | boolean | true | Drop a boon reward in the start room. |
endOnDeath | boolean | true | End the run when the player dies. |
ending | string | run | none: nothing of this kit wins or loses the game (a house, a hub). |
cornerLights | boolean | true | Braziers in free corners of rooms without lights. |
ceiling, ceilingVisible | boolean | false | Map: an unseen solid lid; draw it. |
openLabel, exitLabel, lockedLabel | string | Open, Leave, Locked | Door and exit prompts. |
lockedMessage, exitMessage | string | Locked., Defeat every enemy first. | Messages on a refusal. |
modules, levelAt, levelExcept, levelNear, doorModel | Art options for modular kits and level models. |
Also windowNodes and skylightNodes. Nearly all settings are moddable.
Services, events, verbs, variables and data #
world.rooms(service):run(),current(),rooms(),doors(),enter(id, reward),exit(door),clear(),dropReward(reward, at),end(result), and for mapsopenDoor(id),closeDoor(id),doorOpen(id),roomCleared(id).world.ready,run.started,room.entered,room.cleared,door.unlocked,reward.dropped,reward.collected,run.ended(events).run.endedcarriesresultvictoryordeath.door.refused,exit.refusedandhud.notify(events): a map door or exit stayed shut, with a message for the HUD.open_door,close_door(actions) anddoor_open,room_cleared(conditions): script verbs.room.name,room.index,room.count,room.cleared,run.money,run.result(variables).rooms,runs,maps,module_kits(collections). A map hasrooms(room,at),links(fromandtoasroom.door,openamongcleared,interact,always,closed,key,when,consume,frame),startandexit(room,at,requiresamongenemies,rooms,none).
Hooks and modding #
| Hook | Mutable | Asked when |
|---|---|---|
room.enter | room | a room is about to be entered (a tap may name a secret room) |
room.reward | type, god, amount | a cleared room is about to drop its reward |
room.unlock | type, god, amount | a door unlocks and previews the next reward |
room.door | none | a map door is about to open |
run.exit | none | a player uses a map exit that would win |
All are cancellable. The rooms registry lets a document extend another to make a variant.
{ "id": "gold_rush", "hook": "room.reward", "priority": 0, "match": { "type": "money" }, "mul": { "amount": 2 } }
When it does not do what you expect #
- A door never opens: the room is not cleared, the player lacks the key or condition, or a
room.doortap cancelled it. - A refusal shows no message: read
door.refusedorhud.notifyin your HUD. - A run ends at once:
endOnDeathis on, or a boss room was cleared. Useending: nonefor a hub. - Walls are plain boxes: no level model or module is bound to the slots.
Limits #
A run or map holds at most 64 rooms; a map at most 128 links. Enemies and rewards come from other kits.
Versions #
Kit 1.19.1. 1.19.0 added per-room height, 1.18.0 polygon rooms, 1.8.0 the map layout, 1.6.0 the hooks.