Tutorial: Areas in Downbeat
An area is a named, concrete place that agents can inhabit — a town square, a harbor, a government hall, a restaurant. For downbeat, the entrance area is where the zine plays.
This tutorial is a reference. For narrative context on how areas work in the zine, see TUTORIAL-zines.md.
The Minimal Area Document
apiVersion: net.plantange/v1
kind: simulation.area
meta:
title: <Human name>
name:
common:
en: <machine_name>
uuid: <unique id>
That's the absolute minimum. The Rust parser requires apiVersion, kind, meta.title, and meta.uuid. Everything else is optional.
meta.name — Two Valid Forms
Area names can be written in two ways:
Plain string (simple, preferred for bare stubs):
meta:
name: entrance
Locale map (use when you need translated names):
meta:
name:
common:
en: entrance
Either form is accepted by the parser. Pick the locale map form when you know the name may need translation; use the plain string for quick stubs.
Optional Blocks
Areas grow richer by adding optional blocks. None are required, but each unlocks something at runtime.
space
Declares the physical shape and scale of the area:
space:
shape: point # point | circle | rectangle
scale: medium # small | medium | large | epic
orientation: horizontal # optional
For downbeat entrance, use shape: point (abstract) and scale: medium.
environment
Continuous field baselines — climate, atmosphere, sensory:
environment:
climate:
temperature: 18.5
humidity: 0.65
airflow: 0.3
pressure: 101.3
sensory:
light_level: 0.85
visibility: 0.9
noise_level: 0.4
odor_profile:
stone: 0.3
air: 0.7
Values are floats; most are 0.0–1.0. Omit any sub-field you don't need.
affordances
Typed activity declarations — what agents can do here:
affordances:
- type: area.activity.gather
class: social
inputs:
- agent.humanoid
- agent.ensemble
outputs:
- event.gathering
salience: 0.85
type uses dot-namespaced identifiers. class groups it semantically. inputs/outputs are content class hints. salience (0.0–1.0) weights how attractive this activity is.
constraints
Hosting limits:
constraints:
capacity: 500
content_types:
- agent
- item
- data
capacity caps total occupancy. content_types restricts what can be present.
corporation
Declares the governing institution of the area:
corporation:
type: townhall
standing: sovereign
name: Lobby Authority
| Field | Values | Notes |
|---|---|---|
type |
townhall, bank |
These are executable — runner creates service |
type |
guild_council, land_trust, port_authority, market_board, charter |
Spec-only for now — recorded but no handler |
standing |
sovereign, public, private |
Legitimacy regime |
name |
any string | Display name for the institution |
Omit corporation entirely for abstract spaces and lobbies that have no governing body.
A Minimal Entrance Example
# area/entrance.yml
apiVersion: net.plantange/v1
kind: simulation.area
meta:
title: Entrance Hall
description:
common:
en: "The grand entrance lobby where all players begin."
name:
common:
en: entrance
uuid: 019d8202-e322-76c6-1f0a2b3c4d5e6fa2
space:
shape: point
scale: medium
environment:
climate:
temperature: 18.5
humidity: 0.65
airflow: 0.3
pressure: 101.3
sensory:
light_level: 0.85
visibility: 0.9
noise_level: 0.4
odor_profile:
stone: 0.3
air: 0.7
affordances:
- type: area.activity.gather
class: social
inputs:
- agent.humanoid
outputs:
- event.gathering
salience: 0.85
No corporation block — entrance is a gathering place, not a legal seat.
A Staging Example — Antechamber
If you want NPCs to pre-stage before entrance (optional):
# area/antechamber.yml
apiVersion: net.plantange/v1
kind: simulation.area
meta:
title: Antechamber
name:
common:
en: antechamber
uuid: 019d8202-e322-76c6-1f0a2b3c4d5e6fa9
space:
shape: point
scale: small
No environment, no affordances. Antechamber is just a waypoint.
How Areas Connect to Regions
A region references its areas by UUID in features::
# region/lobby.yml
features:
- spec: 019d8202-e322-76c6-1f0a2b3c4d5e6fa2 # entrance
- spec: 019d8202-e322-76c6-1f0a2b3c4d5e6fa9 # antechamber
The UUID must match meta.uuid in the area doc exactly.
Area vs Region — When to Use Which
Use simulation.area when… |
Use simulation.region when… |
|---|---|
| It's a specific named place | It's a geographic zone |
| Agents concretely inhabit and act there | It defines terrain, climate, ecology |
| It may have a corporation / institution | It contains multiple areas |
| It's a leaf in the world graph | It's a parent in the world graph |
For downbeat:
- Area (entrance) = the specific hall where the zine plays (leaf)
- Region (lobby) = the overall entrance zone (parent)
Common Mistakes
| Mistake | Symptom | Fix |
|---|---|---|
Missing meta.uuid |
Parser error | Add a unique UUID under meta: |
kind: simulation.region in area/ folder |
Area handler rejects it | Change to kind: simulation.area |
Using unknown corporation.type |
Warning logged, no service | Use townhall or bank for executable; use roadmap names for spec-only |
space.shape not in valid list |
Parser error | Use point, circle, or rectangle only |
meta.name locale map missing common.en |
Name resolves as empty | Add common: en: <name> inside the map |
Affordance salience out of range 0.0-1.0 |
Behavior undefined; may clamp | Keep salience between 0.0 and 1.0 |