62 lines
2.6 KiB
Markdown
62 lines
2.6 KiB
Markdown
# Event reasons (camera + orange dossier)
|
||
|
||
## Contract
|
||
|
||
Registered **events** own the idle camera.
|
||
`EventStrength` / `TotalScore` ranks who wins.
|
||
Character fill runs only when the pending **EventLed** queue is empty, and uses an empty Label (task chip only).
|
||
|
||
Orange dossier reason = the owning event’s `Label` while the scene is active (`InterestDirector.TryGetOwnedReasonCandidate`).
|
||
Quiet grace / inactive dwell clears the reason even if focus has not switched yet.
|
||
|
||
## EventReason
|
||
|
||
[`IdleSpectator/Events/EventReason.cs`](../IdleSpectator/Events/EventReason.cs) is the sole Label factory for camera candidates.
|
||
It lives in the Events module with catalogs (not in the director).
|
||
Feeds call typed helpers (`Fight`, `BuildingEat`, `SeekingLover`, …) or `Apply(template, a, b, id)`.
|
||
|
||
## Events module layout
|
||
|
||
| Path | Role |
|
||
|------|------|
|
||
| `Events/EventCatalog.cs` (+ `Catalogs/EventCatalog.*.cs`) | **One inventory** - nested domains (`Status`, `Combat`, …) |
|
||
| `Events/Feeds/` | Build + register candidates from catalog dials |
|
||
| `Events/Patches/` | Harmony hooks → feeds |
|
||
| `Events/EventReason.cs` | Orange reason sentences |
|
||
| `Events/EventFeedUtil.cs` | Shared Register path |
|
||
| `Events/DiscreteEventEntry.cs` | Shared catalog row shape |
|
||
|
||
`InterestDirector` only ranks registered candidates for the camera - it does not author event inventory.
|
||
|
||
Rules:
|
||
|
||
- Sentence form with names: `{a} is fighting {b}`, `{a} is eating a beehive`, `{a} is seeking a lover`.
|
||
- Set `RelatedUnit` when the sentence names a second party.
|
||
- Never invent stranger subjects for unit-led events.
|
||
- Never use engine jargon that misstates the action (`Consumes a building` → eating/foraging via `BehConsumeTargetBuilding`).
|
||
|
||
## Removed crumbs
|
||
|
||
Do not author these as orange reasons:
|
||
|
||
- `In action`
|
||
- bare `Duel` / `Fight (N)` without a named sentence
|
||
- identity titles (`King of X`, `Leader of X`, `Lone beetle`)
|
||
- `Consumes a building` / `Damages a building: {a}` crumb form
|
||
|
||
## Strength dial (no ownership enum)
|
||
|
||
`InterestOwnership` / `OwnsCamera` were removed.
|
||
Every registration is EventLed and may own the camera.
|
||
`CreatesInterest` gates whether an id registers; `EventStrength` ranks.
|
||
Instant cut-in when `next.TotalScore >= current + cutInMargin` (see `scoring-model.json`).
|
||
|
||
## Dossier display
|
||
|
||
`UnitDossier.EventLabelBeat` keeps the authored sentence.
|
||
It only rejects identity/weak crumbs and scrubs living stranger names (`ReasonNamesStranger` / `LeadsWithForeignName`).
|
||
|
||
## See also
|
||
|
||
- [`event-audit.md`](event-audit.md) - full source inventory, MaxWatch classes, drowning policy
|
||
- [`scoring-model.md`](scoring-model.md) - score weights
|