World & rooms

Rooms

How the interior of every building is built from mod data, and how to change or add a venue's rooms.

Every interior in Underlives is assembled at runtime from mod files: the shell (walls, floor, ceiling, doors, windows), the furniture, the lights. Nothing is a hand-built Unreal level. Change the files and every café in every city changes with them.

modder

Which furniture a bar gets, where the counter goes, how many ceiling lights hang in a gym: all of it is a grammar or a recipe in Rooms/. The engine only knows how to solve and render them.

The four kinds of file

File Where Says
.ulroom (a recipe) Rooms/<name>.ulroom For one venue tag: the shell kit, which furniture sets to use, and how (preset or grammar)
.ulgrammar (a grammar) Rooms/Grammars/<name>.ulgrammar The shape of a kind of room: which zones exist, what goes in each, where
A set Rooms/Sets/<Set>/ A furniture set: one .glb per piece, plus their catalog and the groups built from them
.ulroomlayout (a layout) Rooms/Layouts/ or saved games An exact arrangement of furniture, from the room editor

When the player enters a building, the game finds the recipe for its venue tag, picks a dominant style from the building's seed, and either reposes a whole authored set or composes the room from the grammar. The same building always gets the same room.

Recipes: .ulroom

lua-- Rooms/arcade.ulroom
local KIT_FILE = "GenericKit/kit_worn.glb#"
local function M(node) return KIT_FILE .. node end

return {
	AMENITY = "arcade",
	PERSONALITY = { CLEANLINESS = 0.4, CLUTTER = 0.8, DECORATION = 0.4 },

	-- A building either reposes one authored set as-is…
	LAYOUT = {
		SETS = { "Sets/UndergroundGame" },
		USE_SET_WALLS = false,
	},
	PRESET_CHANCE = 0.5,
	-- …or is composed by a grammar from groups mined out of these sets.
	GENERATE = {
		GRAMMAR = "games_hall",
		SETS = { "Sets/UndergroundGame" },
		EXTRA = { "Sets/CasinoHall", "Sets/Bowling", "Sets/SportsBar" },
	},

	KIT = {
		FLOOR = M("Floor_Tile"), CEILING = M("Ceiling_Tile"), WALL = M("Wall"),
		WALL_WINDOW = M("Wall_Window"), WALL_DOOR = M("Wall_Door"), DOOR = M("Door_Leaf"),
		PILLAR = M("Pillar"), CEILING_LIGHT = M("Ceiling_Light"),
		TILE = 200, WALL_HEIGHT = 250, WINDOW_EVERY = 2, FACING = 0,
	},

	POOLS = {},
}
Field Meaning
AMENITY The venue tag this recipe is for. A later mod's recipe for the same tag replaces it.
PERSONALITY CLEANLINESS, CLUTTER, DECORATION from 0 to 1: how tidy, full and decorated the place feels
LAYOUT.SETS Authored sets a building may repose whole, one picked per building
LAYOUT.USE_SET_WALLS Keep the set's own walls instead of the generated shell
GENERATE.GRAMMAR The grammar that composes the room
GENERATE.SETS Sets that can be the building's dominant style
GENERATE.EXTRA Sets that only lend groups the dominant one lacks
GENERATE.ROOMS For multi-room venues: { { "living", "home_living" }, { "bedroom", "home_bedroom" }, … }, each room with its own grammar. The first is where the player enters; each other room gets a door.
PRESET_CHANCE With both LAYOUT and GENERATE: the share of buildings that get an authored set; the rest are composed
CROWD Optional { MIN = 2, MAX = 6, AREA = 8 }: strangers in the room, one per AREA m² of floor the furniture leaves free, kept between MIN and MAX. Each field left out uses the venue size's default (max 2 / 4 / 7 / 8 from small to institutional, min 1 for small rooms and 2 otherwise, 8 m²). No room ever holds more than 10. How many people a venue holds in the town simulation, and who walks in and out while the player is there, is Map/venue_capacity.json and Animations/ambient.json (people who come and go)
KIT The modular shell: node names in a .glb kit ("file.glb#Node"), the tile size and wall height in cm, a window every N wall tiles. By default the ceiling grid hangs a light borrowed from the furniture sets, for variety; OWN_CEILING_LIGHT = true hangs the kit's own CEILING_LIGHT instead (the hospital keeps its ceiling panels this way)

The shipped kits live in ul_Base/Rooms/GenericKit/ (kit_apartment.glb, kit_bar.glb, kit_worn.glb…) and can be referenced from any mod's recipe.

Open-air sites

A park, a beach or a forest is a room without walls; a back alley is walls without a roof (ROOFLESS, below). OPEN = true in the KIT turns the shell into an open site:

  • the kit's floor becomes the ground, painted by the look's floor_texture, and it runs on for kilometres past the plot;
  • no walls, ceiling, windows, doors, pillars or ceiling lights are built, and lighting zones are skipped;
  • the sun and the sky light the site, with a brighter sky fill than indoors;
  • the camera stands back off the plot.

A street can be a site too: bus_stop.ulroom and taxi.ulroom are a stretch of pavement with the shelter, the rank sign, bins and bollards along the far edge, and street lamps, plane trees and house fronts scattered beyond it.

luaKIT = {
	OPEN = true, SEA = "back", SHORE = 450,
	FLOOR = M("Floor_Tile"), WALL = M("Wall"),
	TILE = 200, WALL_HEIGHT = 250, WINDOW_EVERY = 0,
	SCATTER = {
		{ LEAD = "Nature/Tree", MATCH = { "Palm" }, COUNT = 25, NEAR = 150, FAR = 2500 },
		{ LEAD = "Nature/Backdrop", MATCH = { "Mountain" }, COUNT = 6, NEAR = 3500, FAR = 9000 },
	},
},
Field Meaning
OPEN true for an open-air site
ROOFLESS true for walls without a ceiling: a back alley, a yard, a light well. The shell is built as a closed room (its door on the street side, windows only if WINDOW_EVERY asks), but no ceiling or ceiling lights are hung and the sky lights it like an open site. alley.ulroom uses it with WALL_HEIGHT = 650
SEA "back", "front", "left" or "right": a sea on that side, with waves, surf and wet sand, out to the horizon. The ground stops at the waterline and the camera faces the water
SHORE Distance in cm from the plot's edge to the waterline (default 450)
RIVER Width in cm: the water on the SEA side becomes a calm river that wide, below its banks, with the far bank beyond
SCATTER Scenery strewn in a ring around the plot, picked from the recipe's sets. Nothing is placed between the camera and the plot, or in the water. Each entry takes:
• LEAD and MATCH, as a grammar zone;
• COUNT;
• NEAR and FAR, the ring in cm measured from the plot's edge (points crowd toward NEAR);
• SCALE = { min, max }.
Entries with NEAR of 2000 or more are far scenery: they are placed only on the side the camera looks at, measured to their own edge. Use them for Nature/Backdrop mountains, hills and tree lines

The grammar's wall and corner bands become the site's edges. It should have no ceiling zone.

Multi-room venues

luaGENERATE = {
	GRAMMAR = "home",
	ROOMS = { { "living", "home_living" }, { "bedroom", "home_bedroom" }, { "kitchen", "home_kitchen" }, { "bathroom", "home_bathroom" } },
	SETS = { … },
},

"home:bedroom" addresses one room of a multi-room venue directly.

The rooms need not share a grammar family: brothel.ulroom opens on a brothel_lounge (reception, sofas, price board) with a hotel_room off it, and newsroom.ulroom puts a news_studio (anchor desk, cameras, green-screen cove) next to the newsroom floor. Each extra room's own set list, the third entry of its pair, is where its special pieces come from.

Grammars: .ulgrammar

A grammar describes a kind of room as zones. The solver fills each zone with furniture groups from the recipe's sets, scoring every candidate spot.

lua-- Rooms/Grammars/bar.ulgrammar (abridged)
return {
	NAME = "bar",
	ZONES = {
		{ NAME = "lighting", LEAD = { "Lighting/CeilingLight", "Lighting/Chandelier" }, PLACE = "ceiling",
		  COUNT = { 2, 4 }, DUPES = true, ANY = true, HUNG = true },
		{ NAME = "bar", LEAD = { "Counter/Bar", "Counter" }, PLACE = "wall", REQUIRED = true, ANY = true, MAX_WIDTH = 900,
		  PREFER = { FAR_FROM_DOOR = 1.0, AWAY_FROM_WINDOW = 0.8 } },
		{ NAME = "back_bar", LEAD = { "Storage/Shelf", "Display/Rack", "Appliance/Fridge" }, PLACE = "wall",
		  COUNT = { 0, 3 }, DUPES = true, CHANCE = 0.9, HUNG = true, ANY = true, PREFER = { NEAR = "bar" } },
		{ NAME = "stools", LEAD = { "Seating/Stool" }, PLACE = "free", COUNT = { 0, 4 }, DUPES = true,
		  CHANCE = 0.7, STANDALONE = true, PREFER = { NEAR = "bar" } },
	},
}

Zone fields

Field Meaning
NAME The zone's name (other zones refer to it in PREFER)
LEAD What the group is built around: "Category" or "Category/Type" of its main piece (see Naming and kinds). A Type is one kind of object, so "Fixture/BondageCross" is only crosses; list several kinds for a zone that takes several
ROLES Only groups mined from these room roles ("bedroom", "kitchen"…)
PLACE "wall" (default), "corner", "free" (in the open floor), "ceiling" or "aisle" (back-to-back rows down the room's long axis, the way a warehouse or a supermarket stands its racking and gondolas; the only open-floor place that takes pieces 2.2 m tall and 1.8 m long)
AISLE With PLACE = "aisle": walkway width in cm between rows and at the row ends (default 200, minimum 80)
REQUIRED The room is not valid without it
COUNT { min, max } groups (default one)
CHANCE Probability the zone is filled at all (default 1)
DUPES May place a kind of furniture the room already has (a wall of shelves)
REPEAT Every placement after the first takes the same model when it fits (one pendant model across a ceiling)
LEAD_ORDER LEAD is a preference order: an assembly matching an earlier entry always wins over a later one (the cafe takes a bar counter or a whole counter wall, Counter/Bar, before any other Counter)
MATCH Of the pieces LEAD allows, only those whose name contains one of these words: LEAD = { "Fixture/Sling" }, MATCH = { "Sling_Frame" } keeps the framed slings and leaves out the ones hung from a hook
NOT_MATCH Leaves out the pieces whose name contains one of these words, after MATCH: MATCH = { "Appliance_Washer" }, NOT_MATCH = { "Commercial" } keeps the home washers only
STANDALONE Wants single pieces rather than composed groups
ANY Single pieces and groups are equally welcome
HUNG Accepts wall-hung groups (high shelves, mirrors)
MAX_WIDTH, MAX_HEIGHT Size caps in cm (keeps a 7 m diner counter out of a home kitchen)
MIN_AREA Only in rooms of at least this many m²
PREFER Soft preferences with weights: FAR_FROM_DOOR, NEAR_DOOR, NEAR_WINDOW, AWAY_FROM_WINDOW, CORNER; and NEAR, FACES, OPPOSITE naming another zone

Grammar fields

Field Meaning
NAME The grammar's name (recipes refer to it)
EXTENT { x, y }: half-size of the room in cm, instead of the building's size tier
KIT_FILE Another kit .glb for this room (a tiled bathroom inside an apartment)
FLOOR_TILE The floor must be tile or stone (wet rooms)
WINDOW_EVERY Override the kit's window spacing (0 = no windows)
SCORE Weights for the whole layout: OPEN_CENTRE, WALL_COVERAGE, CAMERA
tip

Always give a grammar a lighting zone with PLACE = "ceiling". It is how a composed room gets real light fixtures of its own; without one, it is lit only by a generic ceiling grid.

Sets: furniture

A set is a folder under Rooms/Sets/. The base game's sets are all generated (Gen*): GenCore holds every piece, and the use sets (GenHome, GenFood, GenNight…) and their style variants (GenHome_WoodLight…) hold the pieces for one kind of venue.

textRooms/Sets/GenFood/
├── Pieces/GenFood/<Piece>.glb   -- one model per piece, named after it
├── Pieces/GenFood/<Piece>.ulmat -- its surfaces, moving parts and restraint points
├── catalog.ulset                -- per piece: category, type, size, height off the floor, wall-hung or not
└── assemblies.ulset             -- the groups the solver places (single pieces and composed groups)

Naming and kinds

A piece's name is Category_Type_Descriptors, and its kind is Category/Type:

  • Category is one of Seating, Table, Desk, Bed, Storage, Counter, Display, Appliance, Lighting, Fixture, Arch, Decor, WallDecor, Textile, Rug, Plant, Nature, Product, Wear.
  • Type is the object itself, never the venue: Seating_BarStool_Saddle_Reception, Fixture_Turnstile_Tripod, Appliance_Dishwasher. A specialised object has its own Type, so a dining room asking for Seating/Chair never gets a dentist's chair (Seating/DentistChair) or a wheelchair (Seating/Wheelchair).
  • Descriptors tell pieces of one kind apart: model, material, size, venue, state (_Open, _Lit). British spelling, no real brand names.

Lights: Lighting/CeilingLight, Pendant and Chandelier hang from the ceiling; FloorLamp, TableLamp, WallLight, Neon, StreetLight and Floodlight do not.

  • catalog.ulset lists every piece with its category, type, size (cm), centre, height off the floor and whether it hangs on a wall. Generated pieces also carry surface (the top's height in cm) and levels, every flat surface a small object can stand on: [[z, x0, y0, x1, y1, clear], ...] in cm from the piece's origin, lowest first, with z the height, x0..x1 / y0..y1 the usable rectangle (x to the piece's right, y to its back, the front is at -y) and clear the free height above it (200 when nothing is above). A bookcase has one level per shelf; a coffee table its top and the shelf under it. Room dressing puts objects on them. The levels of a cupboard, fridge or wardrobe that lie below its top are its inside shelves: home storage stands the things you keep on them.
    • A moving part listed under parts can have its own levels, in the same space and measured with the part closed. These are a drawer's floor, a freezer basket, the racks on the inside of a fridge door. For an open drawer, add its slide (axis × hi cm). For a door, turn the level about the part's pivot_cm and axis.
    • rails lists the bars that clothes hang on, in wardrobes and on clothes rails: [[z, x0, y0, x1, y1, drop], ...] in cm, in the same axes as levels. z is the top of the bar, where a hanger's hook rests. (x0, y0)–(x1, y1) are its two ends. drop is the free height under it, down to the wardrobe floor, a shelf or the floor. A wardrobe with a shirt rail over a trouser rail has two entries. The same rails are written in the piece's .ulmat.
  • assemblies.ulset lists the groups: an id (G_<Piece> for a single piece, C_… for a composed group), a kind (a single piece's kind, or its lead piece's kind plus what the group adds: Table_DiningTable+4Seat, Counter_KitchenUnit+3), a room role, the lead piece, the nodes it contains, its footprint and facing, and interaction slots. surface is the top of the piece's main horizontal surface in cm above the floor (the seat of a chair, the mattress of a bed, the top of a table), measured from the mesh as seen from above. Scenes use it to find a seat or a couch of the height a position was made for (Rooms/SceneHeights.json), since size includes the backrest. "ceiling": true marks a group that hangs from the ceiling: the room lifts it under its own ceiling and does not count its footprint. Without the field, a Lighting lead of type CeilingLight, Pendant or Chandelier hangs.
  • Groups are looked up by the set's folder, and referenced from layouts as set + id.

Any recipe in any mod can use the base game's sets.

Surfaces of the generated furniture: .ulmat

The Gen* sets ship one .glb per piece under Pieces/, with no textures inside. Beside each .glb, a .ulmat file (JSON) gives every material zone of the piece its surface. The scan textures live in Textures/Scans/<id>/ (diffuse.jpg, normal.jpg, rough.jpg) in any mod, and are projected onto the piece, so the mesh needs no UVs. Edit a .ulmat to retint or refinish a piece without touching its mesh.

json{ "zones": {
  "Wood": { "scan": "walnut_veneer", "tint": [0.62, 0.45, 0.30], "scale": 1.0,
            "rough": 1.0, "metal": 0.0, "coat": 1.0, "coat_rough": 0.16 } } }
Field Meaning
scan Scan folder id, or null for a plain colour
grey true uses the scan's colourless twin (diffuse_grey.jpg), so tint alone gives the colour
tint RGB multiplied over the scan, or the colour itself when there is no scan
scale Tiles per metre
rough Multiplies the scan's roughness (1 = as scanned), or the roughness itself for a plain zone
metal Metallic, 0 to 1
coat, coat_rough A varnish, lacquer or glaze film over the surface: its weight (0 to 1) and its own roughness. A veneer table is 1.0 / 0.16; leather 0.4 / 0.38. Leave them out for bare fabric, plaster or raw wood
emissive Glow strength, in the tint's colour (lamp shades, screens)
alpha Below 1 keeps the .glb's own see-through material (glass)
rails Top level, beside zones. The piece's hanging rails, as in catalog.ulset: [[z, x0, y0, x1, y1, drop]] in cm, where z is the top of the bar, (x0, y0)–(x1, y1) are its ends and drop is the free height under it. Add an entry to let the game hang clothes on a bar of your own furniture
grips Top level, beside zones. Where a hand takes the piece when a person picks it up: [{"name": "Main", "kind": "power", "hand": "any", "pos_cm": [3.8, 0, 10], "normal": [1, 0, 0], "fingers": [0, -1, 0]}]. pos_cm is the point the palm rests on, normal the surface normal out of the object, fingers where the straight fingers point, kind how they close (power, pinch, tripod, key, hook, platform, spherical, trigger, two_hand, from the .ulgrips files). Without one, the game guesses the grip from the piece's size. Details under Touches, Grips
rig Top level, beside zones. A bendable piece's skeletal twin: {"file": "<piece>__rig", "bones": 14, "clips": {"Hang": 1.0, "Crack": 1.0}}. file is a .glb beside the static (a skin plus one glTF animation per clip name); the game plays Hang on pick-up and the rest through Actor:heldClip. Details under Touches, Rigged things
points Top level, beside zones, not per zone. Named restraint points where a person's wrist, ankle or neck is tied to the piece: [{"name": "WristL", "kind": "ring", "pos_cm": [48.8, 5.5, 178.6]}]. kind is ring (tie-off ring), post (bed post or leg to tie round), hook (overhead hook) or bar (a rail or board a cuff clips onto). pos_cm is in centimetres from the piece's origin (floor centre), x right, y back, z up, front toward −y. Left and right are the tied person's own. Add or move entries to make your own furniture restrainable

At the top level, beside zones, "ao": true says the .glb carries contact shading in its vertex colour (COLOR_0, grey: 1 = open, darker = in a joint or under a seat). The game multiplies it into every zone of the piece. Leave it out when your mesh has no vertex colour, or the piece renders black.

warning

Packing a new set (writing its catalog.ulset and mining assemblies.ulset from a .glb) is done with tools that are not distributed yet. You can already reuse and recombine every shipped set in your own recipes and grammars; new furniture packs will follow once the packing tool is released.

Printed surfaces: menus, posters, labels

Picture frames, posters, menu boards, signs, cans, bottles, books and boxes have a surface the game prints an image on (the piece's material zone is named Canvas). Each piece placed in a room gets its own image, picked from Rooms/Canvas/:

textRooms/Canvas/
├── canvas.ulcanvas          -- which kind of image each piece gets
├── menu/cafe/*.jpg          -- <kind>/<venue>/: images for one venue type
├── menu/any/*.jpg           -- <kind>/any/: images for every venue
├── poster/any/ …
└── art/home/ …

canvas.ulcanvas is JSON:

json{
  "rules": [
    { "match": "Board_Menu|Chalkboard|A_Board", "kind": "menu" },
    { "match": "Picture_Frame|Picture_Canvas", "kind": "art" }
  ],
  "venues": { "coffee": "cafe", "pub": "bar" }
}
  • rules: the first rule whose match is found in the piece's name gives the kind. Alternatives are separated by |, and * matches anything. A mod's rules are tried before the base game's.
  • Venue: the room's tag (cafe, bar, home…), renamed through venues so several tags can share one folder.
  • Choice: the venue's own images count twice as much as those in any/. Among a few candidates, the image whose width / height is closest to the surface's wins, so make wide images for signs and wide labels for cans (about 2.4 : 1).
  • Images are .jpg or .png. To add yours, drop them into a folder in your mod with the same layout; there is nothing to register.

The kinds the base game uses: menu, poster, sign, art, graffiti (the painted wall pieces, WallDecor/Graffiti; the base images are spray tags, drop your murals in graffiti/any/ or graffiti/<venue>/), certificate, print (books, magazines, newspapers) and one label/<product> per kind of product: label/tin, label/drink_can, label/beer, label/wine, label/spirit, label/soft, label/sauce, label/cosmetic, label/pharma, label/cleaning, label/cup, label/takeaway, label/snack, label/grocery, label/tobacco, label/shopbag, label/money, label/card, label/casino, label/shop, label/street, label/machine (payphone and token-machine panels), label/audio (amplifier and stereo badges) and label/misc; and calendar (wall and desk calendar pages). A kind can be a path, so its images go in label/tin/any/ and so on. Labels on cans, tins, jars and bottles are unrolled: the image goes all the way round, so make them wide (2.4 : 1 for a can, 3 : 1 for a tin).

note

In Underlives' world, the brands on labels and ads belong to Underlives and Broken Human Studio. Keep real brands out of your images.

Layouts and presets

The room editor saves an exact arrangement of furniture as a .ulroomlayout (JSON):

json{
  "tag": "clothes",
  "grammar": "shop_fashion",
  "name": "Clothes Shop",
  "seed": 7,
  "placements": [
    { "set": "ClothingBoutique", "id": "A013", "x": -271, "y": 167.8, "yaw": 0, "zone": "racks" },
    { "set": "ClothingBoutique", "id": "A016", "x": 272.5, "y": 224.5, "yaw": 0, "zone": "counter" }
  ]
}
  • A layout in a mod, under Rooms/Layouts/, is a shared preset for venues with that tag. It only needs the sets it references to be installed.
  • seed (optional) pins the room itself: when the preset is forced (-RoomLayout=, cine.room layout=, Game:roomLayout) and no seed is given, the walls, windows, doors and style sets are rolled from this seed, so the room is the same every time. Without it only the furniture is pinned and the shell is rolled again at every visit. cine.saveroom writes the seed of the room it saw.
  • Layouts the player edits in their own game (build mode) are saved per building in the save slot, so two lives do not share one furnished home. Games saved before October 2026 copy the old Saved/RoomLayouts/ files into the slot the first time they are loaded. Outside a game (the room editor) layouts are still files under Saved/RoomLayouts/.
  • Layouts downloaded from the content hub land in Mods/lp_hub_downloads/Rooms/Layouts/.
  • A venue the player has changed (a thing taken, put down, moved or bought, or its shop's stock sold) keeps its furniture from then on. A building's room comes out of its seed, but the furniture also avoids what the rest of the city showed lately, so a building nobody touched can look different on the next visit. At the first change the save slot stores that venue's layout (every room of it, plus its style set), and later visits replay it instead of solving again; the dressing and the player's changes then go on top as usual. Untouched venues keep their variety and cost nothing in the save. If a mod you removed supplied a piece of a stored layout, that piece is left out and the rest of the room stays; if a room's grammar changed, that room is generated again.

Build mode and bought furniture

In a game, the player furnishes their home in build mode. Its catalog has three tabs: PIECES and SETS (the room's whole library) and OWNED, the furniture the player bought at a furniture shop, with how many of each they have.

  • Placing an owned piece uses one up; taking it out of the room again (delete, undo, or cancelling the placement) puts it back in the inventory.
  • A piece placed from OWNED is marked in the saved layout (its zone is "owned"), so the game knows which pieces were bought: the furniture that came with the home can be moved but never turns into something to sell.
  • OWNED also lists the small things the player carries that have a room piece (a .ulitem with Piece:, such as a table lamp or a radio bought off a shop's shelf), grouped by the piece's category and type, with how many they have. Picking one makes it follow the cursor: it stands on the top or a shelf of the furniture under it (the measured levels the dressing uses) or on the floor, and a click puts it there and takes one out of the inventory. These are not layout pieces: they are saved with the room like anything put down, in the save slot. A click on one the player put down picks it back up into the inventory and puts it on the cursor again; Escape or a right click keeps it in the inventory.
  • The standalone room editor has no player and no OWNED tab.
warning

Today a shared preset is applied to every building of its tag, not to a share of them. Ship a preset only for a tag you mean to fix to that one arrangement.

Checklist for a new venue type

  1. Add the tag to Map/amenities.json (Map and venues).
  2. Write Rooms/<tag>.ulroom pointing at existing sets and a grammar (reuse one of the 47 shipped grammars (hospital_reception, ward, delivery and er make up the generated hospital), or write your own in Rooms/Grammars/).
  3. Give the venue something to do: actions with the tag in WHERE (Actions).
  4. Optionally a look profile for its lighting and colours.
  5. Optionally a crowd profile so the strangers in it are the venue's own people, not anyone.