Elf Revel Wiki
Welcome to the comprehensive reference for Elf Revel, a colony sim where elves compose music, throw revels, and argue about art.
This wiki documents every game system in detail — exact formulas, tick-level behavior, hidden mechanics, and strategy advice. Whether you're a new player figuring out the controls or an optimizer calculating revel satisfaction scores, you'll find what you need here.
The Three-Tier Model
Elf Revel has three levels of intentionality:
- You (the Patron) — provide taste, artistic direction, and broad guidance via the chat panel and keyboard commands
- The AI Advisor (Curator) — translates your preferences into concrete cultural policies: role assignments, revel scheduling, build orders
- The Elves — execute autonomously at the tick level: gather resources, compose music, attend revels, form relationships
The human has taste, the AI has hands, the elves have lives.
How to Use This Wiki
New players — start with Controls and Your First Settlement.
Understanding mechanics — each system page in Core Systems and Art & Culture covers mechanics from overview down to exact formulas.
Optimizing play — the Strategy Guides connect game systems into practical advice.
Every page follows the same structure:
- Overview — what the system does
- How It Works — mechanics description
- Values & Formulas — tables with exact numbers from the source code
- Interactions — how it connects to other systems
- Tips — practical advice
Game Timing
All game mechanics run on ticks. One day = 100 ticks. One season = 25 days. One year = 100 days (4 seasons). The game starts in Spring.
Controls
Complete keybinding reference for Elf Revel. The game is controlled entirely via keyboard.
Core
| Key | Action |
|---|---|
Space | Pause / Resume simulation |
+ / = | Speed up (1x → 2x → 4x → 8x) |
- | Slow down |
Arrow keys | Pan map (when map focused) |
Tab | Cycle focus: Map → Chat → Events |
BackTab (Shift+Tab) | Cycle focus backward |
Esc | Close overlay / deselect / back |
Ctrl+C | Quit |
? | Help overlay (press any key to close) |
Elf Selection
| Key | Action |
|---|---|
1-9 | Select elf by number |
, | Cycle to previous elf |
. | Cycle to next elf |
Enter | Open elf detail popup (when elf selected) |
Screens (Full Overlays)
Each screen opens a full overlay. Press the same key again or Esc to close. You can switch directly between screens by pressing another screen key.
| Key | Screen | What It Shows |
|---|---|---|
s | Settlement Overview | Population, resources (Wood/Stone/Food/FineWood), buildings, daily production rates |
a | Art Gallery | All compositions with genre, quality, properties, titles, descriptions |
x | Relationships | Elf-to-elf bonds (friends, rivals, mentors) with relationship strength |
v | Revel History | Past revels: when they happened, who attended, what was performed, satisfaction |
b | Build Management | Build queue: pending and completed buildings with progress |
w | Work Assignments | Elf-by-role grid for reassigning roles |
All screens support Up/Down to scroll.
Work Assignments Screen
The Work Assignments screen (w) uses a cursor-based grid:
| Key | Action |
|---|---|
Up/Down | Select elf row |
Left/Right | Select role column |
Enter | Assign the selected role to the selected elf |
Current assignment shows as [X] in green. Cursor cell is highlighted in cyan.
Panels & Modes
| Key | Action |
|---|---|
r | Toggle roster sidebar (list of all elves with mood indicators) |
e | Toggle events panel (scrolling settlement event log) |
l | Enter look mode (inspect tiles on the map) |
Look Mode
In look mode, a cursor appears on the map for tile inspection:
| Key | Action |
|---|---|
Arrow keys | Move look cursor |
w/a/s/d | Pan camera (WASD) |
Enter | Select elf at cursor position |
n | Name the location at cursor position |
, / . | Cycle elves (from cursor) |
Esc or l | Exit look mode |
Chat (AI Advisor)
| Key | Action |
|---|---|
/ | Open chat input (from map focus) |
Tab → type | Focus chat panel, then type freely |
Enter | Send message to the curator |
Esc | Cancel / close chat input |
Up/Down | Scroll message history (when chat focused) |
See How the Curator Works for what the advisor can do.
Actions
| Key | Action |
|---|---|
d | Cycle artistic direction: Balanced → Favor Mastery → Favor Originality → Favor Emotion |
i | Watch/unwatch selected elf (marks for tracking in detail view) |
f | Toggle favorite on selected composition (in elf detail) |
j/k | Navigate between compositions (in elf detail) |
Tips
- Pause often (
Space) — the simulation runs even while you browse screens - Events panel (
e) is the most informative panel — it shows compositions, relationships, mood shifts, spirit warnings, and season changes - Name locations via look mode (
l→ navigate →n) — named spots persist and appear on the map
UI Guide
The main screen is a terminal interface with several panels and overlay screens.
Main View
Map (Center)
The map shows your settlement on a procedurally generated terrain grid. Elves are colored letters moving across the landscape.
| Glyph | Meaning |
|---|---|
| Colored letters | Elves (each has a unique color) |
. | Meadow |
# | Stone |
~ | Water |
T | Ancient Forest |
t | Young Forest |
= | Wall (player-built) |
| Building glyphs | Dwellings, Workshops, Gardens, Feast Halls |
See Terrain for full details on each tile type.
Status Bar (Top)
Displays the current game state at a glance:
- Season and day: e.g., "Spring Day 12 (Day)"
- Weather icon: current weather condition
- Curator mode: which advisor is active (Dummy or LLM)
- Speed: current simulation speed (1x-8x)
- Pause indicator: shows when paused
Footer Bar (Bottom)
Shows resource counts (Wood, Stone, Food, FineWood) and a condensed status line with season and temperature.
Elf Detail Panel (Right, when selected)
Select an elf (1-9 or ,/.) then press Enter to see:
- Mood — current morale state and active modifiers
- Needs — bar display for Rest, Sustenance, Beauty, Stimulation, Company
- Current task — what the elf is doing right now
- Skills — Music, Building, Gathering levels with XP progress
- Compositions — portfolio of works (navigate with
j/k, favorite withf) - Relationships — bonds with other elves
- Aesthetic position — four-axis position (structure, tradition, emotion, social)
Events Panel (Right, toggle with e)
A scrolling log of settlement events:
- Composition completions
- Relationship changes (new bonds, breakups, mentoring)
- Mood shifts and need warnings
- Revel announcements and results
- Forest spirit warnings
- Season changes and notable weather
- Departure warnings and departures
Roster Sidebar (Right, toggle with r)
List of all elves with mood indicator icons. Quick way to scan settlement morale at a glance.
Overlay Screens
Press any screen key to open a full overlay. Overlays replace the main view until closed with Esc or by pressing another screen key.
Settlement Overview (s)
Population count, resource stockpiles with daily production/consumption rates, and a list of completed and in-progress buildings.
Art Gallery (a)
Every composition in the settlement, showing:
- Title (three-part procedural name)
- Composer
- Genre family and base type
- Quality scores (mastery, originality, emotional)
- Properties (up to 15 attributes)
Relationships (x)
Grid of all elf-to-elf bonds with type (Friend, Rival, Mentor) and strength value. See Relationships.
Revel History (v)
Record of past revels: date, location, attendees, performances, and audience satisfaction. See Revels.
Build Management (b)
Build queue showing pending construction with progress bars, plus completed buildings.
Work Assignments (w)
Interactive elf-by-role grid. Cursor navigation to reassign elves between Gatherer, Builder, Composer, and Unassigned. See Roles.
Chat Panel (Bottom)
The chat panel shows your conversation with the AI cultural advisor. Press / or Tab to focus, type a message, and press Enter to send.
The curator responds based on settlement state and your artistic direction. See How the Curator Works.
Your First Settlement
A walkthrough of your first game session, covering what happens in the first 50 ticks and the key decisions that shape your colony.
Starting State
When you begin a new game, you have:
- 5-8 elves with randomized skills, aesthetic positions, and starting needs
- Resources: a small starting stockpile of Wood, Stone, and Food
- No buildings — your elves are in the open
- Season: Spring (the most forgiving season — resource regeneration is doubled)
- Forest Spirit: at 0 (Harmony)
The Dummy Curator is active by default and will auto-assign initial roles based on each elf's highest skill.
First 25 Ticks: Establish Basics
Priority 1: Check Your Elves
Press 1-9 to select each elf, then Enter to see their detail panel. Note:
- Who has the highest Music skill? They should be composing.
- Who has the highest Gathering skill? They should be gathering.
- The curator usually handles this, but check the Work Assignments screen (
w) to verify.
Priority 2: Watch the Events Panel
Press e to open the events panel. Early events tell you what's happening:
- Role assignments from the curator
- Elves starting to forage and gather
- Social interactions as elves meet each other
Priority 3: Start Building
The curator will typically queue a Dwelling first (10 Wood). Dwellings provide shelter and faster rest recovery (+5/tick vs. base rate). Check the Build Management screen (b) to see the queue.
If you have a Builder-role elf, they'll start quarrying stone and constructing automatically.
Suggested early build order:
- Dwelling — shelter from weather, faster rest
- Workshop — composing station, stimulation boost
- Garden — beauty +3/tick, calms forest spirit -2/dawn
Ticks 25-50: First Compositions and Social Bonds
Compositions Begin
Composer-role elves will start creating music once they have enough inspiration. Watch for "composed" events in the event panel. Early compositions are typically low quality (skill level 1-3), but they improve as elves gain XP.
XP note: each level costs level × 50 XP. A level 1 elf needs just 50 XP to reach level 2. See Skills.
Relationships Form
Elves form bonds through proximity and shared experiences. After ~25 ticks, you'll see Friend and occasionally Rival relationships appearing. Elves with similar aesthetic positions bond more easily. See Relationships.
Watch the Needs
Needs decay continuously:
| Need | Decays Every | Watch For |
|---|---|---|
| Rest | Every tick | Elves auto-rest when low |
| Sustenance | Every 4 ticks | Need food stockpile > 0 |
| Beauty | Every 2 ticks | Gardens and forest terrain help |
| Stimulation | Every 2 ticks | Social events and composing |
| Company | Varies | Proximity to friends |
If any elf's morale drops below 50 (Stressed tier), they'll appear with a warning indicator in the roster (r).
First Revel
The Dummy Curator schedules a revel when:
- A Feast Hall exists (15 Wood, 5 Stone), or the curator decides to hold one anyway
- Food stockpile is sufficient (>= 5, or >= 15 in Winter)
- Cooldown from last revel has expired
Revels are the core social event — they satisfy Beauty and Stimulation needs, generate mood modifiers, and reveal how your elves react to each other's compositions.
See Revels for the full lifecycle.
Key Milestones
| Milestone | When | Why It Matters |
|---|---|---|
| First Dwelling built | Ticks 10-30 | Shelter from rain/storms, faster rest |
| First composition | Ticks 15-40 | Art system is active |
| First relationship | Ticks 20-50 | Social bonds affect mood and aesthetics |
| First revel | Ticks 40-80 | Settlement-wide celebration |
| Food stockpile > 15 | Before Winter | Curator won't schedule winter revels without it |
What to Watch For
- Forest Spirit: if you clear too much forest, the spirit meter rises. Stay below 20 for Harmony. See Forest Spirit.
- Discontented elves: if an elf shows the discontented indicator, their satisfaction has been low for 300 ticks. You have 500 more ticks before they depart. Prioritize their needs.
- Seasonal shift: Winter starts at day 75. Foraging drops to ×0.5 (halved again with snow). Summer (×1.5) and Autumn (×1.25) are your stockpiling windows. See Seasons & Weather.
Tips for New Players
- Pause early and often (
Space) — take time to explore screens and understand the UI - Don't clear Ancient Forest unless necessary — it gives the most wood but angers the spirit the most (+5 anger, +7 in Spring)
- Gardens are powerful — +3 beauty/tick for nearby elves AND -2 spirit anger/dawn, even in Winter
- Let the curator work — the Dummy Curator makes reasonable decisions. Override via Work Assignments (
w) only when you disagree - Use artistic direction (
d) to guide the colony's cultural output without micromanaging
Needs & Mood
Overview
Every elf has five basic needs and a mood stack that together determine their morale -- the single number (0-100) that governs behavior, work speed, and departure risk. Needs decay at different rates; mood modifiers stack additively; and morale tiers have hysteresis bands to prevent flickering when an elf hovers near a boundary.
How It Works
Needs
Needs live on a 0-100 scale. Each need decays automatically every tick (or every Nth tick). When a need drops below a threshold, the elf's behavior tree redirects them toward satisfying it before doing productive work.
| Need | Initial Value | Decay Rate | Decay Frequency |
|---|---|---|---|
| Rest | 100 | -1 | Every tick |
| Sustenance | 100 | -1 | Every 4th tick |
| Beauty | 60 | -1 | Every 2nd tick |
| Stimulation | 60 | -1 | Every 2nd tick |
| Company | 50 | varies | Every 2nd tick (personality) |
(Source: src/sim/components.rs, Needs::full();
src/sim/systems.rs, rest_decay_system(), sustenance_decay_system(),
beauty_decay_system(), stimulation_decay_system(), company_system())
Need Status Labels
The game displays a named tier for each need value:
| Value Range | Label | Compact Char |
|---|---|---|
| 80-100 | Fulfilled | + |
| 50-79 | Fine | ~ |
| 20-49 | Wanting | - |
| 0-19 | Critical | ! |
(Source: src/sim/components.rs, need_label(), need_char())
Company (the 5th Need)
Company is unique: its behavior depends on the elf's Social aesthetic axis (0.0 = Personal, 1.0 = Social).
| Social Axis | Behavior | Recovery |
|---|---|---|
| > 0.7 (Social elf) | Decays -1 per cycle toward 0 | +2 when >= 2 elves within 3 tiles |
| < 0.3 (Personal elf) | Rises toward 100 (wants solitude) | -2 when alone; +1 when >= 3 within 5 tiles |
| 0.3-0.7 (Middle) | Gentle pull toward 50 | +1 if below 50; -1 if above 50 |
The proximity check uses Manhattan distance. Company ticks every 2nd tick, same as Beauty and Stimulation.
(Source: src/sim/systems.rs, company_system())
Mood Stack
Mood is a collection of active MoodModifiers. Each modifier has:
description-- human-readable label (e.g. "Ate a meal")value-- signed integer bonus/penalty (i8)ticks_remaining-- countdown to expiry
Every tick, the mood system decrements ticks_remaining by 1 and removes
expired modifiers. Modifiers stack additively.
Morale is computed as:
morale = clamp(base + sum(modifier.value), 0, 100)
where base = 50 (constant).
(Source: src/sim/components.rs, Mood::compute_morale(), Mood::net_mood())
Common Mood Modifiers
| Source | Value | Duration (ticks) |
|---|---|---|
| Ate a meal | +5 | 50 |
| Slept in dwelling | +3 | 100 |
| Slept on ground | -3 | 50 |
| Caught in rain (outdoors) | -1 | 50 |
| Snow-covered landscape | +2 | 50 |
| Awed by ancient grove | +2 | 200 |
| Grieving (mourning) | -5 | mourning duration |
| Spring optimism (seasonal) | +2 | 1 day (100 ticks) |
| Autumn melancholy (seasonal) | -1 | 1 day (100 ticks) |
| Winter stillness (seasonal) | -1 | 1 day (100 ticks) |
| Favorite spot | +1 | 15 ticks |
| Personal time | +2 | 50 ticks |
(Source: src/sim/systems.rs, eating_system(), resting_system(),
weather_mood_system(), seasonal_mood_system(), favorite_places_system(),
personal_time_system(); src/sim/components.rs, Mourning)
Replace vs Push Semantics
mood.push()-- always adds a new modifier (stacks with existing same-name entries).mood.replace()-- if a modifier with the same description exists, refreshes its value and duration; otherwise inserts. Weather modifiers use replace to avoid stacking.
(Source: src/sim/components.rs, Mood::push(), Mood::replace())
Values & Formulas
Morale Tiers
| Tier | Morale Range | Effect |
|---|---|---|
| Inspired | 80-100 | Work speed +2; gravitates toward creative work |
| Normal | 50-79 | Standard behavior |
| Stressed | 20-49 | Work speed -1 |
| Breaking | 0-19 | Refuses all non-critical work; idles |
Work Speed Modifier = match morale_state: Inspired => +2, Stressed => -1, else => 0
(Source: src/sim/systems.rs, work_speed_modifier();
src/sim/components.rs, morale_state())
Hysteresis Bands
To prevent rapid tier-flickering, transitions require crossing a threshold 3 points beyond the nominal boundary:
| Current Tier | Transition Up | Transition Down |
|---|---|---|
| Breaking | > 23 -> Stressed | -- |
| Stressed | > 53 -> Normal | < 17 -> Breaking |
| Normal | > 83 -> Inspired | < 47 -> Stressed |
| Inspired | -- | < 77 -> Normal |
If no previous tier exists (e.g. first evaluation), the nominal thresholds (80, 50, 20) are used directly.
(Source: src/sim/components.rs, morale_state_with_hysteresis())
Interactions
- Roles -- morale determines which tasks an elf will accept; Breaking-tier elves refuse all non-critical work.
- Buildings -- Dwellings speed rest recovery (+5/tick vs +2 outdoors); buildings within Manhattan distance 2 count as "shelter" for weather mood modifiers.
- Skills -- work speed modifier from morale applies to gathering and building progress rates.
- Terrain -- terrain beauty values passively restore the Beauty need.
- Resources -- eating consumes 1 Food and restores +30 Sustenance (capped at 100).
Tips
- Rest decays fastest (every tick). Prioritize building Dwellings early to keep rest recovery efficient (+5/tick indoors vs +2 outdoors).
- Sustenance decays slowest (every 4th tick). In a pinch, elves can survive a long time on foraging alone.
- Beauty and Stimulation both decay every 2nd tick starting from 60 (not 100). Build a Garden and Workshop early to prevent mid-game mood dips.
- Company is personality-driven. Social elves (Social > 0.7) need companions nearby; personal elves (Social < 0.3) want solitude. Keep an eye on the aesthetic axes of your colony members.
- Hysteresis means momentum matters. An elf who climbs to Inspired will stay there until morale drops below 77. Plan mood boosts in clusters rather than spreading them thin.
- Weather modifiers use replace semantics, so you will never see "Caught in rain" stacked five times. But one-time events (first ancient grove visit) do stack with ongoing weather effects.
Resources
Overview
The settlement stockpile holds four resource types used for construction, feeding, and crafting. Resources are gathered from map sources, deposited at buildings, and consumed by various systems. Seasonal multipliers and passive foraging prevent hard starvation while still making resource management meaningful.
How It Works
Resource Types
| Resource | Starting Stock | Description |
|---|---|---|
| Food | 50 | Consumed when eating; prevents starvation |
| Wood | 30 | Primary building material |
| Stone | 10 | Used for Workshops and Feast Halls |
| FineWood | 3 | Rare material (reserved for future crafting) |
(Source: src/sim/world.rs, Resources::starting())
Gathering Pipeline
The full resource loop is:
- Task Decision -- an idle elf decides to gather a resource type
based on role, policy priority, or the
most_needed_resource()fallback. - Pathfinding -- the elf walks to the nearest
ResourceSourceof that type. - Gathering -- once at the source and with no remaining path, the elf accumulates progress each tick.
- Pickup -- at progress >= 100, the elf picks up 5 units of the resource and the source loses 1 amount.
- Return -- the elf pathfinds back to the nearest building.
- Deposit -- at a building tile, carried resources are added to the stockpile.
Gathering Progress Rate = (5 + gathering_skill) + work_speed_modifier
(minimum 1)
At completion, the elf gains 10 XP toward the Gathering skill.
(Source: src/sim/systems.rs, gathering_system(), deposit_system(),
return_to_stockpile_system())
Most-Needed Resource Fallback
When no role or policy dictates a specific resource, the system picks the resource with the lowest current stock:
if food <= wood && food <= stone -> Food
else if wood <= stone -> Wood
else -> Stone
FineWood is never selected by this fallback.
(Source: src/sim/systems.rs, most_needed_resource())
Resource Priority Override
Cultural policies can set a resource_priority list. If the top-priority
resource has stock < 10, it overrides the elf's role-based gathering choice.
(Source: src/sim/systems.rs, decide_default())
Values & Formulas
Passive Foraging
Elves with Sustenance < 40 passively forage every 10th tick when standing on a walkable, non-stone, non-wall tile. This is an automatic safety net -- no task decision required.
| Terrain | Forage Amount | Cap |
|---|---|---|
| Forest (Ancient or Young) | +8 | 60 |
| Other walkable | +5 | 60 |
Foraging restores Sustenance directly (not stockpile Food). It caps at 60, preventing full satisfaction from foraging alone.
(Source: src/sim/systems.rs, foraging_system())
Eating
When an elf performs the Eat task at a building with Food in the stockpile:
- Consumes 1 Food from stockpile
- Restores +30 Sustenance (capped at 100)
- Applies mood modifier: "Ate a meal" +5 for 50 ticks
(Source: src/sim/systems.rs, eating_system())
Season Foraging Multiplier
The climate system provides a seasonal multiplier that affects foraging yields:
| Season | Multiplier |
|---|---|
| Spring | 1.0x |
| Summer | 1.5x |
| Autumn | 1.25x |
| Winter | 0.5x |
(Source: src/sim/climate.rs, Climate::season_foraging_multiplier())
Note: Seasons last 25 days each (100 days per year).
(Source: src/sim/climate.rs, SEASON_LENGTH, YEAR_LENGTH)
Resource Source Regeneration
At dawn each day, resource sources regenerate +1 amount, up to a cap:
| Source Type | Regeneration Cap |
|---|---|
| FineWood | 5 |
| All others | 10 |
(Source: src/sim/systems.rs, regeneration_system())
Gathering Yield
When gathering completes (progress reaches 100):
- Elf picks up 5 units of the resource
- Source loses 1 amount
- Elf gains 10 Gathering XP
(Source: src/sim/systems.rs, gathering_system())
Daily Rate Tracking
The stockpile tracks net change per resource per day. At each dawn,
Resources::snapshot_day() computes the delta from the previous day's
snapshot. This powers the daily rate display in the UI.
(Source: src/sim/world.rs, Resources::snapshot_day(), Resources::daily_rate())
Interactions
- Needs & Mood -- Sustenance below 20 triggers critical need behavior; eating gives a +5 mood boost.
- Roles -- Gatherer role defaults to Wood; Builder role defaults to Stone. Resource priority can override both.
- Buildings -- construction consumes resources from the stockpile; deposits require proximity to a building.
- Skills -- Gathering skill increases collection speed via the progress rate formula.
- Terrain -- foraging yields differ by terrain type; forest tiles give +8, other walkable tiles give +5.
Tips
- Build a Feast Hall early -- elves performing the Eat task need to be at a building tile. Without buildings, the eating pipeline stalls even with Food in the stockpile.
- Watch the daily rates. Negative Food rate means you are consuming faster than you gather. Assign a Gatherer role or raise Food in the priority list.
- FineWood is scarce. Sources cap at 5 and it starts at only 3 in the stockpile. Treat it as a strategic reserve.
- Foraging caps at 60 Sustenance. Elves can survive on foraging alone, but they will never be "Fulfilled" (80+) without proper meals from the stockpile.
- Winter halves foraging. Stockpile Food in Autumn (1.25x) to buffer the Winter deficit (0.5x).
- Resource priority < 10 triggers override. If your top-priority resource drops below 10, all Unassigned elves switch to gathering it regardless of their normal behavior.
Roles
Overview
Each elf can be assigned one of four roles that influence their task selection,
default gathering target, and behavior under the Cultural Policies system.
Roles are assigned by the patron (or AI curator) and stored in the
CulturalPolicies::workshop_assignments map. Unassigned elves follow a
general-purpose behavior tree.
How It Works
Role Types
| Role | Description |
|---|---|
| Unassigned | Default. Follows the general behavior tree; gathers the most-needed resource. |
| Composer | Gravitates toward composing at a Workshop when no urgent needs exist. |
| Builder | Prioritized for build queue assignments; default gather target is Stone. |
| Gatherer | Default gather target is Wood; handles general resource collection. |
(Source: src/sim/components.rs, enum ElfRole)
Role Assignment
Roles are set via CulturalPolicies::workshop_assignments, a map from elf
name to ElfRole. If an elf's name is not in the map, they default to
ElfRole::Unassigned.
role = workshop_assignments.get(name).unwrap_or(Unassigned)
(Source: src/sim/world.rs, CulturalPolicies::role_for())
Role-Resource Linkage
Each role has a default resource it will gather when sent to decide_default():
| Role | Default Resource |
|---|---|
| Gatherer | Wood |
| Builder | Stone |
| Composer | None (uses policy priority or most-needed) |
| Unassigned | None (uses policy priority or most-needed) |
(Source: src/sim/world.rs, CulturalPolicies::role_resource())
Values & Formulas
Task Decision Priority
The behavior tree (task_decision_system) evaluates priorities in strict
order. Roles only matter at Steps 3c and 4 -- critical needs always come
first.
| Priority | Condition | Action |
|---|---|---|
| Step 0: Preempt | Sustenance or Rest critical (< 20, or < 5 for construction) | Cancel current task, go idle |
| Step 1: Critical Needs | Sustenance < 20 | Eat (if Food available) or Gather Food |
| Rest < 20 | Rest (seek Dwelling) | |
| Step 1b: Discontented | Elf has Discontented marker | Only gather Food or idle; refuses creative/ambitious work |
| Step 1c: Mourning | Elf has Mourning marker | Compose at Workshop (tribute); Wander if no Workshop. Skips gathering/building. |
| Step 2: Creative Block | Elf has CreativeBlock | Seek Garden (if available) |
| Step 3: Moderate Needs | Beauty < 30 or Stimulation < 30 | Compose (Stimulation) or SeekGarden (Beauty), whichever is lower |
| Step 3b: Aspirations | Aspiration wants compose/socialize | Compose at Workshop or Wander to social buildings |
| Step 3c: Skill-Driven | Music skill >= 7 | Compose at Workshop |
| Building skill >= 7 + build queue not empty | Build | |
| Step 3d: Personal Time | 5% random chance | Seek favorite place or Garden for beauty/inspiration |
| Step 4: Cultural Policy | Role == Composer | Compose at Workshop |
| Any other role | decide_default() | |
| Breaking Morale | Morale < 20 (inserted between Steps 3 and 3b) | Idle (refuse all non-critical work) |
(Source: src/sim/systems.rs, task_decision_system())
Default Behavior (decide_default)
When an elf reaches the default branch:
- Check
resource_priority[0]-- if that resource stock < 10, gather it (override). - Otherwise, if the elf's role has a
role_resource, gather that. - Otherwise, use
resource_priority[0]if set. - Otherwise, gather
most_needed_resource()(lowest stock of Food/Wood/Stone). - If no source exists for the chosen resource, fall back to most-needed.
- If still no source, Wander.
(Source: src/sim/systems.rs, decide_default())
Build Queue Assignment
When the build queue is non-empty and resources are available:
- Prefer idle elf with Builder role.
- Then any idle elf.
- Then any Builder-role elf on a non-critical task (Sustenance >= 40 and Rest >= 40).
- Only one elf builds at a time (no double-assignment).
(Source: src/sim/systems.rs, build_queue_system())
Preemption Rules
Active tasks can be interrupted when needs become critical:
| Current Task | Preempt Threshold |
|---|---|
| Gather, Compose, SeekGarden, Wander | Sustenance < 20 OR Rest < 20 |
| Build, ClearForest | Sustenance < 5 OR Rest < 5 |
When preempted, the elf's task is set to Idle, their path is canceled, and any carried resources are dropped (lost). Construction tasks get a lower preemption threshold to avoid interrupting nearly-finished builds.
(Source: src/sim/systems.rs, task_decision_system(), Phase 0)
Revel Attendance Override
Elves attending an active revel skip the entire behavior tree. The
RevelAttending marker component is checked first, and those elves are
excluded from all task decisions until the revel ends.
(Source: src/sim/systems.rs, task_decision_system())
Role Behavior Summary Table
| Role | Idle Behavior | When Needs OK | When Needs Critical |
|---|---|---|---|
| Unassigned | Gather most-needed resource | Follow policy priority | Eat/Rest |
| Composer | Compose at Workshop | Compose at Workshop | Eat/Rest |
| Builder | Gather Stone | Assigned to build queue first | Eat/Rest |
| Gatherer | Gather Wood | Gather Wood | Eat/Rest |
Interactions
- Needs & Mood -- critical needs always override role behavior; morale tier affects willingness to work.
- Resources -- role determines which resource an elf gathers by default; resource priority can override role.
- Skills -- high Music skill (>= 7) self-selects to Compose regardless of role; high Building skill (>= 7) self-selects to Build.
- Buildings -- Builders are prioritized for the build queue; Composers require a Workshop.
Tips
- Composer is the only role that directly affects task selection at Step 4. Builder and Gatherer mostly influence which resource is gathered in the default branch.
- Skill-driven preferences (Step 3c) bypass role. An elf with Music 7+ will self-select to compose even if unassigned. Assign roles primarily for lower-skill elves.
- Aspirations (Step 3b) also bypass role. Elves pursuing a "compose works" aspiration will compose without needing the Composer role.
- Builders get pulled from non-critical tasks to fill the build queue. Make sure your Builder has adequate Sustenance and Rest (>= 40 each) or they will be skipped.
- Unassigned is not idle. Unassigned elves still gather the most-needed resource or follow the resource priority list. In a small settlement, leaving everyone Unassigned is a valid strategy.
- Resource priority override is powerful. Setting a priority resource effectively overrides all non-Builder roles when that resource drops below 10 units.
Skills
Overview
Every elf has three skill proficiencies -- Music, Building, and Gathering -- each on a 1-10 scale. Skills level up through XP accumulation, improve task efficiency, and influence composition quality. At higher levels, skills can drive autonomous behavior: a Music-7 elf will self-select to compose even without a role assignment.
How It Works
Skill Types
| Skill | Governs | Key Threshold |
|---|---|---|
| Music | Composition speed, quality (mastery score) | >= 7: self-selects to compose |
| Building | Construction speed, building XP gains | >= 7: self-selects to build (if queue non-empty) |
| Gathering | Resource collection speed | -- |
All skills start at level 1 with 0 XP.
(Source: src/sim/components.rs, struct Skills, impl Default for Skills)
XP and Leveling
XP accumulates per-skill. When accumulated XP reaches the threshold for the current level, the elf levels up and excess XP carries over.
XP Threshold = level x 50
(Source: src/sim/components.rs, Skills::xp_threshold())
The maximum skill level is 10. XP gains are ignored at level 10.
(Source: src/sim/components.rs, Skills::add_xp())
Full XP Table
| Level | XP to Next Level | Cumulative XP |
|---|---|---|
| 1 | 50 | 0 |
| 2 | 100 | 50 |
| 3 | 150 | 150 |
| 4 | 200 | 300 |
| 5 | 250 | 500 |
| 6 | 300 | 750 |
| 7 | 350 | 1,050 |
| 8 | 400 | 1,400 |
| 9 | 450 | 1,800 |
| 10 | -- (max) | 2,250 |
Formula: Cumulative XP to reach level L = sum(i=1..L-1) of i*50 = 25 * L * (L-1).
XP Sources
| Activity | Skill | XP per Event |
|---|---|---|
| Complete a gathering task | Gathering | +10 |
| Complete a building task | Building | +15 |
| While composing (per tick) | Music | +1 |
(Source: src/sim/systems.rs, gathering_system(), building_progress_system(),
compose_system())
Values & Formulas
Gathering Progress
progress_rate = (5 + gathering_skill) + work_speed_modifier
Progress starts at 0 and completes at 100. At completion, the elf picks up 5 units and gains 10 Gathering XP.
work_speed_modifier: Inspired = +2, Normal = 0, Stressed = -1. Minimum rate is 1.
| Gathering Skill | Ticks to Complete (Normal morale) |
|---|---|
| 1 | 17 |
| 3 | 13 |
| 5 | 10 |
| 7 | 9 |
| 10 | 7 |
(Source: src/sim/systems.rs, gathering_system(), work_speed_modifier())
Building Progress
progress_rate = (5 + building_skill) + work_speed_modifier
Same formula as gathering. Completes at 100. Grants 15 Building XP.
| Building Skill | Ticks to Complete (Normal morale) |
|---|---|
| 1 | 17 |
| 3 | 13 |
| 5 | 10 |
| 7 | 9 |
| 10 | 7 |
(Source: src/sim/systems.rs, building_progress_system())
Composition Speed
Composition duration scales inversely with Music skill:
duration = max(50 - music_skill * 2, 30)
Progress rate per tick = 100 / duration (minimum 1).
| Music Skill | Duration (ticks) | Progress/tick |
|---|---|---|
| 1 | 48 | 2 |
| 3 | 44 | 2 |
| 5 | 40 | 2 |
| 7 | 36 | 2 |
| 10 | 30 | 3 |
(Source: src/sim/art.rs, compose_duration())
Composition Quality
Music skill directly drives the mastery quality axis:
mastery = clamp(music_skill * 10 + random(-5..+5), 0, 100)
A level-10 musician produces mastery scores around 95-105 (clamped to 100). A level-1 musician produces mastery around 5-15.
Originality depends on inspiration total; emotional depends on net mood.
(Source: src/sim/art.rs, compute_quality())
Skill-Driven Behavior Thresholds
| Skill | Level | Behavior |
|---|---|---|
| Music | >= 7 | Self-selects to Compose (Step 3c in behavior tree) |
| Building | >= 7 | Self-selects to Build when build queue is non-empty |
These thresholds bypass role assignment -- the elf follows their expertise automatically.
(Source: src/sim/systems.rs, task_decision_system(), lines 491-510)
Interactions
- Roles -- roles provide a suggestion for default behavior; high skill levels provide an override at Step 3c.
- Needs & Mood -- morale affects work speed modifier: Inspired (+2), Stressed (-1).
- Resources -- gathering skill controls how fast resources are collected.
- Buildings -- building skill controls construction speed; completion awards 15 XP.
Tips
- XP scales quadratically. Getting from level 1 to 5 takes 550 cumulative XP. Getting from 5 to 10 takes another 1,950. Late levels are a long grind.
- Music XP trickles in at 1/tick while composing. Even at the slow rate, a composer working full-time levels up steadily. Building XP comes in bigger chunks (15 per completion) but less frequently.
- Level 7 is the magic number. At Music 7 or Building 7, elves start self-directing. This is the threshold where specialization pays off without needing explicit role assignment.
- Work speed modifier matters most at low skill. The Inspired +2 bonus on a skill-1 elf increases their rate from 6 to 8 (33% faster). On a skill-10 elf, it goes from 15 to 17 (13% faster). Keep your rookies happy.
- Composition quality tracks mastery closely with music skill. A skill-10 composer produces consistently excellent mastery. Invest in your top musician for the best compositions.
Terrain
Overview
The map is a 2D grid of terrain tiles that determine movement, beauty, foraging yields, and resource placement. Six terrain types form three functional zones: the settlement clearing (Meadow), the surrounding forest ring (Ancient and Young Forest), and the outer wilderness (mixed, with obstacles).
How It Works
Terrain Types
| Terrain | Glyph | Walkable | Is Forest | Beauty Value |
|---|---|---|---|---|
| Meadow | . | Yes | No | 0 |
| Stone | # | Yes | No | 0 |
| Water | ~ | No | No | 0 |
| AncientForest | T | Yes | Yes | 2 |
| YoungForest | t | Yes | Yes | 1 |
| Wall | X | No | No | 0 |
(Source: src/sim/components.rs, enum Terrain, walkable(), is_forest(),
beauty_value())
Walkability
Elves can move on any tile except Water and Wall. The pathfinding system uses walkability to compute valid routes.
walkable = !matches!(terrain, Water | Wall)
(Source: src/sim/components.rs, Terrain::walkable())
Beauty Restoration
Each tick, the terrain_effect_system checks the elf's current tile and all
four adjacent tiles (N, S, E, W). The highest beauty value among these
five tiles is added to the elf's Beauty need.
beauty_gain = max(current_tile.beauty_value, adjacent_tiles.beauty_value)
Seasonal overrides:
| Terrain | Season | Effective Beauty |
|---|---|---|
| AncientForest | Autumn | 3 (base 2 + autumn color bonus) |
| YoungForest | Winter | 0 (bare branches, normally 1) |
| All others | Any | Base value |
(Source: src/sim/systems.rs, terrain_effect_system())
Stream Adjacency
If any adjacent tile is Water, the elf gains a solitude inspiration bonus (+1 every 10 ticks).
(Source: src/sim/systems.rs, terrain_effect_system())
Inspiration from Terrain
Every 10 ticks:
| Terrain | Inspiration Gain |
|---|---|
| AncientForest | +1 Nature inspiration |
| YoungForest | +1 Nature inspiration (every 20 ticks only) |
| Adjacent Water | +1 Solitude inspiration |
(Source: src/sim/systems.rs, terrain_effect_system())
First-Visit Mood
The first time an elf enters an AncientForest tile, they receive:
- Mood modifier: "Awed by ancient grove" +2 for 200 ticks
This is tracked per-elf via VisitedTerrains and only fires once.
(Source: src/sim/systems.rs, terrain_effect_system();
src/sim/components.rs, VisitedTerrains)
Values & Formulas
Foraging Yields by Terrain
| Terrain | Forage Amount | Condition |
|---|---|---|
| Forest (Ancient or Young) | +8 Sustenance | Sustenance < 40, every 10th tick |
| Other walkable (Meadow, Stone) | +5 Sustenance | Sustenance < 40, every 10th tick |
| Water, Wall | 0 (not walkable) | -- |
Foraging caps at 60 Sustenance (elves cannot reach "Fulfilled" from foraging). Stone is explicitly excluded from foraging despite being walkable.
Wait -- re-reading the source: Stone is excluded in foraging_system() by the
check !matches!(terrain, Terrain::Stone | Terrain::Wall).
| Terrain | Forageable |
|---|---|
| Meadow | Yes (+5) |
| AncientForest | Yes (+8) |
| YoungForest | Yes (+8) |
| Stone | No |
| Water | No |
| Wall | No |
(Source: src/sim/systems.rs, foraging_system())
Resource Sources
Resource sources are separate entities placed on map tiles. Their type determines what can be gathered there. Sources regenerate +1 per dawn, up to a cap of 10 (5 for FineWood).
(Source: src/sim/systems.rs, regeneration_system())
Map Generation
Maps are generated with three concentric zones:
Zone 1: Settlement Clearing (center)
- Radius:
max(min(width, height) * 0.15, 5.0)tiles from center - Mostly Meadow
- A narrow stream (Water) runs through the center
Zone 2: Forest Ring
- Extends 3 tiles beyond the clearing radius
- 65% forest (inner half = AncientForest, outer half = YoungForest)
- 10% Stone
- 25% Meadow
Zone 3: Outer Wilderness
- Everything beyond the forest ring
- Distribution:
| Terrain | Probability |
|---|---|
| Wall | 2% |
| Water | 5% |
| Stone | 8% |
| YoungForest | 15% |
| Meadow | 70% |
(Source: src/sim/map.rs, generate_map())
Default map size: 40 x 30.
Interactions
- Needs & Mood -- terrain beauty restores the Beauty need; first-visit moods add to the mood stack.
- Resources -- foraging yields vary by terrain; resource sources are placed on specific tiles.
- Buildings -- buildings are placed on walkable tiles; the settlement clearing provides the main building area.
- Skills -- terrain does not directly affect skill gains, but proximity to forest tiles enables passive beauty restoration that keeps elves happy and productive.
Tips
- AncientForest is the most valuable terrain. Beauty 2, +1 Nature inspiration every 10 ticks, first-visit mood bonus, and best foraging yield. Build paths (or settle) near AncientForest tiles.
- Autumn is peak beauty season. AncientForest beauty jumps to 3 in Autumn. Plan revels and creative work for this season.
- Winter kills YoungForest beauty. Bare branches mean 0 beauty value. Make sure you have a Garden or AncientForest access to compensate.
- The center stream is a double-edged tile. Water blocks movement but gives adjacent elves solitude inspiration. Build near it, not on it.
- Stone terrain is walkable but not forageable. Elves can cross Stone tiles freely but will not passively forage there.
- Wall tiles (2% of outer wilderness) are impassable obstacles. They can block pathfinding to outer resource sources. Scout the map for bottlenecks.
Buildings
Overview
Buildings are permanent structures placed on the map via the build queue. They provide shelter from weather, enable critical tasks (eating, resting, composing), and buff nearby elves. Four building types cover the settlement's needs: housing, crafting, aesthetics, and communal gathering.
How It Works
Building Types
| Building | Description |
|---|---|
| Dwelling | Living quarters. Speeds rest recovery. Counts as shelter. |
| Workshop | Crafting space. Required for composing. Counts as shelter. |
| Garden | Beauty and creative block recovery. Does NOT count as shelter. |
| Feast Hall | Communal eating. Social gathering space. Counts as shelter. |
(Source: src/sim/components.rs, enum BuildingType)
Build Costs
| Building | Wood | Stone | FineWood |
|---|---|---|---|
| Dwelling | 10 | -- | -- |
| Workshop | 10 | 10 | -- |
| Garden | 5 | -- | -- |
| Feast Hall | 15 | 5 | -- |
(Source: src/sim/systems.rs, build_cost())
Build Queue
Buildings are constructed through the build queue system:
- The patron or AI curator adds a
QueuedBuild(type + site position) toCulturalPolicies::build_queue. build_queue_system()checks if the settlement can afford the top item.- If affordable, it assigns an idle elf (preferring Builders) and deducts resources immediately.
- The assigned elf pathfinds to the build site and begins construction.
- Only one build is active at a time (no double-assignment).
(Source: src/sim/systems.rs, build_queue_system())
Builder Assignment Priority
When a build is ready to start:
| Priority | Candidate |
|---|---|
| 1st | Idle elf with Builder role |
| 2nd | Any idle elf |
| 3rd | Builder-role elf on a non-critical task (Sustenance >= 40, Rest >= 40) |
Builder-role elves on critical tasks (Eat, Rest, Build, ClearForest) or with low needs are not reassigned.
(Source: src/sim/systems.rs, build_queue_system())
Values & Formulas
Construction Progress
progress_rate = (5 + building_skill) + work_speed_modifier
Construction completes when progress reaches 100. Minimum rate is 1.
work_speed_modifier: Inspired = +2, Normal = 0, Stressed = -1.
| Building Skill | Ticks to Complete (Normal) | Ticks (Inspired) | Ticks (Stressed) |
|---|---|---|---|
| 1 | 17 | 13 | 20 |
| 3 | 13 | 10 | 15 |
| 5 | 10 | 8 | 12 |
| 7 | 9 | 7 | 10 |
| 10 | 7 | 6 | 8 |
On completion, the builder gains 15 Building XP.
(Source: src/sim/systems.rs, building_progress_system();
src/sim/components.rs, Skills::add_xp())
Shelter Radius
Buildings classified as shelter (Dwelling, Workshop, Feast Hall) protect elves within Manhattan distance <= 2 from weather penalties.
is_indoors = any shelter building within Manhattan distance 2 of elf
Garden does not count as shelter.
(Source: src/sim/systems.rs, weather_mood_system())
Weather Mood Effects (Shelter-Dependent)
| Weather | Outdoors Effect | Indoors Effect |
|---|---|---|
| Rain | "Caught in rain" -1 (50 ticks) | None |
| Snow | "Snow-covered landscape" +2 (50 ticks) | None |
| Storm | "Sheltering from storm" +0 (50 ticks) | "Sheltering from storm" +0 (50 ticks) |
(Source: src/sim/systems.rs, weather_mood_system())
Rest Recovery
Resting elves recover at different rates depending on proximity to a Dwelling:
| Location | Rest Recovery Rate | Mood on Completion |
|---|---|---|
| At Dwelling | +5 per tick | "Slept in dwelling" +3 (100 ticks) |
| Outdoors | +2 per tick | "Slept on ground" -3 (50 ticks) |
Resting completes when Rest reaches 80 ("Fulfilled" threshold).
(Source: src/sim/systems.rs, resting_system())
Eating
Elves perform the Eat task at any building tile (not just Feast Halls). Eating consumes 1 Food from the stockpile and restores +30 Sustenance.
(Source: src/sim/systems.rs, eating_system())
Composing
Composing requires presence at a Workshop tile with no remaining path. Composition duration scales with Music skill (see Skills for the formula).
(Source: src/sim/systems.rs, compose_system())
Garden and Creative Block
Elves with Creative Block seek a Garden. The Garden does not directly
restore beauty via a building buff -- instead, Gardens are typically placed
near forest tiles where the terrain_effect_system provides passive beauty
restoration. Creative Block drives the elf to the Garden as a waypoint.
(Source: src/sim/systems.rs, task_decision_system(), Step 2)
Interactions
- Resources -- build costs are deducted from the stockpile when construction starts; deposits require proximity to any building.
- Needs & Mood -- Dwellings provide faster rest recovery (+5 vs +2) and a positive mood modifier; sheltered buildings prevent rain mood penalties.
- Roles -- Builder role elves are prioritized for construction assignments.
- Skills -- Building skill determines construction speed; completion grants 15 XP.
- Terrain -- buildings must be placed on walkable tiles; Gardens are most effective near forest terrain for beauty synergy.
Tips
- Build order matters. A Dwelling first ensures Rest recovery is efficient. A Workshop second enables composing and Stimulation restoration. Garden third handles Beauty needs.
- Feast Hall is expensive but versatile. At 15 Wood + 5 Stone, it is the costliest building. But it serves as shelter, eating location, and social gathering point for elves pursuing social aspirations.
- Garden is cheap and essential. At only 5 Wood, it is the most cost-effective building. Place it adjacent to AncientForest tiles to maximize beauty synergy.
- Shelter radius is Manhattan 2. Buildings placed 1 tile apart create overlapping shelter zones. Cluster buildings to cover the most elves.
- One build at a time. The system prevents multiple simultaneous constructions. Queue your builds in priority order; the next one starts automatically when the current one finishes.
- Resources are deducted immediately when a build starts, not when it finishes. If a builder gets interrupted, the resources are still consumed. Make sure your builder has adequate needs before starting expensive constructions.
- Outdoor resting gives a mood penalty. Without a Dwelling, elves who rest get "Slept on ground" (-3 for 50 ticks). This stacks with weather effects and can spiral morale downward in early game.
Compositions
Overview
Compositions are the primary creative output of an elven settlement. When an elf with the Composer role (or any elf choosing to compose) finishes a composing task, the simulation generates a unique musical work with a procedurally generated name, title, description, quality scores, and special properties. Compositions are permanent artifacts stored in the settlement's portfolio and performed at Revels.
Every composition encodes the emotional and aesthetic state of its creator at the moment of creation. Two compositions by the same elf in different moods will sound completely different.
How It Works
Composing Duration
The time to compose is determined by music skill. Higher skill means faster work, but there is a floor of 30 ticks:
Duration = max(50 - skill x 2, 30) ticks
| Music Skill | Compose Time (ticks) |
|---|---|
| 1 | 48 |
| 5 | 40 |
| 8 | 34 |
| 10 | 30 |
Source: src/sim/art.rs, compose_duration
Genre Families
Every composition belongs to one of three genre families, selected based on the composer's Aesthetic Position and Inspiration.
| Genre | Description | Selection Bias |
|---|---|---|
| Traditional | Classical forms, familiar structures | High tradition axis |
| Radical | Avant-garde, experimental | Low tradition axis |
| Pastoral | Nature-inspired, ambient | High Nature inspiration (>40) |
Base selection formula:
p_radical = max((1.0 - tradition - 0.5) x 1.5, 0.0)-- Radical probability rises as tradition fallsp_nature = 0.6if Nature is the dominant inspiration source AND nature > 40, otherwise0.1p_traditional = max(1.0 - p_radical - p_nature, 0.0)- All three are normalized, then a weighted random roll selects the genre
There is an 8% "cross-genre surprise" chance that ignores all the above and picks a random genre (roughly once per 20-day session).
Seasonal bias further adjusts probabilities:
| Season | Bias |
|---|---|
| Winter | Pastoral +20% |
| Summer | Radical +20% |
| Spring | Traditional +10% |
| Autumn | No bias (most varied season) |
Source: src/sim/art.rs, select_genre_seasonal
Base Types (Skill Tiers)
Within each genre, the composer's music skill determines which tier of base type is available. There are 4 tiers per genre (12 total):
| Skill | Tier | Traditional | Radical | Pastoral |
|---|---|---|---|---|
| 0-3 | Apprentice | Lullaby, Hymn, Folk Song, Ditty, Canticle, Air | Chant Riff, Drum Circle, Voice Loop, Spoken Word | Birdsong, Creek Melody, Windchime, Leaf Rustle |
| 4-6 | Journeyman | Ballad, Rondo, Serenade, Nocturne, Madrigal, Minuet | Blues Lament, Groove, Free Verse, Syncopation | Storm Song, Forest Waltz, River Suite, Dawn Chorus |
| 7-9 | Master | Sonata, Concerto, Rhapsody, Aubade, Fantasia, Elegy | Jazz Standard, Rock Anthem, Beat Poem, Fusion | Thunder Concerto, Tide Rhapsody, Season Cycle |
| 10+ | Grandmaster | Requiem, Symphony, Magnum Opus, Oratorio | Noise Symphony, Rap Epic, Punk Requiem, Ambient Opus | World Song, Elements Symphony, Celestial Harmony, Earthsong, Aurora Opus |
Source: src/sim/art.rs, select_base_type
Values & Formulas
Quality Scores
Each composition has three quality dimensions scored 0-100:
| Dimension | Driver | Formula |
|---|---|---|
| Mastery | Music skill | skill x 10 + random(-5..+5), clamped 0-100 |
| Originality | Inspiration total | inspiration_total x 0.6 + random(0..20), clamped 0-100 |
| Emotional | Net mood | mood x 0.5 + 30 + random(0..10), clamped 0-100 |
Average quality = (mastery + originality + emotional) / 3
| Average Quality | Tier Label |
|---|---|
| 90-100 | Transcendent |
| 70-89 | Masterful |
| 50-69 | Skilled |
| 25-49 | Modest |
| 0-24 | Crude |
Elegy bonus: Compositions created while an elf is mourning a departed friend receive +15 to the emotional score.
Source: src/sim/art.rs, compute_quality; src/sim/components.rs, quality_avg, quality_tier
Composition Properties
Properties are special tags earned from extreme creation conditions. Each composition can have at most 2 properties.
Condition properties (checked in order):
| Property | Condition |
|---|---|
| Cathartic | Composer has an active creative block |
| Transcendent | Total inspiration > 90 |
| Debut | First composition ever (empty portfolio) |
| Magnum Opus | Skill 10 AND inspiration > 90 AND mood > 50 (once per lifetime) |
| Masterwork | Skill >= 10 (if Magnum Opus not triggered) |
| Elegy | Composed while mourning a departed friend |
Compound inspiration properties (require two channels both > 30):
| Property | Channels Required |
|---|---|
| Manifesto | Rivalry > 30 AND Social > 30 |
| Obsessive | Rivalry > 30 AND Solitude > 30 |
| Communal | Nature > 30 AND Social > 30 |
| Timeless | Nature > 30 AND Solitude > 30 |
| Virtuosic | Beauty > 30 AND Rivalry > 30 |
| Sublime | Beauty > 30 AND Solitude > 30 |
| Bittersweet | Social > 30 AND Solitude > 30 |
| Enchanted | Nature > 30 AND Beauty > 30 |
| Anthem | Social > 30 AND Beauty > 30 |
Source: src/sim/systems.rs, lines 918-964; src/sim/components.rs, CompositionProperty
Creative Block
Three or more consecutive compositions with average quality below 50 give a 30% chance of triggering a creative block. Duration is 100 to 200 ticks (random). During a block, the elf refuses to compose and seeks a Garden instead.
Source: src/sim/systems.rs, ConsecutiveMediocre, creative block trigger logic
Name Generation
Composition names follow the structure "{Prefix} {Base Type} {Suffix}".
Prefix is selected from mood tier pools, with two override conditions checked first:
| Condition | Pool | Examples |
|---|---|---|
| Night AND mood < -10 | Haunted | Haunted, Spectral, Moonlit, Shadow-woven |
| Inspiration > 70 AND mood < 0 | Fierce | Fierce, Defiant, Tempestuous, Raw |
| Mood <= -41 | Devastated | Shattered, Grieving, Tormented |
| Mood -40 to -21 | Sad | Melancholic, Mournful, Desolate |
| Mood -20 to +10 | Reflective | Contemplative, Wistful, Pensive |
| Mood +11 to +40 | Content | Serene, Gentle, Tender |
| Mood +41 to +70 | Happy | Joyful, Radiant, Exuberant |
| Mood > +70 | Euphoric | Ecstatic, Triumphant, Blazing |
Suffix comes from the dominant inspiration source:
| Source | Example Suffixes |
|---|---|
| Nature | "of the Silver Wood", "of Falling Rain" |
| Social | "of Fellowship", "of the Long Table" |
| Rivalry | "of the Challenge", "of Defiance" |
| Beauty | "of the Master's Touch", "of Perfect Form" |
| Solitude | "of Midnight", "of the Lonely Peak" |
Title Generation
In addition to the composition name, each work gets a short and long title pair. The short title is drawn from a pool matching the dominant inspiration source (e.g., "Still Water", "The Argument"). The long title appends a mood modifier (e.g., "Still Water, in the Rain").
Source: src/sim/art.rs, generate_name, generate_title
Interactions
- Inspiration -- Originality score and compound properties depend on inspiration channels
- Aesthetic Position -- Determines genre family selection and composition aesthetic snapshot
- Revels -- Compositions are performed at revels where audience reactions are computed
- Needs & Mood -- Mood drives the emotional score and name prefix selection
- Skills -- Music skill determines mastery score, base type tier, and compose duration
- Artistic Direction -- Patron direction influences which elves the curator assigns as Composers
Tips
- A skill-10 elf with high inspiration and good mood can produce a Magnum Opus -- the rarest property in the game. Protect your best musicians from mood crashes.
- Creative blocks are not purely bad: composing during a block earns the Cathartic property, which is otherwise unobtainable.
- Seasonal genre bias means Winter is the best time for Pastoral works and Summer for Radical. Plan revel timing accordingly.
- The 8% cross-genre surprise means even a deeply traditional elf occasionally writes something radical. This is intentional and can spark interesting audience reactions.
- Compositions with the Elegy property are only possible when an elf is mourning -- these tend to have very high emotional scores due to the +15 bonus.
Inspiration
Overview
Inspiration is the creative fuel that drives composition quality. Every elf has five independent inspiration channels that accumulate from different experiences. These channels feed into the originality score of Compositions, determine which composition properties are earned, and influence genre selection.
Inspiration is not a single number -- it is a 5-dimensional creative profile that reflects how an elf has been inspired, not just how much.
How It Works
The Five Channels
Each channel is a u8 value (0-255 per channel, but the total is capped):
| Channel | Source | What Builds It |
|---|---|---|
| Nature | Exposure to the natural world | Being near forests, gardens, water; wandering in wilderness |
| Social | Community and companionship | Proximity to other elves, shared meals, conversations |
| Rivalry | Artistic competition | Proximity to rivals, competing at revels, aesthetic disagreements |
| Beauty | Witnessing great art | Hearing loved compositions at revels, being near gardens |
| Solitude | Time alone | Wandering alone, working in isolation, time away from others |
Total Inspiration
The total is the sum of all five channels, capped at 100 for threshold checks:
Total = min(nature + social + rivalry + beauty + solitude, 100)
This cap means that a broadly inspired elf (moderate across all channels) reaches the ceiling just as easily as a deeply specialized one.
Source: src/sim/components.rs, Inspiration::total
Dominant Source
The channel with the highest value is the "dominant source." This determines:
- The suffix of composition names (e.g., "of the Silver Wood" for Nature)
- The title pool for short/long titles
- Which channel receives a +5 boost from Love reactions at revels
- Genre selection bias (Nature dominance with value > 40 favors Pastoral)
Ties are broken by priority order: Nature > Social > Rivalry > Beauty > Solitude.
Source: src/sim/components.rs, Inspiration::dominant_source
Values & Formulas
Inspiration Equilibrium
Each elf has a natural equilibrium for their inspiration channels, derived from their Aesthetic Position. The equilibrium represents where the elf's inspiration naturally gravitates:
| Channel | Equilibrium Formula |
|---|---|
| Nature | (1.0 - structure) x 20 |
| Social | social x 25 |
| Rivalry | (1.0 - tradition) x 15 |
| Beauty | (structure + tradition) x 10 |
| Solitude | (1.0 - social) x 25 |
Example: An elf with aesthetic position (structure=0.3, tradition=0.2, emotion=0.7, social=0.8) would have equilibrium:
- Nature:
(1.0 - 0.3) x 20 = 14 - Social:
0.8 x 25 = 20 - Rivalry:
(1.0 - 0.2) x 15 = 12 - Beauty:
(0.3 + 0.2) x 10 = 5 - Solitude:
(1.0 - 0.8) x 25 = 5
Source: src/sim/components.rs, InspirationEquilibrium::from_aesthetic
Seeding from Equilibrium
When an elf's inspiration is initialized from equilibrium, the system guarantees a minimum total of 25 by boosting the highest-equilibrium channel in increments of 5 until the floor is reached.
Source: src/sim/components.rs, Inspiration::from_equilibrium
Impact on Composition Quality
Inspiration total feeds directly into the Originality score:
Originality = inspiration_total x 0.6 + random(0..20), clamped 0-100
An elf with 0 total inspiration will produce originality scores of 0-20 (random noise only). An elf with 100 total inspiration will score 60-80 on average.
Revel Inspiration Boost
When an elf has a Love reaction to a composition at a revel, their dominant inspiration channel receives +5 (capped at 100 per channel).
Source: src/sim/systems.rs, revel_tick_system Love reaction handler
Composition Property Thresholds
Inspiration channels interact to create special composition properties when two channels both exceed 30:
| Property | Required Channels |
|---|---|
| Transcendent | Total > 90 (any combination) |
| Manifesto | Rivalry > 30 AND Social > 30 |
| Obsessive | Rivalry > 30 AND Solitude > 30 |
| Communal | Nature > 30 AND Social > 30 |
| Timeless | Nature > 30 AND Solitude > 30 |
| Virtuosic | Beauty > 30 AND Rivalry > 30 |
| Sublime | Beauty > 30 AND Solitude > 30 |
| Bittersweet | Social > 30 AND Solitude > 30 |
| Enchanted | Nature > 30 AND Beauty > 30 |
| Anthem | Social > 30 AND Beauty > 30 |
See Compositions for the full property system.
Creative Block
Trigger Mechanism
When an elf produces three or more consecutive compositions with average quality below 50, each subsequent composition has a 30% chance of triggering a creative block.
A composition with quality >= 50 resets the consecutive mediocre counter to zero.
Block Duration
Creative block lasts 100 to 200 ticks (randomly determined).
Block Effects
- The elf refuses to compose and instead seeks a Garden
- The elf is excluded from revel attendance
- If the elf manages to compose during a block (e.g., forced by circumstances), the composition earns the Cathartic property
- Critical needs (rest, sustenance below 20) override block behavior -- the elf will seek a Dwelling to rest even during a block
Source: src/sim/components.rs, CreativeBlock, ConsecutiveMediocre;
src/sim/systems.rs, creative block trigger and behavior tree
Interactions
- Compositions -- Inspiration drives originality score and enables compound properties
- Aesthetic Position -- Determines inspiration equilibrium values
- Revels -- Love reactions boost dominant inspiration channel by +5
- Needs & Mood -- Mood and inspiration together determine emotional and originality scores
- Terrain -- Forest and garden proximity builds Nature and Beauty inspiration
Tips
- An elf's equilibrium is fixed by their aesthetic position. To shift where inspiration naturally gravitates, you need to shift the elf's aesthetics (via friend drift, school drift, or revel audience drift).
- The Solitude and Social channels are in natural tension: an elf with high
socialaxis will have high Social equilibrium but low Solitude equilibrium, and vice versa. This makes the Bittersweet property (Social > 30 AND Solitude > 30) one of the harder compound properties to earn. - Keep an eye on Nature inspiration for potential Pastoral genre selection. An elf needs Nature as their dominant source AND nature > 40 for the 60% Pastoral bias to kick in.
- The total cap of 100 means you do not need all channels maxed out. A specialist with 80 in one channel and 20 spread across others already hits the cap.
- Creative blocks are recoverable. Place a Garden nearby and the elf will seek it out. The block self-resolves after 100-200 ticks.
Aesthetic Position
Overview
Every elf has a 4-axis aesthetic position that defines their artistic taste and creative identity. This is the most influential hidden stat in the game: it determines which genre an elf composes in, how they react to others' art at Revels, their natural Inspiration equilibrium, and whether they feel alienated from the settlement's cultural center.
Aesthetic positions drift over time through social proximity, school influence, and revel attendance -- creating emergent cultural movements without any scripting.
How It Works
The Four Axes
Each axis is a continuous float from 0.0 to 1.0. The "opposite" of any value
is simply 1.0 - value -- there are no separate fields for opposing poles.
| Axis | Low End (0.0) | High End (1.0) |
|---|---|---|
| Structure | Freedom (improvisation) | Structure (formal composition) |
| Tradition | Innovation (hunger for the new) | Tradition (love of the familiar) |
| Emotion | Intellect (provoke thought) | Emotion (move the audience) |
| Social | Personal (art for oneself) | Social (art for the community) |
New elves are assigned a uniformly random position on all four axes.
Source: src/sim/components.rs, AestheticPosition
Distance Metric
Aesthetic distance between two elves (or between an elf and a composition) uses Euclidean distance in 4D space:
distance = sqrt((s1-s2)^2 + (t1-t2)^2 + (e1-e2)^2 + (sc1-sc2)^2)
Since each axis ranges 0.0-1.0, the maximum possible distance is:
max distance = sqrt(1^2 + 1^2 + 1^2 + 1^2) = 2.0
Two elves at diametrically opposite corners of the aesthetic space are exactly 2.0 apart. Elves within about 0.5 distance are aesthetically compatible; beyond 1.0 they are quite different.
Source: src/sim/components.rs, AestheticPosition::distance_to
Values & Formulas
Audience Evaluation Weights
When an elf evaluates a composition at a revel, their aesthetic position determines how much they weight each quality dimension. The raw weights before normalization:
| Weight | Formula |
|---|---|
| w_mastery | structure x 0.4 + tradition x 0.2 + (1-emotion) x 0.2 + (1-social) x 0.2 |
| w_originality | (1-tradition) x 0.3 + (1-structure) x 0.2 + social x 0.2 + (1-emotion) x 0.3 |
| w_emotional | emotion x 0.4 + social x 0.3 + (1-structure) x 0.15 + (1-tradition) x 0.15 |
These three weights are then normalized to sum to 1.0. The raw sum ranges from about 1.15 to 1.85 depending on position.
The final audience score is:
score = mastery x w_mastery + originality x w_originality + emotional x w_emotional
A social modifier then adjusts the score:
- Social axis > 0.7: +5 points (crowd energy)
- Social axis < 0.3: -3 points (crowd discomfort for introverts)
Source: src/sim/art.rs, evaluate_audience
Genre Affinity
The tradition axis is the primary driver of genre selection:
| Tradition Value | Genre Tendency |
|---|---|
| High (near 1.0) | Strongly Traditional |
| Mid (around 0.5) | Mixed, with ~15% Radical |
| Low (near 0.0) | High Radical probability |
The exact formula:
p_radical = max((1.0 - tradition - 0.5) x 1.5, 0.0)
At tradition=1.0, p_radical=0. At tradition=0.0, p_radical=0.75.
Source: src/sim/art.rs, select_genre
Inspiration Equilibrium
Aesthetic position determines the natural resting state of each inspiration channel:
| Channel | Equilibrium |
|---|---|
| Nature | (1.0 - structure) x 20 |
| Social | social x 25 |
| Rivalry | (1.0 - tradition) x 15 |
| Beauty | (structure + tradition) x 10 |
| Solitude | (1.0 - social) x 25 |
See Inspiration for full details.
Source: src/sim/components.rs, InspirationEquilibrium::from_aesthetic
Drift Mechanics
Aesthetic positions are not static. Three independent drift mechanisms slowly reshape the cultural landscape of the settlement.
Friend Drift
When two friends (relationship strength >= 50) are within 3 Manhattan tiles of each other, their aesthetics converge. This runs once per game day.
Rate: 0.01 per axis per day
The drift direction is the sign of the difference: if a friend's structure is higher, the elf's structure increases by 0.01 (and vice versa). All four axes drift independently.
Only friends within 3 tiles are affected. Distant friends do not drift.
Source: src/sim/systems.rs, FRIEND_DRIFT_RATE = 0.01,
aesthetic_friend_drift_system
Audience Drift (Revel)
When an elf hears a composition performed at a Revel, their aesthetic position drifts toward the composition's aesthetic snapshot (captured at creation time).
Rate: 0.005 per axis per composition heard
This is applied once per composition performed, for every audience member. A revel with 5 performances means up to 5 drift applications per attendee.
Source: src/sim/systems.rs, AUDIENCE_DRIFT_RATE = 0.005,
apply_audience_aesthetic_drift
School Drift
Composers who have received 3 or more Love reactions at revels become aesthetic "schools" -- cultural attractors. Non-friend elves within 5 Manhattan tiles of a school composer drift toward that school's aesthetic.
Rate: 0.008 per axis per day
Unlike friend drift which pulls toward the friend's exact position, school drift pulls toward the direction of the school's aesthetic relative to the center (0.5). If a school composer has structure=0.9, nearby non-friends drift in the positive structure direction.
Friends are excluded from school drift because friend drift already handles them.
| Drift Type | Rate/axis/day | Range | Trigger | Frequency |
|---|---|---|---|---|
| Friend | 0.01 | 3 tiles | Friendship (str >= 50) | Once per day |
| Audience | 0.005 | Revel attendance | Each composition heard | Per performance |
| School | 0.008 | 5 tiles | 3+ Love reactions | Once per day |
Source: src/sim/systems.rs, SCHOOL_DRIFT_RATE = 0.008, SCHOOL_THRESHOLD = 3,
aesthetic_school_drift_system
Composition Aesthetic Shift
When a composition is created, its aesthetic snapshot is not identical to the composer's position. Small shifts are applied based on inspiration balance:
| Axis | Shift |
|---|---|
| Structure | +(solitude - social) x 0.001 |
| Tradition | -(originality / 100) x 0.3 |
| Emotion | +(emotional / 100) x 0.2 |
| Social | +(social - solitude) x 0.001 |
This means highly original works drift the composition's tradition axis downward, and highly emotional works drift the emotion axis upward. These shifted values are what audiences drift toward during revels.
Source: src/sim/systems.rs, composition aesthetic drift logic
Interactions
- Compositions -- Genre family, quality weights, and composition aesthetic all derive from position
- Inspiration -- Equilibrium values are computed from aesthetic position
- Revels -- Audience reactions depend on aesthetic distance; attendance causes drift
- Relationships -- Friends within 3 tiles cause mutual aesthetic convergence
- Satisfaction & Departure -- Elves far from the settlement's aesthetic center feel alienated
Tips
- Friend drift is the strongest per-axis rate (0.01/day), but only activates at close range. Housing friends near each other accelerates cultural convergence.
- School drift creates emergent "movements." A legendary composer surrounded by followers will gradually pull nearby elves toward their taste, creating a coherent artistic identity in that area.
- Audience drift at revels is the main mechanism for settlement-wide cultural coherence. Regular revels with compositions from varied composers spread aesthetic influence broadly.
- An elf's genre tendency is almost entirely determined by their tradition axis. If you want more Radical compositions, cultivate low-tradition elves by exposing them to innovative works at revels.
- The composition aesthetic shift means that a purely traditional elf who writes a highly original piece will produce a composition that actually nudges audiences away from tradition. Art has a life of its own.
- The maximum aesthetic distance of 2.0 is useful context: two elves at 1.5+ distance are aesthetically alien to each other and will react very differently to the same composition.
Revels
Overview
Revels are the cultural heartbeat of an elven settlement -- communal gatherings where compositions are performed, audience reactions are evaluated, relationships form, and the settlement's aesthetic identity evolves. They are the primary way that art connects to the social fabric: a single revel can boost morale, trigger creative blocks, form new fandoms, and shift the aesthetic landscape of the entire community.
Revels are scheduled by the Curator (or the Dummy Curator's rule-based logic) and require a Feast Hall, food, compositions, and enough available elves.
How It Works
Scheduling Requirements
The Dummy Curator schedules a revel when all of the following are true:
| Requirement | Condition |
|---|---|
| Feast Hall | At least one built |
| Compositions | At least one exists in the settlement portfolio |
| Available elves | >= 5 elves not in creative block |
| Food | >= 5 (or >= 15 in Winter) |
| Cooldown | >= 400 ticks since last revel ended |
The LLM Curator uses the same information but makes its own judgment call. The player can also influence revel timing through messages to the curator.
Source: src/sim/curator/dummy.rs, revel scheduling logic
Lifecycle Phases
A revel progresses through three phases, each with a fixed tick duration:
None --> Gathering (5 ticks) --> Performing (5 ticks per piece) --> Aftermath (5 ticks) --> None
Phase 1: Gathering (5 ticks)
During gathering, elves walk toward the Feast Hall. Elves are directed to the hall each tick until they arrive or the phase ends:
- Elves with a creative block are excluded from attendance
- Attendance is capped at the settlement's capacity
- Elves who arrive at the hall receive the
RevelAttendingmarker - Attending elves skip the normal behavior tree for the revel's duration
At the end of the gathering phase, food is consumed:
Food consumed = min(attendee_count, available_food)
If there is not enough food for everyone, all attendees receive a "Sparse feast" mood modifier: -3 for 100 ticks.
Source: src/sim/systems.rs, revel_tick_system, Gathering phase
Phase 2: Performing (5 ticks per composition)
Compositions are performed one at a time, newest first. Each performance takes 5 ticks to complete. At the end of each 5-tick window, audience evaluation runs.
For each audience member and each composition:
- The audience member's aesthetic position determines evaluation weights
- A weighted score is computed from the composition's mastery, originality, and emotional dimensions
- A social modifier is applied (+5 for social axis > 0.7, -3 for social axis < 0.3)
- Discontented elves receive a -5 penalty to their score
- The score maps to a reaction tier
| Score Range | Reaction |
|---|---|
| 0-24 | Dislike |
| 25-50 | Indifferent |
| 51-75 | Enjoy |
| 76-100 | Love |
See Aesthetic Position for the full weight formulas.
Source: src/sim/art.rs, evaluate_audience
Phase 3: Aftermath (5 ticks)
The aftermath phase is a brief wind-down:
RevelAttendingmarkers are removed from all elves- The revel zone is detected from attendee positions
- Average audience score is computed across all performances and reactions
- Great/boring revel satisfaction spikes are applied (see below)
- The revel is archived to history with full reaction data
last_revel_tickis recorded (starts the cooldown timer)
Source: src/sim/systems.rs, revel_tick_system, Aftermath phase
Values & Formulas
Mood Effects
Audience reactions produce mood modifiers:
| Reaction | Mood Effect | Duration |
|---|---|---|
| Dislike | -3 ("Disliked {name}") | 50 ticks |
| Indifferent | No effect | -- |
| Enjoy | +3 ("Enjoyed {name}") | 50 ticks |
| Love | +6 ("Loved {name}") | 100 ticks |
Satisfaction Spikes
Revels directly affect elf satisfaction, which drives the departure system:
| Event | Spike |
|---|---|
| Love reaction (per composition) | +15 to that audience member |
| Great revel (avg score > 60) | +10 to all attendees |
| Boring revel (avg score < 30) | -10 to all attendees |
These are buffered as "spikes" consumed by the satisfaction system on its next tick, so they integrate properly with the satisfaction recomputation.
Source: src/sim/systems.rs, revel satisfaction spike logic
Inspiration Boost
A Love reaction boosts the audience member's dominant inspiration channel by +5 (capped at 100 per channel).
Source: src/sim/systems.rs, Love reaction handler
Aesthetic Drift
Every composition heard at a revel nudges all audience members' aesthetic positions toward the composition's aesthetic snapshot:
Drift rate: 0.005 per axis per composition heard
A revel with 4 performances applies up to 4 drift increments per attendee. See Aesthetic Position for details.
Source: src/sim/systems.rs, AUDIENCE_DRIFT_RATE = 0.005
Fandom Formation
When an elf has a Love reaction to a composition (and is not the composer), the reaction is recorded in their Fandom memory. Each elf tracks up to 5 fan relationships, pruning the weakest if capacity is exceeded.
When a new fandom forms (first Love reaction for that composer), a
FandomFormed event is emitted and archived as a revel incident.
Source: src/sim/components.rs, Fandom; src/sim/systems.rs, fandom logic
in revel_tick_system
Prestige Update
When a composer's work receives a Love reaction, their last_love_tick is
updated. This feeds into the prestige decay system -- recent Love reactions keep
prestige high.
Cooldown
After a revel ends, 400 ticks must pass before the next one can be scheduled. The first revel after settlement creation has its cooldown waived.
| Parameter | Value |
|---|---|
| Cooldown duration | 400 ticks |
| First revel | Cooldown waived |
| Food requirement (normal) | >= 5 |
| Food requirement (Winter) | >= 15 |
| Minimum elves | 5 |
Source: src/sim/curator/dummy.rs, cooldown check; src/sim/world.rs,
last_revel_tick initialization
Revel Archive
Every completed revel is archived with:
- Day number
- Zone name (detected from attendee positions)
- Attendee names
- Full performance records with per-elf reactions and scores
- Incidents (public critiques, fandom formations)
The archive computes an average score across all reactions and identifies the highlight (best-received performance by total reaction score sum).
Source: src/sim/components.rs, RevelArchive
Interactions
- Compositions -- Performed newest-first; quality dimensions drive audience scores
- Aesthetic Position -- Evaluation weights and audience drift
- Inspiration -- Love reactions boost dominant channel; high inspiration prevents creative block
- Satisfaction & Departure -- Great revels boost satisfaction, boring revels damage it
- Needs & Mood -- Reactions generate mood modifiers; sparse feasts cause mood penalties
- Relationships -- Fandom formation creates persistent social bonds
- Buildings -- Feast Hall required; compositions require Workshop
- Artistic Direction -- Direction influences which compositions are created before the revel
Tips
- Schedule revels when your best composers have recently finished new works. Compositions are performed newest-first, so recent high-quality pieces get heard.
- Ensure adequate food before a revel. A "Sparse feast" mood penalty hits every attendee and can tank audience scores for the whole event.
- Revels are the primary mechanism for settlement-wide aesthetic convergence. Without regular revels, elves drift apart culturally and satisfaction drops.
- A revel with low average scores (< 30) actively harms the settlement through the -10 satisfaction spike. It is better to skip a revel than to hold one with only crude compositions.
- Watch for discontented elves at revels -- they evaluate with a -5 penalty, making bad reactions even more likely. Addressing satisfaction before a revel improves outcomes.
- The 400-tick cooldown means roughly one revel every 4 game days (with DAY_LENGTH=100). Winter's higher food requirement (15 vs 5) means you need well-stocked granaries to keep the revel cadence up.
- Fandom is a powerful social mechanic. An elf who Loves a composer's work becomes a fan, which affects future proximity-seeking and inspiration. Legendary composers can reshape the settlement's culture through school drift.
Artistic Direction
Overview
Artistic Direction is the patron's primary tool for shaping the settlement's creative culture. It is a single setting with four modes that influences how the Curator makes decisions about role assignment, composition encouragement, and settlement priorities. The direction does not force any specific outcome -- it nudges the curator's judgment toward a particular aesthetic value.
You cycle through directions by pressing 'd' during normal gameplay (not in Look mode, where 'd' controls the camera).
How It Works
The Four Directions
| Direction | Label | Description |
|---|---|---|
| Balanced | Bal | No preference -- the curator decides freely based on settlement needs |
| Favor Mastery | Mas | Prioritizes high-skill elves as composers; values technical excellence |
| Favor Originality | Orig | Encourages experimental, inspiration-driven work |
| Favor Emotion | Emo | Values emotional resonance over technical skill |
The default starting direction is Balanced.
Pressing 'd' cycles through them in order:
Balanced --> Favor Mastery --> Favor Originality --> Favor Emotion --> Balanced
Source: src/sim/components.rs, ArtisticDirection;
src/model.rs, cycle_artistic_direction
How the Curator Interprets Direction
The direction is communicated to the curator in two ways:
-
System prompt context: The LLM Curator receives the direction as part of its system prompt under "Patron's Direction," with explicit guidance:
- Favor Mastery: "nurture your most skilled composers"
- Favor Originality: "encourage avant-garde elves"
- Favor Emotion: "protect your deeply-feeling artists from creative block"
- Balanced: no specific instruction
-
Dummy Curator rule: When the direction is non-Balanced, the Dummy Curator ensures the best musician (highest music skill) is assigned the Composer role if no Composer has been assigned yet. This applies equally to all three non-Balanced directions.
Source: src/sim/curator/prompt.rs, build_system_prompt;
src/sim/curator/dummy.rs, artistic direction handling
State Snapshot
The current direction is included in the settlement state snapshot sent to the curator each consultation cycle:
patron_direction: "FavorMastery"(or Balanced, FavorOriginality, FavorEmotion)
This means the LLM Curator sees the direction every time it evaluates the settlement and can adjust its strategy accordingly.
Source: src/sim/curator/state.rs, patron_direction field
Values & Formulas
Direction Does Not Affect Composition Scores Directly
Artistic direction does not modify the quality formulas. Mastery is always driven by music skill, originality by inspiration total, and emotional by mood. The direction works indirectly:
| Direction | Indirect Effect |
|---|---|
| Favor Mastery | Curator assigns high-skill elves as Composers, who produce higher mastery scores |
| Favor Originality | Curator encourages conditions for high inspiration (gardens, varied experiences) |
| Favor Emotion | Curator protects emotionally-driven elves from creative block, maintains positive mood |
| Balanced | Curator optimizes for settlement health without bias toward any quality dimension |
Interaction with Audience Evaluation
While direction does not change evaluation weights (those come from individual elf aesthetic positions), the compositions produced under each direction tend to score differently:
| Direction | Tends to Produce | Audience Effect |
|---|---|---|
| Favor Mastery | High mastery scores | Appreciated by structured, traditional elves |
| Favor Originality | High originality scores | Appreciated by innovative, low-tradition elves |
| Favor Emotion | High emotional scores | Appreciated by emotional, social elves |
| Balanced | Even distribution | Moderate reception across the board |
Patron Taste System
Artistic direction is one part of the broader Patron Taste system, which also includes:
| Feature | Description | Control |
|---|---|---|
| Artistic Direction | Bias curator decisions | 'd' key |
| Favorite Compositions | Mark compositions you value | Composition interaction |
| Interesting Elves | Mark elves you want the curator to focus on | Elf interaction |
| Named Locations | Place meaningful names on the map | Map interaction |
The curator sees all of these when making decisions. Favorite compositions that are performed at revels trigger a special patron notification event.
Source: src/sim/components.rs, PatronTaste
TUI Display
The current direction is shown in the status bar with a short label:
| Direction | Status Bar |
|---|---|
| Balanced | Bal |
| Favor Mastery | Mas |
| Favor Originality | Orig |
| Favor Emotion | Emo |
Source: src/render_terminal.rs, direction label rendering
Interactions
- Compositions -- Direction biases which compositions get created through role assignment
- Revels -- Composition quality affects revel outcomes; direction shapes what is composed
- Roles -- Non-Balanced directions influence the curator to assign Composer roles
- The Curator -- Primary consumer of direction; both Dummy and LLM curators respond to it
- Aesthetic Position -- Audience evaluation weights are per-elf, not direction-dependent
Tips
- Balanced is the safe default. The curator already optimizes for settlement health. Only switch to a specific direction when you have a deliberate artistic vision.
- Favor Mastery is strongest in established settlements with high-skill composers. In a young settlement where everyone is skill 1-3, the mastery ceiling is too low for direction to matter much.
- Favor Originality works best when you can supply high inspiration. Build gardens, encourage wandering, and ensure varied experiences. Without inspiration sources, the direction is aspirational but ineffective.
- Favor Emotion is the defensive choice for settlements under stress. Emotional compositions with high mood tend to get broad audience approval, which boosts satisfaction and prevents departures.
- Direction changes take effect on the next curator consultation cycle. There is no delay or transition cost -- switch freely as conditions change.
- The LLM Curator interprets direction more creatively than the Dummy Curator. Where the Dummy Curator simply assigns the best musician as Composer, the LLM Curator might rearrange multiple roles, suggest garden placement, or write messages explaining its artistic reasoning.
- Watch the composition quality breakdowns to verify your direction is working. If you favor Mastery but compositions still have low mastery scores, the problem is likely insufficient music skill, not the direction setting.
Relationships
Elves form bonds with each other through proximity, shared activities, and aesthetic affinity. These relationships shape mood, satisfaction, and the social fabric of your settlement.
Overview
Every elf maintains a list of up to 20 relationships, each with a numeric strength value ranging from -100 to +100. As strength changes, relationships cross thresholds that reclassify them into one of three types: Acquaintance, Friend, or Rival.
Relationships form gradually. Two elves standing near each other and working gain small increments of strength. Over time, those small gains accumulate until a bond crystallizes. The social system runs every 50 ticks, evaluating proximity and adjusting strength for every pair of elves.
How It Works
Bond Types
Relationships are classified by their strength value:
| Type | Strength Range | Description |
|---|---|---|
| Acquaintance | -29 to +49 | Neutral. Default state for any new relationship. |
| Friend | +50 to +100 | Positive bond. Provides mood bonuses and satisfaction gains. |
| Rival | -100 to -30 | Negative bond. Causes mood penalties when nearby. |
New relationships always start as Acquaintance with strength 0.
Source: src/sim/components.rs, Relationships::adjust -- strength clamped to -100..100, Friend at 50+, Rival at -30 or below.
Formation Triggers
Relationships shift through proximity-based delta calculations that fire every 50 ticks in the social system:
Base delta (requires Manhattan distance <= 3 between the two elves):
| Condition | Base Delta |
|---|---|
| Both actively working (not Idle) | +1 |
| Both resting or eating, distance <= 2 | +2 |
| One or both idle | 0 (no change) |
Aesthetic affinity modifier (applied on top of base delta):
| 4D Aesthetic Distance | Modifier |
|---|---|
| < 0.3 (very similar) | +1 |
| 0.3 -- 0.7 (moderate) | 0 |
| 0.7 -- 0.9 (different) | -1 |
| > 0.9 (strongly opposed) | -2 |
Aesthetic distance is computed as Euclidean distance in 4D aesthetic space (structure, tradition, emotion, social axes, each 0.0--1.0). The maximum possible distance is 2.0.
Source: src/sim/systems.rs, social_system -- proximity check at Manhattan <= 3, aesthetic distance thresholds at 0.3/0.7/0.9.
Social Axis Scaling
After computing the combined delta, it is scaled by each elf's Social axis (from their Aesthetic Position):
| Social Axis Value | Multiplier | Personality |
|---|---|---|
| > 0.7 | x2 | Social elf -- bonds form and break faster |
| 0.3 -- 0.7 | x1 | Balanced |
| < 0.3 | x0.5 (halved) | Personal elf -- bonds form slowly |
This means a Social elf gains +2 per working-proximity tick instead of +1, while a Personal elf only gains +0 (rounded down from 0.5). The scaling applies to both positive and negative deltas.
Source: src/sim/systems.rs, apply_social_axis_scale -- threshold checks at 0.7 and 0.3.
Bond Formation Origins
Relationships track how they originally formed, which affects affixes:
| Formation Origin | Trigger |
|---|---|
| Workshop | Proximity while both are composing or building |
| Revel | Bond formed during a revel event |
| Critique | Bond formed through artistic disagreement |
| Rescue | Bond formed when one elf helped another in need |
Source: src/sim/components.rs, BondFormation enum.
Relationship Affixes
Each relationship carries two boolean flags:
-
Tested: Set to
truewhen a friendship (strength >= 50) dips below 50 and then recovers back above 50. Also set during departure recovery -- if an elf nearly leaves but stays, friends who helped keep them get the Tested flag. A "Tested" bond is one that survived adversity. -
Fragile: Starts as
truefor all new relationships. Indicates the bond has not yet been reinforced. Set totrueon relationships where an elf recovered from near-departure without any friend support.
Source: src/sim/components.rs, Relationship struct -- tested and fragile fields.
Values & Formulas
Strength Progression Example
Starting from 0, with both elves actively working within 3 tiles and having similar aesthetics (distance < 0.3):
- Base delta: +1 (both active)
- Aesthetic bonus: +1 (affinity)
- Total per 50-tick cycle: +2 per elf (before social scaling)
- Social elf (> 0.7): +4 per cycle
- Balanced elf: +2 per cycle
- Personal elf (< 0.3): +1 per cycle
At +2/cycle, a balanced elf pair reaches Friend status (+50) in approximately 25 cycles = 1,250 ticks (~12.5 days).
Decay
Every 500 ticks, any relationship where the two elves are not within Manhattan distance 3 of each other decays by -1 strength. This means neglected friendships slowly fade, though it takes 500+ ticks of separation for a friend (50+) to drop back to acquaintance.
Source: src/sim/systems.rs, social_system -- decay branch at tick.is_multiple_of(500).
Capacity and Pruning
Each elf can hold at most 20 relationships. When the list exceeds 20, it is sorted by absolute strength (strongest bonds first) and truncated. This means the weakest acquaintanceships are pruned to make room for stronger bonds.
Source: src/sim/components.rs, Relationships::prune -- MAX_RELATIONSHIPS = 20.
Interactions
Mood Effects
The social mood system runs every 10 ticks and applies mood modifiers based on nearby relationships:
| Situation | Mood Modifier | Duration |
|---|---|---|
| Near a friend (distance <= 3) | +3 | 50 ticks |
| Near a rival (distance <= 3) | -2 | 50 ticks |
| Social elf (> 0.7) with any company nearby | +1 "Enjoying company" | 50 ticks |
| Personal elf (< 0.3) alone | +2 "Peaceful solitude" | 50 ticks |
| Personal elf (< 0.3) with 3+ nearby | -1 "Too many people" | 50 ticks |
Source: src/sim/systems.rs, social_mood_system -- distance checks at 3 (friends/rivals) and 5 (general nearby).
Company Need
The company need (0--100 scale) is influenced by the Social axis and proximity, running every 2 ticks:
| Elf Type | Condition | Effect |
|---|---|---|
| Social (> 0.7) | 2+ elves within distance 3 | +2 company/tick |
| Social (> 0.7) | Alone | -1 company/tick (lonely) |
| Personal (< 0.3) | Nobody within distance 5 | -2 company/tick (relieved) |
| Personal (< 0.3) | 3+ within distance 5 | +1 company/tick (overwhelmed) |
| Balanced | Any | Drifts toward 50 |
For Personal elves, "company" is inverted -- low values are good (solitude achieved).
Source: src/sim/systems.rs, company_system.
Satisfaction
Friend count feeds directly into the satisfaction formula:
Satisfaction = inspiration x 0.3 + morale x 0.2 + friends x 5.0 + aesthetic_fit x 20.0 + revel_score x 0.1 + prestige x 0.15 + spike
Each friend contributes +5.0 to satisfaction. An elf with 4 friends gets +20 satisfaction from relationships alone, which can be the difference between staying and departing.
Departure Cascade
When an elf departs, remaining elves receive mood effects based on their relationship:
| Relationship to Departed | Mood Effect | Duration |
|---|---|---|
| Friend | -10 | 300 ticks |
| Rival | +3 | 100 ticks |
| Acquaintance | -2 | 100 ticks |
Close friends (strength >= 60) also enter a Mourning state for 200 ticks, gaining an additional -5 "Grieving" mood modifier. Mourning elves are drawn toward composing tributes.
Source: src/sim/systems.rs, satisfaction_system -- departure cascade section.
Tips
-
Cluster housing near workshops to maximize proximity time. Elves who rest and work near each other accumulate relationship strength fastest (+2 base for co-resting).
-
Watch the aesthetic positions of your elves. Pairs with similar aesthetics (distance < 0.3) gain bonds 50% faster. The Aesthetic Position panel shows each elf's 4D position.
-
Social elves are relationship engines -- their x2 multiplier means they bond (and feud) at double speed. Assign them roles that keep them near others.
-
Personal elves need space. They bond slowly (x0.5) and get stressed near crowds. Give them solitary tasks like distant gathering.
-
Friendships prevent departure. Each friend adds +5 satisfaction. An elf with 0 friends and low inspiration is at serious risk. Check the Satisfaction page for threshold details.
-
Don't ignore rival buildup. Two aesthetically opposed elves working together can drift to rivalry (-30) in about 15 cycles (750 ticks). Separate them before the -2 mood penalty kicks in.
-
Pruning is automatic at 20 relationships. If an elf has many weak acquaintances, stronger bonds are preserved. You don't need to manage this.
Satisfaction & Departure
Satisfaction measures how content each elf is with life in the settlement. When satisfaction stays too low for too long, the elf will warn you, then leave permanently. This is the primary population-loss mechanic.
Overview
Every elf has a satisfaction value (0--100) that is recomputed every 10 ticks from a weighted formula combining inspiration, mood, friendships, aesthetic alignment, revel quality, and prestige. When satisfaction drops below an elf's personal departure threshold, a countdown begins. If the elf stays below threshold for 300 ticks, they become Discontented (visible warning). If they remain below threshold for 500 more ticks (800 total), they depart -- permanently removed from the settlement.
How It Works
The Satisfaction Formula
Satisfaction is recomputed from scratch every 10 ticks (not accumulated):
Satisfaction = (inspiration x 0.3) + (morale x 0.2) + (friends x 5.0) + (aesthetic_fit x 20.0) + (revel_score x 0.1) + (prestige x 0.15) + spike
The result is clamped to 0--100.
| Component | Weight | Range | Max Contribution |
|---|---|---|---|
| Inspiration total | x 0.3 | 0--100 | 30.0 |
| Morale (base 50 + mood modifiers) | x 0.2 | 0--100 | 20.0 |
| Friend count | x 5.0 | 0--20 | 100.0 (capped by max relationships) |
| Aesthetic fit (1 - distance/2) | x 20.0 | 0.0--1.0 | 20.0 |
| Last revel avg score | x 0.1 | 0--100 | 10.0 |
| Prestige score | x 0.15 | 0--100 | 15.0 |
| Satisfaction spike (revel bonuses) | +direct | varies | consumed once |
Where:
- Inspiration total = sum of all 5 inspiration channels (nature, social, rivalry, beauty, solitude), capped at 100. See Inspiration.
- Morale = base 50 + sum of all active mood modifiers, clamped 0--100. See Needs & Mood.
- Friend count = number of relationships with strength >= 50.
- Aesthetic fit = how well this elf's aesthetic position matches the settlement mean. Calculated as
1.0 - (euclidean_distance / 2.0). An elf at the exact center of the community gets 1.0; one at maximum distance (2.0 in 4D space) gets 0.0. - Revel score = average audience score from the most recent revel.
- Prestige = the elf's social prestige score (0--100), derived from revel performances and fandom.
- Spike = buffered satisfaction delta from revel events. Consumed and zeroed each time the formula runs.
Source: src/sim/systems.rs, satisfaction_system -- formula at the new_value computation.
Departure Thresholds
Each elf has a personal departure threshold that determines when they start considering leaving. This threshold is based on the elf's highest skill level at creation:
| Highest Skill Level | Base Departure Threshold |
|---|---|
| 1--3 | 15.0 |
| 4--6 | 20.0 |
| 7--9 | 25.0 |
| 10 | 30.0 |
More skilled elves are harder to satisfy -- they have higher standards.
Source: src/sim/components.rs, Satisfaction::new -- skill-based threshold.
The Departure Timeline
When satisfaction drops below the elf's personal threshold, a tick counter starts incrementing (by 10 each cycle, since the system runs every 10 ticks):
| Phase | Tick Range Below Threshold | What Happens |
|---|---|---|
| Silent | 0 -- 299 | Counter accumulates. No visible indicator. |
| Discontented | 300 -- 799 | Warning event fires. Discontented marker added. UI shows warning. |
| Departure | 800+ | Elf is permanently despawned from the world. |
- At 300 ticks: a
LeaveWarningevent fires. TheDiscontentedcomponent is added to the elf. The event reports how many ticks remain before departure. - At 800 ticks: the elf departs. A
ElfDepartedevent fires with a reason string -- either "profound dissatisfaction" (satisfaction < 10) or "aesthetic alienation" (satisfaction >= 10 but still below threshold).
The counter resets to 0 whenever satisfaction rises back above the threshold.
Source: src/sim/components.rs, Satisfaction::warning_threshold() returns 300, Satisfaction::departure_ticks() returns 800.
Recovery Mechanics
If a Discontented elf's satisfaction rises above their departure threshold, they recover:
- The
Discontentedmarker is removed. - The ticks-below-threshold counter resets to 0.
- The elf's departure threshold permanently increases by 5.0. This means each near-departure makes the elf harder to keep next time.
- The elf receives a mood modifier: "Reconsidered leaving" +8 for 300 ticks.
- Relationship affixes are updated:
- If the elf has any Friend relationships, those friends get the Tested affix (the bond survived crisis).
- If the elf has no friends, all their relationships get the Fragile affix.
The threshold increase is permanent and cumulative. An elf that has recovered twice from departure attempts has their base threshold raised by 10.0 total.
Source: src/sim/components.rs, Satisfaction::recover -- threshold += 5.0. src/sim/systems.rs, SatAction::Recover branch.
Revel Satisfaction Spikes
Revels can buffer satisfaction deltas through the satisfaction_spike field. Instead of writing directly to the satisfaction value (which would be overwritten on the next 10-tick recomputation), revel events write to this buffer. The satisfaction system consumes the spike by folding it into the formula, then zeroes the buffer.
This means a great revel performance can temporarily boost an elf's satisfaction above their threshold, potentially triggering recovery.
Source: src/sim/components.rs, Satisfaction::apply_spike and the formula in satisfaction_system.
Values & Formulas
Satisfaction Scenarios
| Scenario | Inspiration | Morale | Friends | Aes. Fit | Revel | Prestige | Total |
|---|---|---|---|---|---|---|---|
| Happy elf | 60 (x0.3=18) | 70 (x0.2=14) | 3 (x5=15) | 0.8 (x20=16) | 50 (x0.1=5) | 30 (x0.15=4.5) | 72.5 |
| Struggling elf | 20 (x0.3=6) | 30 (x0.2=6) | 0 (x5=0) | 0.3 (x20=6) | 0 (x0.1=0) | 0 (x0.15=0) | 18.0 |
| Social butterfly | 40 (x0.3=12) | 60 (x0.2=12) | 6 (x5=30) | 0.5 (x20=10) | 40 (x0.1=4) | 20 (x0.15=3) | 71.0 |
| Lonely master | 80 (x0.3=24) | 50 (x0.2=10) | 0 (x5=0) | 0.9 (x20=18) | 60 (x0.1=6) | 50 (x0.15=7.5) | 65.5 |
Recovery Threshold Escalation
| Recovery Count | Threshold (Skill 1-3) | Threshold (Skill 4-6) | Threshold (Skill 10) |
|---|---|---|---|
| 0 (never recovered) | 15.0 | 20.0 | 30.0 |
| 1 | 20.0 | 25.0 | 35.0 |
| 2 | 25.0 | 30.0 | 40.0 |
| 3 | 30.0 | 35.0 | 45.0 |
Timing Summary
| Event | Ticks |
|---|---|
| Satisfaction recomputed | Every 10 ticks |
| Silent countdown phase | 0 -- 299 ticks below threshold |
| Warning fires (Discontented) | 300 ticks below threshold |
| Negotiation window | 300 -- 799 ticks (500-tick window) |
| Departure | 800 ticks below threshold |
At real speed, the full departure timeline from first dropping below threshold is 800 ticks = 8 in-game days.
Interactions
Departure Cascade
When an elf departs, their relationships trigger mood effects on remaining elves:
| Relationship | Mood Effect | Duration |
|---|---|---|
| Friend | "Friend departed" -10 | 300 ticks |
| Rival | "Rival departed" +3 | 100 ticks |
| Acquaintance | "Acquaintance departed" -2 | 100 ticks |
Mourning: Close friends (strength >= 60) enter a Mourning state for 200 ticks. This adds an additional "Grieving" -5 mood modifier that stacks with "Friend departed." Total mood impact for a close friend's departure: -15 for 200 ticks, then -10 alone for the remaining 100 ticks. Mourning elves are drawn toward composing (creating tributes to the departed).
One departure can cascade: the mood hit from a friend leaving can push another elf below their satisfaction threshold, starting a new departure countdown. In a tightly bonded colony, losing one key elf can trigger a chain of departures.
Source: src/sim/systems.rs, satisfaction_system -- Phase 3 departure processing.
Aesthetic Fit
Aesthetic fit rewards elves who align with the settlement consensus. The settlement aesthetic center is the weighted mean of all elves' aesthetic positions. Outlier elves -- those with very different creative values -- have lower aesthetic fit and thus lower satisfaction.
This creates a natural tension: aesthetic diversity makes for richer compositions at revels, but outliers are harder to retain.
Prestige and Recognition
Prestige contributes up to 15 points of satisfaction (at score 100). Elves who perform well at revels, gain fans, and build a strong portfolio accumulate prestige. Recognizing an elf's work helps keep them satisfied.
Forest Spirit Impact
The Forest Spirit does not directly affect satisfaction, but its effects on mood (through weather disruption and comfort) can indirectly lower morale, which feeds the satisfaction formula at a 0.2 weight.
Tips
-
Friends are the strongest lever. Each friend adds +5 to satisfaction. Getting even one friendship for an at-risk elf can pull them above threshold. See Relationships for how to accelerate bonding.
-
Watch the events panel for
LeaveWarningevents. You have 500 ticks (5 in-game days) between the warning and departure. Act immediately. -
Revel spikes can save elves. A well-timed revel with high audience scores injects a satisfaction spike that can push a Discontented elf above their threshold, triggering recovery.
-
Recovery has a cost. Each recovery raises the threshold by +5 permanently. An elf that has recovered twice is now 10 points harder to keep happy. At some point, it may be better to invest in new arrivals than to keep saving the same discontented elf.
-
Outlier aesthetics are a risk. If one elf has a radically different aesthetic position from the settlement center, their aesthetic_fit will be low (potentially 0.0, costing them 20 satisfaction points). Consider using Artistic Direction to shift the settlement's creative center.
-
Morale management matters. At 0.2 weight, the difference between morale 30 (Stressed) and morale 80 (Inspired) is 10 satisfaction points. Keep needs above the Wanting threshold.
-
Monitor the "Struggling elf" scenario -- an elf with 0 friends, low inspiration, and poor aesthetic fit can have satisfaction as low as 18. That is below even the lowest departure threshold (15.0) and will trigger departure in 800 ticks with no intervention.
-
Plan for cascade risk. If your top composer has 4+ close friends and departs, every friend takes -10 mood for 300 ticks, and close friends (strength >= 60) additionally enter Mourning at -5 for 200 ticks. This can domino. Prioritize retention of well-connected elves.
Favorite Places
Overview
Elves develop attachment to locations they spend time in. Over repeated visits, a position becomes a favorite place -- a spot the elf feels drawn to and gains comfort from. Each elf can have up to 3 favorite places.
Favorite places interact with the personal time behavior: idle elves occasionally take short breaks to visit a favorite spot or a garden, gaining beauty inspiration and a mood boost.
How It Works
Attachment Formation
The favorite places system runs every 10 ticks. For each stationary elf (no active pathfinding), the system checks whether their current position is "meaningful":
| Position Type | Qualifies? |
|---|---|
| Within 1 tile of a building (Workshop, Garden, Dwelling, etc.) | Yes |
| On scenic terrain (Ancient Forest, Meadow) | Yes |
| Open terrain with no buildings nearby | No |
If the position qualifies, visit ticks accumulate. Once a position reaches the attachment threshold of 20 visit ticks, it becomes a favorite.
Source: src/sim/systems.rs, favorite_places_system; src/sim/components.rs, FavoritePlaces.
Slot Management
Each elf has 3 favorite place slots. Slots are sorted by visit count (most visited first). New positions are added to empty slots. When all 3 slots are full, new positions cannot displace existing favorites -- the elf must continue visiting one of their current 3.
Mood Boost
When an elf is standing at a favorite place, they receive a mood modifier:
| Modifier | Value | Duration | Semantics |
|---|---|---|---|
| "Favorite spot" | +1 | 15 ticks | Replace (no stacking) |
This is a small but steady comfort bonus for elves who spend time in places they've grown attached to.
FavoritePlaceFormed Event
When a new favorite forms (position crosses the 20-tick threshold), a FavoritePlaceFormed event fires with the elf's name and a description of the location (zone name if in a zone, or terrain type with coordinates).
Personal Time
Idle elves have a 5% chance per idle decision to take personal time instead of accepting work. During personal time, the elf paths toward their top favorite place (or a Garden if no favorites exist).
On arrival, the elf receives:
| Benefit | Amount |
|---|---|
| Beauty need | +5 |
| Beauty inspiration | +3 |
| Solitude inspiration | +2 |
| Mood: "Personal time" | +2 for 50 ticks |
After receiving these benefits, the elf returns to Idle and resumes normal behavior.
Personal time is a low-priority behavior -- it is preempted by hunger, exhaustion, and all other urgent needs.
Source: src/sim/systems.rs, personal_time_system, task_decision_system Step 3d.
Interactions
- Needs & Mood -- Favorite spot mood boost contributes to morale; personal time restores beauty need.
- Inspiration -- Personal time adds beauty and solitude inspiration, feeding into composition quality.
- Satisfaction -- Mood improvements from favorite places and personal time contribute to morale, which feeds the satisfaction formula at 0.2 weight.
- Buildings -- Buildings create "meaningful" positions that can become favorites. Gardens are common personal time destinations.
Tips
-
Workshops and Gardens naturally generate favorites. Elves who compose regularly at the same workshop will develop attachment to it.
-
Favorite places are a retention tool. The +1 mood boost is small but persistent. An elf standing at a favorite spot while composing gets a steady morale lift.
-
Personal time is self-regulating. At 5% per idle check, it happens roughly once every 20 idle decisions. You don't need to manage it -- elves take breaks on their own.
-
Scenic terrain matters. Elves near Ancient Forest or Meadow tiles can develop favorites without buildings nearby. Consider settlement placement near scenic areas.
Seasons & Weather
The climate system drives a 100-day year divided into four 25-day seasons. Weather and temperature shift each day, affecting mood, foraging efficiency, and the forest spirit.
Overview
Time in Elf Revel is measured in ticks. One in-game day is 100 ticks. A full year is 100 days (10,000 ticks), split evenly into four seasons of 25 days each. At each day boundary, the climate system advances the season (if needed), rolls for new weather, and computes a daily base temperature with jitter.
Temperature updates every tick based on time of day. Weather persists with 70% momentum -- there is only a 30% chance it changes on any given day within the same season, while season boundaries always force a reroll.
How It Works
The Year Cycle
| Season | Days | Day Range (in year) | Description |
|---|---|---|---|
| Spring | 0--24 | 0--24 | Awakening. Balanced foraging. Spirit is sensitive. |
| Summer | 25--49 | 25--49 | Peak abundance. Highest foraging multiplier. |
| Autumn | 50--74 | 50--74 | Declining bounty. Snow begins to appear. |
| Winter | 75--99 | 75--99 | Harsh. Reduced foraging. Snow is common. Spirit dormant. |
Years wrap: day 100 is Spring of year 1, day 200 is Spring of year 2, and so on.
Source: src/sim/climate.rs, SEASON_LENGTH = 25, YEAR_LENGTH = 100, Season::from_day.
Time of Day
Each 100-tick day is divided into four periods:
| Period | Tick Range (within day) | Temperature Modifier |
|---|---|---|
| Dawn | 0--9 | -5 |
| Day | 10--69 | +0 (base) |
| Dusk | 70--84 | -3 |
| Night | 85--99 | -8 |
The temperature modifier is applied to the daily base temperature each tick. Dawn and Night are the coldest periods.
Source: src/sim/world.rs, TimeOfDay::from_tick. src/sim/climate.rs, Climate::update_temperature.
Temperature Curve
Each season defines a quadratic temperature curve with three control points: start, mid-extreme, and end. The temperature is interpolated across the 25 days of the season using quadratic interpolation, then jittered by a random value in the range +/-5.
| Season | Start Temp | Mid-Extreme | End Temp |
|---|---|---|---|
| Spring | 35 | 45 | 55 |
| Summer | 55 | 75 | 65 |
| Autumn | 65 | 45 | 30 |
| Winter | 30 | 15 | 25 |
The interpolation formula uses quadratic Bezier-style weighting:
base = start x (1-t)(1-2t) + mid x 4t(1-t) + end x t(2t-1)
Where t = day_in_season / 24 (0.0 to 1.0).
After interpolation, jitter of +/-5 is applied, and the result is clamped to 0--100. Temperature can never go below 0 or above 100.
Source: src/sim/climate.rs, Season::temperature_curve and Climate::advance_day.
Temperature Thresholds
| Condition | Threshold | Effect |
|---|---|---|
| Cold | Temperature < 25 | Outdoor mood penalty: "Chilled" -2 |
| Hot | Temperature > 75 | Universal mood penalty: "Sweltering" -1 |
Cold only affects elves outdoors (not within Manhattan distance 2 of a roofed building). Hot affects everyone.
Source: src/sim/climate.rs, is_cold() and is_hot(). src/sim/systems.rs, weather_mood_system.
Weather System
Weather is determined daily. On a season boundary, weather is always rerolled. Within a season, there is a 30% chance of reroll and a 70% chance the previous weather persists (momentum).
Source: src/sim/climate.rs, Climate::advance_day -- rng.gen::<f32>() < 0.3 triggers reroll.
Weather Types
| Weather | Description | Possible Seasons |
|---|---|---|
| Clear | Sunny skies. No special effects. | All |
| Cloudy | Overcast. No direct effects. | All |
| Rain | Outdoor mood penalty. | All |
| Storm | Flavor event (neutral mood). | All |
| Snow | Outdoor beauty bonus. | Autumn, Winter only |
| Fog | Inspiration boost for skilled musicians. | All |
Snow has zero weight in Spring and Summer -- it physically cannot occur in those seasons.
Source: src/sim/climate.rs, Weather::season_weights.
Values & Formulas
Season Weather Weights
Each weather type has a probability weight per season. To get the percentage chance, divide by the row total (100 in all cases).
| Weather | Spring | Summer | Autumn | Winter |
|---|---|---|---|---|
| Clear | 40 | 60 | 40 | 30 |
| Cloudy | 25 | 15 | 25 | 25 |
| Rain | 25 | 10 | 20 | 10 |
| Storm | 5 | 10 | 10 | 5 |
| Snow | 0 | 0 | 5 | 25 |
| Fog | 5 | 5 | 0 | 5 |
Notable patterns:
- Summer is 60% Clear -- the best season for outdoor work.
- Winter has a 25% Snow chance -- the highest of any weather type besides Clear.
- Fog only appears in Spring, Summer, and Winter (0% in Autumn).
- Storms are rare in Spring and Winter (5%), more common in Summer and Autumn (10%).
Source: src/sim/climate.rs, Weather::season_weights.
Seasonal Mood Modifiers
In addition to weather, each season applies a persistent mood modifier to all elves. These are refreshed at every day boundary using replace semantics.
| Season | Modifier | Value | Duration |
|---|---|---|---|
| Spring | "Spring optimism" | +2 | 1 day (100 ticks) |
| Summer | (none) | -- | -- |
| Autumn | "Autumn melancholy" | -1 | 1 day (100 ticks) |
| Winter | "Winter stillness" | -1 | 1 day (100 ticks) |
Spring is the most mood-positive season (+2 baseline), while Autumn and Winter carry a persistent -1 drag on morale. Summer is neutral -- no seasonal modifier, but typically benefits from 60% Clear weather.
Source: src/sim/systems.rs, seasonal_mood_system.
Weather Mood Effects
These are applied by the weather mood system. "Outdoors" means the elf is more than Manhattan distance 2 from any Dwelling, Workshop, or Feast Hall.
| Weather/Condition | Target | Mood Value | Duration | Notes |
|---|---|---|---|---|
| Rain (outdoors) | Outdoor elves | -1 "Caught in rain" | 50 ticks | Shelter negates |
| Snow (outdoors) | Outdoor elves | +2 "Snow-covered landscape" | 50 ticks | Beauty bonus |
| Storm | All elves | 0 "Sheltering from storm" | 50 ticks | Flavor only |
| Fog | Musicians (skill > 5) | +1 "Mysterious fog" | 50 ticks | Also +1 Nature inspiration |
| Cold (temp < 25, outdoors) | Outdoor elves | -2 "Chilled" | 50 ticks | Shelter negates |
| Hot (temp > 75) | All elves | -1 "Sweltering" | 50 ticks | Cannot be avoided |
Mood effects use replace semantics -- they refresh the duration instead of stacking. An elf standing in rain for 100 ticks gets one -1 modifier refreshed repeatedly, not multiple stacking penalties.
Source: src/sim/systems.rs, weather_mood_system -- uses mood.replace().
Foraging Multipliers
The seasonal foraging multiplier affects passive sustenance gain when elves forage:
| Season | Multiplier | Effective Foraging |
|---|---|---|
| Spring | 1.0x | Baseline |
| Summer | 1.5x | Peak abundance |
| Autumn | 1.25x | Slight bonus |
| Winter | 0.5x | Halved |
Foraging happens every 10 ticks for elves with sustenance below 40. On forest terrain, the base gain is 8; on meadow or other walkable terrain, it is 5 (capped at 60). The seasonal multiplier applies to the overall foraging economy of the settlement.
Source: src/sim/climate.rs, Climate::season_foraging_multiplier. src/sim/systems.rs, foraging_system.
Interactions
Forest Spirit
The Forest Spirit responds differently to clearing based on season. Clearing forest in Spring adds +7 anger (vs. +5 in other seasons) because the forest is awakening. The spirit's natural dawn decay and garden calming also vary by season -- see the Forest Spirit page for details.
Composition and Inspiration
Fog weather adds +1 to the Nature inspiration channel for all elves, which can help trigger compositions. Snow gives a beauty mood bonus that feeds into morale, indirectly improving composition emotional depth.
Needs Decay
Weather does not directly change needs decay rates, but the mood modifiers it produces affect morale, which determines the morale state (Inspired/Normal/Stressed/Breaking). See Needs & Mood. Morale state in turn affects work speed: Inspired elves get +2 work speed, Stressed elves get -1.
Building Shelter
Roofed buildings (Dwelling, Workshop, Feast Hall) provide shelter within Manhattan distance 2. Gardens do not provide shelter -- they are open-air structures. In rainy or cold weather, having roofed buildings near work areas protects your elves from mood penalties.
Tips
-
Stockpile food before Winter. Foraging drops to 0.5x, and Snow weather (25% chance) adds further pressure. Aim for a food stockpile of 15+ by day 50 (mid-Autumn).
-
Summer is build season. With 60% Clear weather and 1.5x foraging, your elves can work outdoors without mood penalties and food accumulates naturally. Queue major construction projects for Summer.
-
Build roofed structures early. A single Dwelling shelters all elves within 2 tiles from rain (-1 mood) and cold (-2 mood). Place it centrally.
-
Fog is a gift for musicians. If you have a high-skill composer (Music > 5), fog gives them +1 mood and +1 Nature inspiration. Don't pull them indoors during fog.
-
Snow is surprisingly pleasant. The +2 beauty mood bonus outweighs any cold penalty for elves near shelter. Let your elves enjoy it, but make sure they have a warm building nearby.
-
Watch season transitions. Weather always rerolls at a season boundary. The jump from Autumn to Winter can bring sudden Snow (25% weight) and cold temperatures. Prepare your settlement layout accordingly.
-
Spring clearing is dangerous. Clearing forest in Spring costs +7 spirit anger instead of +5. If you need to expand, wait until Summer when the spirit is less reactive.
-
Night is the coldest period. At -8 from base temperature, Night in Winter can push temperatures down to single digits. Ensure resting elves are near Dwellings.
-
Spring is the best season for morale. The +2 "Spring optimism" modifier offsets rain penalties and helps recovering Discontented elves. Time revel performances for Spring to maximize audience mood.
-
Autumn and Winter stack mood drags. The -1 seasonal modifier on top of cold weather (-2) and rain (-1) can push morale down quickly. Plan building shelter completion before Autumn arrives.
Forest Spirit
The forest spirit is the ancient consciousness of the woodland that surrounds your settlement. As you clear trees and expand, its anger rises. If left unchecked, the spirit's displeasure manifests as alerts, mood effects, and a growing threat to your colony's harmony.
Overview
The forest spirit is tracked by a single meter value from 0 to 100. The meter determines the spirit's state, which escalates through four tiers as anger accumulates. Clearing forest tiles raises the meter; natural decay at dawn and Garden buildings lower it. The challenge is to balance expansion (which requires clearing) with the spirit's tolerance.
How It Works
Spirit States
The spirit's behavior is determined by its meter value:
| State | Meter Range | Description |
|---|---|---|
| Harmony | 0--20 | Peaceful coexistence. No negative effects. |
| Tension | 21--50 | The forest stirs. Alert appears in the UI. |
| Displeasure | 51--75 | Active resistance. The settlement feels the pressure. |
| Anger | 76--100 | The forest is hostile. Significant penalties. |
The meter is clamped to 0--100 using saturating arithmetic -- it cannot go below 0 or above 100.
Source: src/sim/world.rs, ForestSpirit::state -- match on meter ranges. ForestSpirit::add and sub use saturating ops with min(100).
Anger Triggers
The only action that raises the spirit meter is clearing forest tiles. When an elf completes a ClearForest task, changing a YoungForest tile to Meadow:
| Season | Anger Increase Per Tile |
|---|---|
| Spring | +7 |
| All other seasons | +5 |
Spring incurs a heavier penalty because the forest is awakening -- clearing during this time is seen as desecration. There is no penalty for simply walking through or gathering from forest tiles.
Each cleared tile also produces 3 Wood and grants 10 Building XP to the elf who cleared it.
Source: src/sim/systems.rs, clear_forest_system -- spirit.add(if season == Season::Spring { 7 } else { 5 }).
Calming Mechanics
The spirit meter decays through two mechanisms, both applied at dawn (once per day, when tick is a multiple of the day length):
Natural Decay
The spirit naturally calms by -1 per dawn.
The doc-comments in the source describe seasonal variation (Spring: -2, Summer/Autumn: -1, Winter: 0 dormant), but the current implementation applies a flat -1 regardless of season.
Source: src/sim/systems.rs, forest_spirit_system -- spirit.sub(1).
Garden Calming
Each Garden building reduces the spirit meter by -2 per dawn. This stacks with natural decay and with multiple gardens.
| Gardens | Total Dawn Decay |
|---|---|
| 0 | -1 (natural only) |
| 1 | -3 (-1 natural, -2 garden) |
| 2 | -5 (-1 natural, -4 gardens) |
| 3 | -7 (-1 natural, -6 gardens) |
Gardens work regardless of season -- even when natural decay is minimal, gardens still calm the spirit. This makes them the primary tool for spirit management.
Source: src/sim/systems.rs, forest_spirit_system -- spirit.sub((garden_count as u8) * 2). Confirmed by test: "Gardens should reduce spirit faster" asserts 20 - 5 = 15 with 2 gardens.
Rate of Change Examples
Clearing without gardens (non-Spring): Each cleared tile adds +5. Dawn decay removes -1. Net per day if you clear one tile: +4.
Clearing with 2 gardens (non-Spring): Each cleared tile adds +5. Dawn decay removes -5 (-1 natural, -4 gardens). Net per day if you clear one tile: +0 -- perfectly balanced.
No clearing with 2 gardens: Dawn decay removes -5 per day. A meter at 50 reaches 0 in 10 days.
Spring clearing without gardens: Each cleared tile adds +7. Dawn decay removes -1. Net per day if you clear one tile: +6. The meter rises quickly.
Values & Formulas
Spirit Meter Math
| Action | Effect | When |
|---|---|---|
| Clear YoungForest tile (Spring) | +7 | On task completion |
| Clear YoungForest tile (other seasons) | +5 | On task completion |
| Natural dawn decay | -1 | Every dawn |
| Per Garden at dawn | -2 | Every dawn |
| Meter minimum | 0 | Saturating subtraction |
| Meter maximum | 100 | Capped at 100 |
Days to Reach Key Thresholds (No Gardens)
Starting from Harmony (meter 0), clearing one tile per day:
| Target State | Meter Required | Days (non-Spring) | Days (Spring) |
|---|---|---|---|
| Tension | 21 | 6 days (6 clears x net +4 = 24) | 4 days (4 x net +6 = 24) |
| Displeasure | 51 | 13 days | 9 days |
| Anger | 76 | 19 days | 13 days |
Days to Calm from Key States (No Clearing)
With various garden counts, days to return from Anger (meter 76) to Harmony (meter 20):
| Gardens | Dawn Decay | Days to Drop 56 Points |
|---|---|---|
| 0 | -1/day | 56 days |
| 1 | -3/day | 19 days |
| 2 | -5/day | 12 days |
| 3 | -7/day | 8 days |
Clearing Progress Rate
The ClearForest task progresses at a rate of 5 + building_skill per tick, completing at 100:
| Building Skill | Progress/Tick | Ticks to Complete |
|---|---|---|
| 1 | 6 | 17 ticks |
| 3 | 8 | 13 ticks |
| 5 | 10 | 10 ticks |
| 10 | 15 | 7 ticks |
Higher-skill builders clear faster, which means they can also anger the spirit faster.
Source: src/sim/systems.rs, clear_forest_system -- rate = (5 + skill).max(1), completes at progress >= 100.
Interactions
Seasons
The spirit meter interacts with Seasons & Weather in two ways:
- Spring penalty: Clearing in Spring costs +7 instead of +5. Plan heavy expansion for Summer or Autumn.
- Dawn timing: Spirit decay happens once per dawn. Since a day is 100 ticks and dawn is ticks 0--9, the decay fires at the start of each new day.
Buildings
Gardens are the primary spirit management tool at -2/dawn each. Other buildings have no direct spirit interaction, but expanding your settlement by clearing forest to make room for buildings is what drives the meter up in the first place.
Mood and Satisfaction
The spirit meter currently produces UI alerts when above Harmony but does not directly apply mood modifiers. However, the consequences of reaching high anger states constrain your expansion, which can indirectly affect elf satisfaction by limiting available resources and building space.
Cultural Advisor
The Curator monitors the spirit state and includes it in settlement alerts when above Harmony. The Dummy Curator factors spirit state into its clearing decisions, avoiding forest clearing when the spirit is already elevated.
Terrain
Only YoungForest tiles can be cleared (converted to Meadow). AncientForest tiles cannot be cleared. This means the spirit meter has a natural ceiling based on the number of YoungForest tiles on the map.
Source: src/sim/systems.rs, clear_forest_system -- checks terrain == Terrain::YoungForest.
Tips
-
Build 2 Gardens early. Two Gardens provide -4/dawn on top of the -1 natural decay, for a total of -5/dawn. This exactly offsets clearing one YoungForest tile per day in non-Spring seasons, keeping the meter stable.
-
Avoid clearing in Spring. The +7 per tile (vs. +5) and the fact that Spring is when the forest is most sensitive makes it the worst season for expansion. Use Spring for composing, socializing, and stockpiling.
-
The 20 → 21 boundary matters. Crossing from Harmony to Tension triggers a persistent alert in the UI. If the spirit reaches Tension, stop clearing and let gardens work it back down before resuming.
-
Plan clearing bursts with recovery periods. If you need to clear 5 tiles quickly, do it in a batch during Summer (+25 meter), then pause clearing for several days. With 2 Gardens, the meter drops at -5/day.
-
Track the cleared tile count. The game tracks total tiles cleared. More clearing means less forest for foraging and beauty effects. Clear strategically -- only where you need building space.
-
Gardens are dual-purpose. They calm the spirit (-2/dawn) AND provide +3 beauty/tick to nearby elves AND boost the beauty need. Build them at the edges of your settlement, facing the forest.
-
You cannot anger the spirit by gathering. Foraging, gathering wood from resource nodes, and walking through forest tiles are all safe. Only the ClearForest task (which converts tiles) provokes the spirit.
-
AncientForest is safe. You physically cannot clear AncientForest tiles. They provide higher beauty values (+2 vs. +1 for YoungForest) and a 30% chance of FineWood resource nodes. Expand into YoungForest areas instead.
Zones
As you place buildings in your settlement, the game automatically detects zones -- named clusters of buildings with a classification based on their composition. Zones give your settlement structure and identity, helping you and the elves understand the layout at a glance.
Overview
The zone detection system scans all placed buildings and groups them into proximity-based clusters. Each cluster with 2 or more buildings becomes a named zone with a classification (Art Quarter, Residential, Commons, or Mixed). Zones are recalculated periodically and displayed in the UI.
Zone detection is passive -- you do not place zones manually. Instead, zones emerge organically from your building placement decisions. Place a Workshop and a Garden near each other and an Art Quarter appears. Cluster Dwellings together and a Residential district forms.
How It Works
Detection Algorithm
The zone detection system uses proximity clustering with a Manhattan-distance radius of 4 tiles:
- Clear existing zones -- zones are recalculated from scratch each time.
- Collect all buildings -- every entity with a Position and Building component.
- Cluster by proximity -- for each building, check if it falls within Manhattan distance 4 of the center of an existing cluster. If so, add it to that cluster. If not, start a new cluster.
- Classify clusters -- only clusters with 2 or more buildings become zones. Single buildings are ignored.
- Name zones -- auto-generated from terrain and classification, or overridden by a nearby patron-named location.
The cluster center is computed as the arithmetic mean of all building positions in the cluster. Buildings are processed in order, and each building joins the first cluster whose center is within range (greedy assignment).
Source: src/sim/systems.rs, zone_detection_system -- cluster_radius = 4i32, center computed as sum/count.
Zone Types
Zones are classified based on which building types are present in the cluster:
| Zone Type | Classification Rule | Typical Use |
|---|---|---|
| Commons | Contains a Feast Hall | Social gathering area |
| Art Quarter | Contains both a Workshop AND a Garden | Creative district |
| Residential | Contains 2+ Dwellings (no Feast Hall, not Workshop+Garden) | Living quarters |
| Mixed | Everything else with 2+ buildings | General-purpose area |
The rules are evaluated in priority order:
- If the cluster contains a Feast Hall --> Commons (regardless of other buildings).
- Else if the cluster contains both a Workshop and a Garden --> Art Quarter.
- Else if the cluster contains 2 or more Dwellings --> Residential.
- Otherwise --> Mixed.
This means a Feast Hall always dominates the classification. A cluster with a Feast Hall, 3 Dwellings, and a Workshop is still classified as Commons.
Source: src/sim/systems.rs, zone_detection_system -- classification logic with has_feast_hall, has_workshop && has_garden, dwelling_count >= 2.
Building Types Reference
The four building types that participate in zone detection:
| Building | Zone Influence | Other Effects |
|---|---|---|
| Dwelling | Residential (if 2+) | Shelter from weather. Faster rest recovery. |
| Workshop | Art Quarter (with Garden) | Composing station. Stimulation boost. |
| Garden | Art Quarter (with Workshop) | Beauty +3/tick. Spirit calming -2/dawn. |
| Feast Hall | Commons (always) | Revel venue. Social gathering point. |
Zone Naming
Each zone receives an auto-generated name based on two components:
Terrain prefix (based on the terrain at the zone center):
| Terrain at Center | Prefix |
|---|---|
| AncientForest | "The Groveward" |
| YoungForest | "The Verdant" |
| Meadow | "The Sunlit" |
| Stone | "The Hearthstone" |
| Other | "The Central" |
Classification suffix:
| Zone Type | Suffix |
|---|---|
| Art Quarter | "Atelier" |
| Residential | "Rest" |
| Commons | "Commons" |
| Mixed | "Quarter" |
Combined examples:
- A Workshop + Garden on a Meadow tile: "The Sunlit Atelier"
- Two Dwellings near an AncientForest tile: "The Groveward Rest"
- A Feast Hall on a Stone tile: "The Hearthstone Commons"
Patron name override: If the player has placed a Named Location (via the patron naming system) within Manhattan distance 4 of the zone center, that name overrides the auto-generated name entirely. This lets you personalize your settlement districts.
Source: src/sim/systems.rs, zone_detection_system -- terrain prefix match, kind suffix match, named_locations override.
Zone Properties
Each detected zone stores the following data:
| Field | Type | Description |
|---|---|---|
| center | Position | Arithmetic mean of all building positions in the cluster |
| radius | u8 | Always 4 (the cluster detection radius) |
| kind | ZoneKind | Art Quarter, Residential, Commons, or Mixed |
| name | String | Auto-generated or patron-overridden name |
| building_count | u32 | Number of buildings in the zone |
Source: src/sim/components.rs, Zone struct.
Values & Formulas
Clustering Math
Two buildings are in the same cluster if:
|building.x - center.x| + |building.y - center.y| <= 4
Where center is the running mean of all buildings already in the cluster. Buildings are assigned greedily -- the first cluster within range absorbs the building. Order of processing can affect which cluster a building joins if it is equidistant from two clusters.
Minimum Cluster Size
A cluster needs >= 2 buildings to become a zone. A single isolated building produces no zone. This means you need at least 2 buildings within Manhattan distance 4 of each other to see any zone appear.
Zone Classification Decision Table
| Feast Hall? | Workshop + Garden? | 2+ Dwellings? | Result |
|---|---|---|---|
| Yes | (any) | (any) | Commons |
| No | Yes | (any) | Art Quarter |
| No | No | Yes | Residential |
| No | No | No | Mixed |
Example Layouts
Minimal Art Quarter: Place a Workshop and a Garden within 4 tiles of each other. No other buildings needed. Result: Art Quarter with building_count = 2.
Minimal Residential: Place 2 Dwellings within 4 tiles. Result: Residential with building_count = 2.
Upgraded Commons: Place a Feast Hall, 2 Dwellings, and a Garden all within a 4-tile cluster. Result: Commons (Feast Hall dominates), building_count = 4.
Split zones: Place a Workshop at (0,0) and a Garden at (10,0). Distance = 10 > 4, so they form separate clusters. Neither cluster has 2 buildings, so no zones are detected. Move them closer (within 4 tiles) to form an Art Quarter.
Interactions
Revels
The Revel system uses zones to determine performance context. Revels happen at the Feast Hall, which is typically the center of a Commons zone. The zone context can influence the flavor of revel events.
Composition
Elves composing in an Art Quarter zone may receive contextual bonuses. The zone's presence near a Workshop affects which elves are drawn to compose there. See Compositions.
Terrain Effects
Zone classification is independent of terrain, but the auto-generated name depends on the terrain at the zone center. Building on different terrain types gives your zones different names and character. See Terrain.
Patron Naming
The patron taste system allows you to name locations on the map. If a named location falls within 4 tiles of a zone center, the zone adopts that name. This is how you personalize your settlement -- name a spot "Luthien's Garden" and any zone that forms near it takes that name.
Cultural Advisor
The Curator considers zones when making building placement decisions. It may prefer to expand existing zones (adding buildings near existing clusters) rather than starting new isolated structures.
Tips
-
Plan your layout with zones in mind. Place your first Workshop and Garden within 4 tiles of each other to create an Art Quarter early. This gives your composers a named creative district.
-
The Feast Hall defines your social center. Any cluster containing a Feast Hall becomes Commons, regardless of other buildings. Place the Feast Hall where you want your settlement's social hub.
-
Separate zones for different purposes. If you want both an Art Quarter and a Residential district, keep them more than 4 tiles apart. Otherwise they will merge into a single cluster and the classification will follow the priority rules.
-
Use patron naming for character. Auto-generated names like "The Sunlit Atelier" are pleasant, but naming a location yourself makes the settlement feel personal. Name a spot before or after buildings appear nearby.
-
Building density matters. A zone with 5 buildings is more robust than one with 2 -- if you remove one building, a 5-building zone survives, but a 2-building zone could drop below the minimum and disappear.
-
Watch for unintended merges. If you build a Dwelling at the edge of your Art Quarter cluster, it gets absorbed and the zone may reclassify. Keep residential buildings at least 5 tiles from your creative district if you want separate zones.
-
Mixed zones are a fallback. If a 2+ building cluster doesn't match any specific pattern, it becomes Mixed. This is fine early on, but you can upgrade a Mixed zone by adding the right building types (e.g., add a Garden to a Workshop cluster to get Art Quarter).
-
Zones are recalculated periodically. They are not permanent. Moving buildings (by demolishing and rebuilding) or adding new ones will change the zone layout on the next detection pass.
The Curator System
Overview
The curator is the AI layer that manages your settlement's cultural direction. It sits between you (the patron) and your elves, translating high-level artistic vision into concrete settlement decisions: who does what, what gets built, when to hold a revel.
Elf Revel uses a three-tier intentionality model:
- Patron (you) -- provides taste, values, and broad artistic direction via
ArtisticDirectionsettings and direct messages. - Curator (AI advisor) -- reads the settlement state and issues
CulturalCommands. Two implementations: a rule-basedDummyCurator(always available) and an LLM-backedLlmCurator(native only, usesclaudeCLI). - Elves (autonomous agents) -- execute tick-level behaviors: gathering, building, composing, attending revels. They have their own needs, aesthetics, and relationships.
The human has taste, the AI has hands, the elves have lives.
How It Works
The CulturalAdvisor Trait
Every curator implements the CulturalAdvisor trait, which defines three core methods:
| Method | Purpose |
|---|---|
consult(world) | Produce a list of CulturalCommands based on current game state |
consult_with_message(world, message) | Same, but with a player-typed message for context |
should_consult(world, events) | Decide whether the curator wants to run this tick |
Two additional methods handle forest-clearing tracking (on_forest_cleared) and UI display (last_reasoning).
When the Curator Is Consulted
The default cadence is once per game day (every 100 ticks). The should_consult method fires at day boundaries -- when tick / DAY_LENGTH changes.
The LlmCurator extends this with event-driven triggers. It will also consult when:
| Event | Condition |
|---|---|
RevelEnded | Always |
ArtCompleted | Always |
InspirationCrisis | Always |
ResourceLow | When amount < 5 |
SpiritStateChanged | When spirit enters "Anger" |
It also returns true immediately if a pending LLM result has arrived from the background thread.
The CulturalCommand Enum
When consulted, the curator returns a Vec<CulturalCommand>. Each variant maps to a concrete game action:
| Command | Fields | Effect |
|---|---|---|
AssignRole | name: String, role: ElfRole | Sets an elf's workshop assignment. Roles: Gatherer, Builder, Composer, Unassigned |
SetResourcePriority | Vec<ResourceType> | Reorders the settlement's gathering priority. Types: Food, Wood, Stone, FineWood |
QueueBuild | kind: BuildingType | Adds a building to the construction queue. Types: Dwelling, Garden, Workshop, FeastHall |
ClearForest | position: Position | Assigns an idle builder (or any idle elf) to clear a forest tile at the given coordinates |
ScheduleRevel | (none) | Transitions RevelState from None to Gathering with 5 ticks remaining |
Message | text: String | Adds curator commentary to the UI event log -- no gameplay effect |
Command Dispatch
Commands are applied via apply_commands(world, commands, curator). Each command:
- Mutates the
GameWorlddirectly (e.g., inserting intopolicies.workshop_assignments, pushing topolicies.build_queue). - Returns a
CulturalEventfor the UI log (e.g.,RoleAssigned,PriorityShifted,BuildQueued,ReadyForRevel,CuratorMessage).
For QueueBuild, the system first calls find_build_site to locate a suitable position:
- First choice: nearest meadow tile to the map center that is not occupied or already queued.
- Fallback: nearest
YoungForesttile, which gets cleared first (assigns an idle builder toClearForesttask). TheDummyCuratorlimits this to one clearing per consultation via itscleared_todayflag.
The search radius is (min(map_width, map_height) * 0.15).max(5.0) + 6 tiles from center.
The Curator Enum (Runtime Dispatch)
At runtime, the game holds a Curator enum that wraps either variant:
pub enum Curator {
Dummy(DummyCurator),
Llm(LlmCurator),
}
On WASM targets (browser build), LlmCurator is a thin stub that delegates to an inner DummyCurator, since the claude CLI is not available in the browser. The UI label shows "rules" for the dummy curator and the model name (e.g., "haiku") for the LLM curator.
State Snapshot Format
The curator never reads GameWorld directly for LLM consumption. Instead, SettlementState::from_world(world) produces a plain-data snapshot that the prompt layer serializes as readable text.
The snapshot includes:
| Section | Data |
|---|---|
| Header | Day, tick, season, day-in-season, year, weather, temperature |
| Resources | Name, current amount, daily rate -- for Food, Wood, Stone, FineWood |
| Elves | Name, role, task, skills (music/building/gathering), morale, satisfaction, aesthetic label, aesthetic distance from center, friend/rival names, portfolio count, aspirations, fandom, discontented/blocked flags |
| Aesthetic center | Settlement-wide average on four axes: structure, tradition, emotion, social |
| Compositions | Name, composer, genre, quality tier, mastery/originality/emotional scores, aesthetic position, properties, patron-favorite flag. Capped at 15 most recent |
| Revel state | Current phase (None / Gathering / Performing / Aftermath) plus history of last 5 revels with highlight composition and average score |
| Buildings | Count by type (Dwelling, Garden, Workshop, FeastHall) plus build queue size |
| Spirit | State label and meter value (0-100) |
| Current policies | Role assignments and resource priority order |
The prompt layer (prompt.rs) adds climate-aware alerts -- winter food warnings below 20, storm shelter alerts, discontented elf warnings, and spirit anger alerts -- before the main state sections.
Interactions
- Dummy Curator -- the rule-based fallback that handles bootstrap and steady-state decisions.
- LLM Curator -- the Claude-backed advisor with background threading and structured output.
- Needs & Mood -- morale values that appear in the state snapshot and inform curator decisions.
Tips
- The curator only runs at day boundaries by default. If your settlement is in crisis, the LLM curator reacts faster because it also triggers on critical events.
Messagecommands are free -- they have no gameplay cost. The LLM curator uses them to explain its reasoning in the event log.- The
QueueBuildcommand does not specify a location. The system automatically finds the best build site near the map center, clearing young forest if no meadow is available. - When the LLM curator's background thread dies or
claudeis not found, it permanently falls back to theDummyCuratorfor the rest of the session. - On WASM (browser), only the dummy curator is available. The LLM curator requires the native TUI build.
Dummy Curator (Rule-Based Fallback)
Overview
The DummyCurator is the settlement's rule-based cultural advisor. It runs on every platform (including WASM/browser), requires no external tools, and handles the essential decisions for a functioning settlement: role assignment, resource priorities, building construction, revel scheduling, and patron-directed composer promotion.
It also serves as the fallback for the LLM Curator -- whenever the LLM is unavailable, over budget, or between consultations, the dummy curator's logic runs instead.
How It Works
Consultation Cadence
The dummy curator runs once per game day, at day boundaries. A game day is 100 ticks (DAY_LENGTH = 100). The check is:
current_day = tick / 100
prev_day = (tick - 1) / 100
consult if current_day != prev_day
At the start of each consultation, the cleared_today flag resets to false, allowing one forest clearing per day.
Internal State
| Field | Type | Purpose |
|---|---|---|
bootstrapped | bool | Whether initial role assignment has run (once per game) |
clearings_since_garden | u32 | Forest tiles cleared since the last garden was built; triggers garden construction at 2 |
cleared_today | bool | Limits forest clearing to one per consultation (reset each day) |
Player Messages
When consult_with_message is called, the dummy curator runs its normal decision tree and appends a Message command acknowledging the input:
Understood, I'll consider your input: "..."
It does not actually modify its behavior based on the message -- that is an LLM Curator capability.
Decision Tree
Each consultation runs three phases in order: bootstrap roles, resource priority, and building queue (which also handles revel scheduling and composer promotion).
Phase 1: Bootstrap Roles
Runs once on the first consultation (bootstrapped == false). Assigns every elf a starting role based on gathering skill.
Algorithm:
- Query all elves with their
gatheringskill value. - Sort by gathering skill, descending (best gatherer first).
- Assign roles by index:
| Index | Role | Rationale |
|---|---|---|
| 0 (best gatherer) | Gatherer | Most efficient food/resource collector |
| 1-2 | Builder | Construction workforce |
| 3+ | Gatherer | Remaining elves gather resources |
With the default 8 starting elves, you get: 1 top Gatherer, 2 Builders, 5 additional Gatherers.
Phase 2: Resource Priority
Runs every consultation. Sets the settlement's gathering priority order based on food levels.
| Condition | Priority Order |
|---|---|
| Food < 20 | Food > Wood > Stone |
| Food >= 20 | Wood > Stone > Food |
The priority is always emitted, but only generates a PriorityShifted event if the new order differs from the current one.
Phase 3: Building Queue + Revel + Composer
The most complex phase. Skips entirely if the build queue already has a pending building. Otherwise, evaluates in order:
Spirit Management (Garden After Clearings)
Condition: clearings_since_garden >= 2 AND wood >= 5
Queues a Garden and resets clearings_since_garden to 0. This takes absolute priority over all other building decisions -- clearing forest angers the forest spirit, and gardens appease it.
Building Priority Order
If spirit management did not trigger, buildings are evaluated in this fixed order:
| Priority | Building | Condition | Purpose |
|---|---|---|---|
| 1 | Dwelling | dwelling_count < 3 AND wood >= 10 | Elf rest and shelter |
| 2 | Garden | garden_count == 0 AND wood >= 5 | Spirit appeasement |
| 3 | Workshop | workshop_count == 0 AND wood >= 10 AND stone >= 10 | Enables composing |
| 4 | FeastHall | feast_hall_count == 0 AND wood >= 15 AND stone >= 5 | Enables revels |
Only one building is queued per consultation. The first matching condition wins.
Revel Scheduling
Evaluated after building decisions. All five conditions must be true:
| Condition | Check |
|---|---|
| No revel active | revel_state == RevelState::None |
| Feast hall exists | At least one FeastHall building |
| Compositions exist | world.compositions is non-empty |
| Enough elves available | At least 5 elves without CreativeBlock |
| Sufficient food | Food >= 5 normally; food >= 15 in Winter |
| Cooldown elapsed | Either first revel ever (last_revel_tick == 0) or at least 400 ticks since last revel |
The winter food threshold (15 vs 5) is the dummy curator's only climate-aware rule. The 400-tick cooldown is equivalent to 4 game days.
Patron-Directed Composer Promotion
Evaluated last, only after bootstrap. When the patron's ArtisticDirection is anything other than Balanced (FavorMastery, FavorOriginality, or FavorEmotion):
- Find the elf with the highest
musicskill. - If no elf currently holds the
Composerrole, assign the best musician asComposer. - If someone is already
Composer, skip (does not re-evaluate).
This ensures non-Balanced artistic directions produce compositions aligned with the patron's taste.
Values & Formulas
Resource Thresholds
| Resource | Threshold | Effect |
|---|---|---|
| Food | < 20 | Priority shifts to Food-first |
| Wood | >= 5 | Can build Garden |
| Wood | >= 10 | Can build Dwelling or Workshop |
| Wood | >= 15 | Can build FeastHall |
| Stone | >= 5 | Can build FeastHall |
| Stone | >= 10 | Can build Workshop |
Building Material Costs (Required to Queue)
| Building | Wood | Stone |
|---|---|---|
| Dwelling | 10 | -- |
| Garden | 5 | -- |
| Workshop | 10 | 10 |
| FeastHall | 15 | 5 |
Revel Preconditions
| Parameter | Value |
|---|---|
Minimum elves (no CreativeBlock) | 5 |
| Food (non-winter) | >= 5 |
| Food (winter) | >= 15 |
| Cooldown between revels | 400 ticks (4 days) |
| Required building | FeastHall |
| Required content | At least 1 composition |
Spirit Management
| Parameter | Value |
|---|---|
| Clearings before forced garden | 2 |
| Max clearings per consultation | 1 (cleared_today flag) |
Interactions
- How the Curator Works -- the overall curator architecture and command dispatch system.
- LLM Curator -- the Claude-backed advisor that uses the dummy curator as its fallback.
- Needs & Mood -- morale and satisfaction values that the dummy curator does not directly read (it uses resource thresholds instead).
Tips
- The dummy curator builds at most 3 Dwellings, 1 Garden (via priority order), 1 Workshop, and 1 FeastHall. Additional gardens come from the spirit management rule (every 2 forest clearings).
- It never reassigns roles after bootstrap. If you want role changes with the dummy curator, you need to switch to the LLM curator or restart.
- Winter is the most dangerous season for revels. The food threshold triples from 5 to 15. Make sure your gatherers have been stocking up through autumn.
- The dummy curator ignores player messages beyond acknowledging them. For actual message-responsive behavior, use the LLM Curator.
- The
clearings_since_gardencounter persists across days and is tracked via theon_forest_clearedcallback. Both directClearForestcommands and build-site clearings increment it. - With 8 starting elves and the bootstrap allocation (6 Gatherers, 2 Builders), the settlement usually accumulates enough wood for its first Dwelling within the first 2-3 days.
LLM Curator (Claude-Backed Advisor)
Overview
The LlmCurator connects your settlement to Claude via the claude CLI, giving the curator genuine reasoning about aesthetics, social dynamics, and cultural strategy. Unlike the Dummy Curator which follows a fixed decision tree, the LLM curator reads the full settlement state -- elf personalities, aesthetic distances, compositions, revel history, climate -- and produces context-aware commands with explanatory reasoning.
It is available in the native TUI build only. On WASM (browser), LlmCurator is a thin stub that delegates to DummyCurator internally.
Setup
Prerequisites
- Install the
claudeCLI and ensure it is on yourPATH. The curator spawns it as a subprocess. - The default model is
haiku(fast, cheap). The model name is stored inself.modeland displayed in the UI as the curator label.
Verifying
Launch the native TUI build with cargo run. If claude is found, the curator label in the UI will show "haiku" instead of "rules". If spawning fails, the curator logs a warning and permanently falls back to the dummy curator for the rest of the session.
Platform Behavior
| Target | Behavior |
|---|---|
Native (cargo run) | Full LLM curator with background thread |
WASM (wasm32-unknown-unknown) | Stub that wraps DummyCurator; label shows "rules" |
How It Works
Background Thread Architecture
The LLM curator is non-blocking. It uses a dedicated background thread to call claude so the game loop never stalls waiting for a response.
Game tick
|
v
should_consult() -- check for pending result or day boundary / event trigger
|
v
consult() -- if pending result ready, return it
-- otherwise, build request, send to background thread
-- return DummyCurator fallback commands for this tick
|
v
[Background thread]
|-- Receives ConsultRequest via mpsc channel
|-- Spawns `claude -p` subprocess
|-- Pipes state message via stdin
|-- Parses JSON envelope from stdout
|-- Stores ConsultResult in Arc<Mutex<Option<...>>>
|
v
Next consult() call picks up the result
Key properties:
- The background thread lives for the entire game session (spawned once in the constructor).
- Only one request can be in flight at a time (the channel is unbounded, but the thread processes sequentially).
- While waiting for the LLM, the dummy curator's logic runs as fallback, so the settlement is never unmanaged.
- If the background thread panics or the channel closes,
permanently_fallbackis set totrue.
Budget and Rate Limiting
The LLM curator enforces two limits to control API costs:
| Parameter | Value | Description |
|---|---|---|
max_per_day | 5 | Maximum LLM consultations per game day |
min_consult_gap | 50 ticks | Minimum ticks between sending new requests (half a day) |
The daily budget resets when tick / DAY_LENGTH changes. When the budget is exhausted or the gap has not elapsed, the curator returns dummy fallback commands.
When It Consults
The LLM curator has a richer trigger set than the dummy curator:
| Trigger | Condition |
|---|---|
| Day boundary | tick / 100 changes (same as dummy) |
| Pending result | Background thread has a result ready -- always process immediately |
| Revel ended | RevelEnded event |
| Art completed | ArtCompleted event |
| Inspiration crisis | InspirationCrisis event |
| Resource critical | ResourceLow event with amount < 5 |
| Spirit anger | SpiritStateChanged event where new state is "Anger" |
Player Messages
When called with consult_with_message, the LLM curator:
- Checks for a pending background result first (returns it if available).
- Appends the player's message to the system prompt as a "Patron's Direct Message" section.
- Sends the request to the background thread.
- Returns
Message("Considering your request...")as an immediate acknowledgment.
The LLM sees the player's exact words and is instructed to "respond to this directive in your reasoning and adjust your decisions accordingly."
Structured Output with --json-schema
The curator uses Claude's structured output mode to guarantee parseable responses.
CLI Invocation
claude -p \
--model haiku \
--output-format json \
--json-schema <schema> \
--system-prompt <system_prompt> \
--tools ""
< state_message
The --tools "" flag disables all tools, forcing pure structured output. The state message is piped via stdin.
Response Envelope
Claude returns a JSON envelope:
{
"type": "result",
"subtype": "success",
"result": "",
"structured_output": { ... },
"total_cost_usd": 0.01
}
The curator reads structured_output first (primary path). If absent, it falls back to parsing result as a JSON string (older format compatibility).
Tool Schema Reference
The schema defines a CuratorResponse object with commands (array) and reasoning (string). Each command is tagged by its action field.
CuratorResponse
{
"commands": [ ... ],
"reasoning": "string"
}
Command Variants
| Action | Fields | Valid Values |
|---|---|---|
assign_role | name, role | role: "Gatherer", "Builder", "Composer", "Unassigned" |
set_resource_priority | priority (array) | "Food", "Wood", "Stone", "FineWood" |
queue_build | kind | "Dwelling", "Garden", "Workshop", "FeastHall" |
clear_forest | x, y (integers) | Map coordinates |
schedule_revel | (none) | |
message | text | Free-form string |
Unknown values (e.g., a role of "Knight") are silently skipped with a log warning. The parse_commands function filters invalid entries rather than rejecting the entire response.
Example LLM Response
{
"commands": [
{"action": "assign_role", "name": "Elowen", "role": "Composer"},
{"action": "set_resource_priority", "priority": ["Food", "Wood"]},
{"action": "message", "text": "Assigning Elowen as Composer -- she has the highest music skill and her emotional style aligns with our patron's taste."}
],
"reasoning": "Best musician gets Composer role."
}
The reasoning field is appended as an additional Message command when non-empty, so it appears in the event log.
The System Prompt
The system prompt establishes the curator's personality as "part colony manager, part artistic director." Key sections:
| Section | Content |
|---|---|
| Aesthetic Axes | Explains the four-axis model (structure, tradition, emotion, social) and how aesthetic distance drives departure |
| Patron's Direction | Inserts the current ArtisticDirection value (Balanced / FavorMastery / FavorOriginality / FavorEmotion) |
| Tools | Documents each command with usage guidance |
| Critical Awareness | Lists situations to watch: discontented elves, aesthetic outliers, creative blocks, spirit anger, food crises, missing compositions, stale revels |
| Style | "Be brief but specific. Name the elves you're acting on and explain why." |
Climate-Aware Context
The state message sent to the LLM includes full climate data:
- Season name, day within season, year
- Current weather and temperature
- Climate-specific alerts (e.g., "Winter food stores running low" when food < 20 in winter, "Settlement sheltering from storm" during storms)
This allows the LLM to make season-appropriate decisions that the dummy curator's fixed rules cannot.
State Snapshot Contents
The LLM receives a text-serialized SettlementState with:
- Resources: current amounts and daily production rates
- Elf roster: skills, morale, satisfaction, aesthetic label and distance, social graph (top 5 friends/rivals by name), portfolio size, aspirations, fandom, status flags (DISCONTENTED, BLOCKED)
- Compositions: last 15 with full quality breakdown, aesthetic position, properties, patron-favorite flag
- Revel history: last 5 with highlight composition, attendee/performance counts, average scores
- Buildings: counts by type, queue size
- Spirit: state label and meter (0-100)
- Current policies: all role assignments and resource priority order
- Patron context: favorite compositions, interesting elves
Compositions are capped at 15 and revel history at 5 to control token usage.
Interactions
- How the Curator Works -- the overall curator architecture, command dispatch, and
CulturalAdvisortrait. - Dummy Curator -- the rule-based fallback that runs when the LLM is unavailable or over budget.
- Needs & Mood -- morale and satisfaction values visible in the state snapshot.
Tips
Effective Prompting (Player Messages)
The patron message is injected verbatim into the system prompt. To get good results:
- Be specific about elves by name: "Focus on Elowen's development as a composer" works better than "make better music."
- Reference the aesthetic axes: "I want a more avant-garde settlement" tells the LLM to favor low-tradition elves.
- Ask for explanations: The LLM always emits a
reasoningfield, but a pointed question like "Why is Theron discontented?" produces richer analysis. - Give artistic direction: "Schedule a revel featuring emotional compositions" guides the LLM's revel timing and implicitly its composer promotion decisions.
Cost Management
- The default model is
haiku-- fast and inexpensive. - At 5 consultations per game day, a typical session costs fractions of a cent.
- The
min_consult_gapof 50 ticks prevents rapid-fire requests even when many events trigger in quick succession. - Token costs are tracked in
total_input_tokensandtotal_output_tokenson the curator struct (not yet surfaced in the UI).
Fallback Behavior
- When the LLM request is in flight, the dummy curator runs. This means the first day's decisions are always rule-based (bootstrap roles, initial priority).
- If
claudeis not on your PATH, the curator permanently switches to dummy mode after the first failed spawn. Check your terminal for the warning: "LLM curator: failed to spawn claude." - LLM results that contain only unknown commands (all filtered out) are treated as empty and trigger a fallback cycle.
Seasonal Planning
The 100-day year creates a rhythm of abundance and scarcity. Planning around seasons is the foundation of colony management.
The Yearly Cycle
| Season | Days | Foraging | Regen | Character |
|---|---|---|---|---|
| Spring (Awakening) | 0-24 | ×1.0 | +2/dawn | Renewal. Spirit heals fastest. |
| Summer (Radiance) | 25-49 | ×1.5 | +1/dawn | Abundance. Best foraging season. |
| Autumn (Fading) | 50-74 | ×1.25 | +1/dawn | Good foraging still. Peak beauty terrain. |
| Winter (Stillness) | 75-99 | ×0.5 | Skip odd days | Scarcity. Spirit dormant. Survival mode. |
(Source: src/sim/climate.rs)
Winter Preparation Checklist
Winter is the most dangerous season. Prepare during Summer and Autumn:
- Food stockpile ≥ 15 — the Dummy Curator won't schedule revels in Winter unless food is above 15 (vs. 5 normally)
- At least 1 Dwelling — shelter from storms and cold. Elves without shelter get "Chilled" (-2 mood) when temperature drops below 25
- Garden(s) built — the forest spirit doesn't heal naturally in Winter. Gardens are the only calming mechanism (-2 per garden per dawn)
- 2+ Gatherers assigned — winter foraging yields only 60% of normal (30% with snow). You need more hands gathering
Spring Opportunities
Spring is the most generous season:
- Resource regen doubled (+2 per source per dawn vs. +1)
- Spirit heals twice as fast (-2 natural dawn decay vs. -1)
- Foraging ×1.0 — baseline rate (Summer at ×1.5 is actually the best foraging season)
- But: clearing forest in Spring angers the spirit more (+7 vs. +5 normally)
Strategy: clear forest in Summer/Autumn when the spirit penalty is lower (+5 vs. +7 in Spring). Summer's ×1.5 foraging is the best stockpiling window. Use Spring's natural healing to recover from any anger accumulated over Winter.
Seasonal Composition Effects
Seasons subtly influence genre selection:
| Season | Genre Tendency |
|---|---|
| Spring | Leans Traditional |
| Summer | Favors Radical |
| Autumn | Most varied |
| Winter | Favors Pastoral |
If you're pursuing a specific cultural direction via Artistic Direction, plan your composition pushes around favorable seasons.
Weather Awareness
Weather has 70% momentum — it tends to persist for a few days. Plan around multi-day patterns:
- Rain: outdoor elves get "Caught in rain" (-1 mood). Shelter helps.
- Storm: elves shelter indoors. Good for composers in Workshops, bad for Gatherers.
- Snow: foraging halved again (stacks with Winter penalty). But "Snow-covered landscape" gives +2 beauty mood.
- Fog: creative elves (Music > 5) get "Mysterious fog" (+1 mood, +1 nature inspiration). A hidden bonus for composers.
Interactions
- Seasons & Weather — full weather mechanics
- Resources — foraging yield formulas
- Forest Spirit — seasonal anger and calming
- Revels — revel scheduling constraints
Spirit Management
The forest spirit tracks ecological balance. Keeping it in Harmony (0-20) is essential — higher states bring terrain effects and reduced yields.
The Anger Budget
Every forest clearing adds anger. Every dawn removes some. Your goal is to keep the net change negative.
Anger Sources
| Action | Anger Added | Notes |
|---|---|---|
| Clear Young Forest | +5 | Standard penalty |
| Clear Ancient Forest | +5 | Same penalty, but you lose more beauty |
| Clear any forest in Spring | +7 | Spring penalty is higher (forest is awakening) |
Calming Sources
| Source | Anger Removed | When |
|---|---|---|
| Natural dawn decay | -1 | Every dawn (except Winter) |
| Natural dawn decay (Spring) | -2 | Spring doubles natural healing |
| Garden | -2 per garden | Every dawn, all seasons including Winter |
Safe Harvesting Rates
With 0 Gardens:
- Non-Spring: clear 1 forest per day → net change = +5 - 1 = +4/day. Spirit enters Tension in 5 days.
- Not sustainable. Build a garden first.
With 1 Garden:
- Non-Spring: +5 - 1 - 2 = +2/day. Slow accumulation — budget ~10 clearings before hitting Tension.
- Spring: +7 - 2 - 2 = +3/day. Faster accumulation due to higher penalty.
With 2 Gardens:
- Non-Spring: +5 - 1 - 4 = 0/day. Break-even. You can clear 1 forest per day indefinitely.
- Spring: +7 - 2 - 4 = +1/day. Slight net positive — still need to pace.
With 3 Gardens:
- Non-Spring: +5 - 1 - 6 = -2/day. Net healing. Clear freely.
- Spring: +7 - 2 - 6 = -1/day. Still net healing.
The Winter Problem
The spirit doesn't heal naturally in Winter. No dawn decay occurs. But Gardens still work.
- With 0 Gardens in Winter: any anger accumulated persists until Spring.
- With 2 Gardens in Winter: -4/dawn. Spirit heals through gardens alone.
Key insight: build gardens before Winter. They're your only defense against persistent anger.
Recovery Timelines
If the spirit reaches Anger (76+) and you stop clearing:
| Gardens | Days to Harmony (from 76) | Season Assumed |
|---|---|---|
| 0 | 56 days | Non-Winter |
| 1 | 26 days | Non-Winter |
| 2 | 15 days | Non-Winter |
| 3 | 10 days | Non-Winter |
| 0 | Never (in Winter) | Winter |
| 2 | 19 days | Winter |
State Consequences
| State | Meter | Effect |
|---|---|---|
| Harmony | 0-20 | No effects. All is well. |
| Tension | 21-50 | Warning events in the event log. |
| Displeasure | 51-75 | Terrain effects, reduced resource yields. |
| Anger | 76+ | Active interference with the settlement. |
Interactions
- Forest Spirit — full mechanics reference
- Buildings — Garden cost (5 Wood) and placement
- Seasonal Planning — Spring vs. Winter clearing strategy
- Resources — wood sources and alternatives
Revel Optimization
Revels are the primary mechanism for boosting Beauty and Stimulation needs, generating mood modifiers, and creating shared cultural experiences. Optimizing them means better morale and longer elf retention.
When to Schedule Revels
The Dummy Curator schedules revels automatically based on:
- Food availability: needs ≥ 5 (or ≥ 15 in Winter)
- Cooldown: a minimum time between revels
- Feast Hall: having a Feast Hall improves revel quality
Player tip: if you're using the LLM Curator, you can request revels via chat. The curator considers settlement state before scheduling.
Timing Considerations
- Avoid scheduling during storms — elves shelter indoors and may not gather at the revel location
- Autumn revels benefit from peak beauty terrain — Ancient Forest gains +1 beauty in Autumn
- Winter revels are expensive — food threshold is 3× normal (15 vs. 5), but they're the best morale tool during the hardest season
- Spring revels pair well with high inspiration — the renewal season often coincides with creative output spikes
Performer Selection
The compositions performed at a revel determine audience satisfaction. Key factors:
- Quality matters: higher mastery, originality, and emotional scores create better experiences
- Aesthetic alignment: audience members enjoy compositions that match their aesthetic position. A Traditional composition played to innovation-leaning elves won't land well.
- Variety: a diverse composition portfolio creates broader appeal
Strategy: encourage a mix of genre families (Traditional, Radical, Pastoral) so revels have something for everyone. Use Artistic Direction set to "Balanced" for maximum variety, or target specific genres to match your colony's dominant aesthetic.
Maximizing Satisfaction
Revel satisfaction feeds into the Satisfaction system. High-satisfaction revels:
- Generate positive mood modifiers for attendees
- Satisfy Beauty and Stimulation needs
- Can rescue discontented elves through satisfaction spikes
The satisfaction spike mechanic: when an elf attends a great revel, the satisfaction boost is buffered to survive the 10-tick recompute cycle. This means a well-timed revel can save an elf approaching the departure threshold.
Saving Discontented Elves
If you see the discontented indicator on an elf:
- Check their needs — address the most critical deficit
- Schedule a revel — the satisfaction spike can buy time
- Assign them near friends — the Company need matters
- You have 500 ticks after the warning before departure
Interactions
- Revels — full lifecycle mechanics
- Compositions — quality formula and genre system
- Satisfaction & Departure — how revel satisfaction affects retention
- Seasonal Planning — seasonal timing for revels
Role Allocation
Choosing the right role for each elf is a balancing act between resource production, artistic output, and construction progress.
The Four Roles
| Role | Primary Output | Skill Used |
|---|---|---|
| Gatherer | Wood, Stone, Food, FineWood | Gathering |
| Builder | Building construction progress | Building |
| Composer | Musical compositions | Music |
| Unassigned | Idle — forages, socializes, rests | None specific |
See Roles for detailed per-role behavior and task selection logic.
Allocation Strategies
Early Game (First 50 Days)
With 5-8 elves, a good starting split:
- 2-3 Gatherers — food security and building materials
- 1 Builder — start the build queue (Dwelling → Workshop → Garden)
- 1-2 Composers — begin cultural output, gain Music XP
- 1-2 Unassigned — flexible labor, passive foraging
Why not all Gatherers? Resources accumulate faster, but you miss early composition XP. Music skill levels matter for quality — starting one tick sooner compounds.
Mid Game (Days 50-75, Autumn)
Shift toward stockpiling for Winter:
- 3+ Gatherers — build food reserves above 15 (Winter revel threshold)
- 1 Builder — finish remaining structures
- 2+ Composers — established skill levels produce better compositions for revels
Winter (Days 75-99)
Foraging yields drop to 50% (25% with snow). Adjust:
- Keep at least 2 Gatherers — maintaining food supply is critical
- More Composers — indoor work, unaffected by weather (if Workshop exists)
- Builder if queue remains — indoor construction if buildings are pending
Late Game
Once buildings are complete and resources are stable:
- 1-2 Gatherers — maintenance level
- 0 Builders — reassign once queue is empty
- Majority Composers — the art system is the endgame
Skill-Based Assignment
The Dummy Curator's bootstrap_roles() assigns roles based on each elf's highest skill:
- Highest Music skill → Composer
- Highest Building skill → Builder
- Highest Gathering skill → Gatherer
- Ties → falls through to Gatherer (most useful default)
Should you follow it? Usually yes. An elf with high Music skill produces better compositions faster. But consider:
- An elf with Music 1 and Gathering 8 generates way more resources as a Gatherer
- XP formula is linear (level × 50 per level), so low-skill elves catch up eventually
- Aesthetic position affects composition genre — an elf with extreme aesthetic values produces more distinctive work
Specialization vs. Generalization
Specialization (few role changes):
- Pros: faster skill growth, higher quality output
- Cons: fragile if an elf departs, resource bottlenecks
Generalization (frequent role changes):
- Pros: flexible, resilient to departures
- Cons: slower XP growth, lower quality output
Recommendation: specialize your best elves (highest skills) and keep 1-2 generalists as flexible labor. The XP curve is linear — every tick of role time matters.
Interactions
- Roles — detailed role behavior
- Skills — XP formula and level effects
- Satisfaction & Departure — departing high-skill elves hurt most
- Seasonal Planning — seasonal role adjustments