# Locations Locations define places in your world -- rooms, buildings, cities, landscapes, or abstract spaces. They provide spatial context for characters, events, and narratives. --- ## Syntax ```bnf ::= "location" "{" * * "}" ``` A location declaration consists of: - The `location` keyword - A unique name (identifier) - A body block containing fields and optional prose blocks Locations are one of the simpler declaration types -- they hold fields and prose blocks but do not support resource linking (`uses behaviors` / `uses schedule`) like characters or institutions. --- ## Basic Location The simplest location has a name and descriptive fields: ```storybook location BakersBakery { type: bakery capacity: 30 address: "14 Main Street" open_hours: "06:00-18:00" } ``` Fields can use any [value type](./18-value-types.md): integers, floats, strings, booleans, enums, lists, ranges, and durations. --- ## Fields Location fields describe properties of the place: ```storybook location BakerHome { type: residence bedrooms: 3 has_garden: true garden_size_sqft: 450.0 residents: ["Martha", "David", "Jane"] comfort_level: 0.85 } ``` ### Common Field Patterns | Field | Type | Description | |-------|------|-------------| | `type` | enum/identifier | Category of the place | | `capacity` | integer | How many can be in this place | | `size` | enum/float | Physical size | | `coordinates` | integer/float | Position in a world map | | `accessible` | boolean | Whether characters can enter | These are conventions, not enforced schema. You define whatever fields are meaningful for your world. --- ## Prose Blocks Locations support prose blocks for rich narrative content. Prose blocks are delimited by `---tag` markers: ```storybook location BakersBakery { type: bakery capacity: 30 ---description A warm, inviting bakery on Main Street. The smell of fresh bread wafts out the door every morning at dawn. Martha has run the shop for fifteen years, and the locals consider it the heart of the neighborhood. --- ---atmosphere Flour dust catches the light from tall windows. A display case holds rows of golden pastries. Behind the counter, the kitchen hums with activity from 4 AM onward. --- } ``` **Prose block rules:** - Start with `---tag_name` on its own line - Content is free-form text (Markdown supported) - End with `---` on its own line - The tag name becomes the key for retrieval - Multiple prose blocks per location are allowed - Each tag must be unique within the location --- ## Ranges Locations can use range values for procedural variation: ```storybook location MarketSquare { type: outdoor_market stalls: 10..25 daily_visitors: 50..200 noise_level: 0.4..0.9 } ``` When instantiated, values are selected from within the specified range. This is useful for locations that should vary across simulation runs. --- ## Lists Locations can hold list values: ```storybook location BakersBakery { type: bakery products: ["sourdough", "croissants", "rye bread", "cinnamon rolls"] equipment: ["stone oven", "mixing station", "proofing cabinet"] } ``` --- ## Referencing Other Entities Location fields can reference other declarations by name: ```storybook location BakersBakery { type: bakery owner: Martha neighborhood: MainStreet part_of: TownCenter } ``` These are identifier references -- they are not validated as cross-references at parse time, but the resolver checks that referenced names exist in the name table. --- ## Nested Structure with Fields You can model spatial hierarchy using fields: ```storybook location BakersBakery { type: bakery parent: MainStreet // Zones within the bakery has_kitchen: true has_storefront: true has_storage_room: true // Dimensions total_sqft: 1200 kitchen_sqft: 600 storefront_sqft: 400 storage_sqft: 200 } location MainStreet { type: street parent: TownCenter length_meters: 500 shops: 12 } location TownCenter { type: district population: 2000 } ``` There is no built-in parent-child relationship for locations -- you model hierarchy through conventional field names like `part_of`, `parent`, or `contains`. --- ## Location with Enum Fields Use [enums](./16-other-declarations.md#enums) for type-safe categorization: ```storybook enum PlaceType { residence, shop, workshop, office, park, street, square, church } enum Accessibility { public, private, restricted, members_only } location BakersBakery { type: shop accessibility: public capacity: 30 } location BakerHome { type: residence accessibility: private capacity: 8 } ``` --- ## Complete Example: Baker Family Locations ```storybook use schema::enums::{PlaceType, Accessibility}; location BakersBakery { type: shop accessibility: public owner: Martha address: "14 Main Street" capacity: 30 employees: 4 established: "2011" specialty: "artisan sourdough" daily_output_loaves: 80..120 ---description Martha Baker's artisan bakery, known throughout town for its sourdough and pastries. The shop opens at 6 AM sharp, and by mid-morning there's usually a line out the door. --- ---history Originally a hardware store, Martha converted the space after winning a local baking competition. The stone oven was imported from France and is the heart of the operation. --- } location BakerHome { type: residence accessibility: private address: "22 Elm Lane" bedrooms: 4 has_garden: true garden_size_sqft: 600 residents: ["Martha", "David", "Jane", "Tom"] comfort_level: 0.9 ---description A comfortable family home on a quiet street. The kitchen is oversized (Martha insisted) and there's always something baking, even at home. --- } location BakersGuildHall { type: office accessibility: members_only address: "7 Guild Row" capacity: 100 meeting_room_capacity: 40 established: "1892" ---description The historic headquarters of the Bakers Guild, where trade matters are discussed and apprenticeships are arranged. --- } ``` --- ## Validation Rules 1. **Unique names**: Location names must be unique within their scope 2. **Valid field values**: All fields must have values that conform to [value types](./18-value-types.md) 3. **Unique field names**: No duplicate field names within a location 4. **Unique prose tags**: No duplicate prose block tags within a location 5. **Valid identifiers**: Location names must follow identifier rules (`[a-zA-Z_][a-zA-Z0-9_]*`) --- ## Locations vs. Other Declarations | Aspect | Locations | Institutions | Characters | |--------|-----------|-------------|------------| | Purpose | Physical/abstract places | Organizations/groups | Individuals | | Resource linking | No | Yes | Yes | | Prose blocks | Yes | Yes | Yes | | Species | No | No | Yes | | Templates | No | No | Yes | Locations are intentionally simple. They define *where* things happen. For *who* does things, use [characters](./10-characters.md). For *organizational structures*, use [institutions](./16b-institutions.md). --- ## Cross-References - [Characters](./10-characters.md) -- Characters can reference locations via fields - [Institutions](./16b-institutions.md) -- Institutions can be associated with locations - [Schedules](./14-schedules.md) -- Schedule activities can reference locations - [Value Types](./18-value-types.md) -- All field value types - [Other Declarations](./16-other-declarations.md) -- Overview of all utility declarations - [Validation Rules](./19-validation.md) -- Complete validation reference