# 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-decl> ::= "location" <identifier> "{" <field>* <prose-block>* "}"
```

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
