132 lines
7.6 KiB
Markdown
132 lines
7.6 KiB
Markdown
# Event prose audit (vs game call sites)
|
||
|
||
Authored IdleSpectator sentences must match what the game actually does when an id fires.
|
||
Source of truth: `Assembly-CSharp` apply sites (`changeHappiness`, relationship patches, status receive), not English guesses from the id string.
|
||
|
||
Audit date: 2026-07-16.
|
||
Scope: Happiness (all authored), Relationship (all), Status/WorldLog/Plot/etc. sampled.
|
||
|
||
## Fixed this pass
|
||
|
||
| Id | Was | Actual | Now |
|
||
|----|-----|--------|-----|
|
||
| `just_born` | "is born into the world" / "first breath" | `Actor.newCreature` spawn; may precede egg form | "appears in the world" / "is brought into existence"; strength 48; no hatch strength floor |
|
||
| `just_kissed` | "shares a kiss" | Mating afterglow (`BehCheckForBabiesFromSexualReproduction`) | "mates with …" / "shares intimacy …" |
|
||
| `just_killed` | "takes a life" | Only with trait `bloodlust` | Explicit bloodlust wording |
|
||
| `add_child` / `EventReason.NewChild` | "{a} and {b} have a new child" | `{b}` is the child | "{a} gains a child, {b}" |
|
||
| `baby_created` / `EventReason.BabyBorn` | "{a} welcomes a baby" | `{a}` is the baby | "{a} is created as a baby" |
|
||
| `just_had_child` | Named newborn `{related}` | Related newborn not wired | "has a child" / parenthood only |
|
||
| `just_started_war` | Anyone cheers war | Culture trait `happiness_from_war` | "is glad war has started" / culture-loves-war |
|
||
| `just_talked` | Always warm | Talk can be good or bad | Neutral "finishes talking" |
|
||
| `just_inspired` | Onset of inspiration | Status `inspired` **end** | "comes down from inspiration" |
|
||
| `slept_outside` | Rough night over | Sleep start, no house | "has to sleep without a house" |
|
||
| `just_rebelled` | Joins / rises | Whole city units swept | "is swept up as the city rebels" |
|
||
| `just_forced_power` | Vague forced power | God force shove | "is flung by a god power" |
|
||
| `got_caught` | Shady catch Signal | No game caller found | Ambient, weak strength |
|
||
| `lost_fight` | Decisive loss | Yield / submit mid-fight | "is forced to yield" |
|
||
| `just_talked_gossip` | Generic juicy gossip | `gossip_lovers` culture | Lover-gossip wording |
|
||
| `become_king` | "crowned king" | Any sex ruler | "takes the crown" / "becomes ruler" |
|
||
| `become_alpha` | Fight for alpha | Oldest living family unit | "becomes the family alpha" |
|
||
| Dreams | "wakes from …" | Dream status on receive | "has a … dream" |
|
||
|
||
## Policy notes
|
||
|
||
- Hatch camera floor (`Max(strength, 88)`) applies only to `just_got_out_of_egg` / `just_hatched`, not `just_born`.
|
||
- True hatch prose (`just_got_out_of_egg` → "hatches from an egg") matches `Actor.eventHatchFromEgg`.
|
||
- Live parent beat is `just_had_child`, not `just_born`.
|
||
|
||
## Still clean (sample)
|
||
|
||
Grief deaths, `fallen_in_love`, gifts, house find/lose, `just_got_out_of_egg`, `just_became_adult`, WorldLog `king_new` template roles, Status `egg` / `drowning` prose.
|
||
|
||
## A/B camera policy (2026-07-16)
|
||
|
||
Interesting = interest candidate. Director ranks by strength.
|
||
|
||
Happiness Ambient only for true FX: poke, caught stub, tax, ate, pooped.
|
||
Status CreatesInterest false only for brief FX/cooldowns + egg gain.
|
||
|
||
Gate helper: `EventCatalog.IsCameraWorthy`. Drops: `InterestDropLog`.
|
||
|
||
## Hatch camera path (fixed)
|
||
|
||
Hatch was Activity-only for many units:
|
||
- Status `egg` has `CreatesInterest=false` (becoming an egg is not a camera beat).
|
||
- `OnStatusChange` previously ignored **losses**, so "Hatches from an egg" never became interest.
|
||
- Happiness `just_got_out_of_egg` is often suppressed (`!hasEmotions()`).
|
||
- Even when a hatch Label existed, dossier identity filter dropped verbs without ` is ` (e.g. "Name hatches …").
|
||
|
||
Fix:
|
||
- Egg status **loss** → `InterestFeeds.EmitHatch` + `EventReason.Hatch`, key `hatch:{id}` shared with happiness.
|
||
- Keep `Name verb …` EventReason sentences in `UnitDossier.OwnedEventReason`.
|
||
|
||
## Reasons
|
||
|
||
EventLed camera candidates always get a `Label` (orange reason) when ownership + sentence filters pass.
|
||
Sources: `EventReason.*`, happiness catalog `PlainClause`, or discrete catalog templates.
|
||
Character fill / ambient may show empty reason.
|
||
Not every Activity line is a camera event (Ambient happiness, status gains with `CreatesInterest=false`, status losses except egg).
|
||
|
||
## Happiness trigger pass (2026-07-16)
|
||
|
||
Full 67-id call-site audit vs decompile + BehaviourTask / StatusLibrary / City civic force.
|
||
|
||
| Id | Finding | Keep-on fix |
|
||
|----|---------|-------------|
|
||
| `just_laughed` / `just_swore` | Fire at **end** of emotion tasks | Prose → finishes laughing / swearing |
|
||
| `just_ate` | Fires on `consumeFoodResource` | Prose → eats / enjoys a meal |
|
||
| `just_felt_the_divine` | Divine light clears bad traits | Prose → cleansed by divine light |
|
||
| `just_played` | Child play task end | Prose → finishes playing around |
|
||
| `got_caught` | Library asset, **no caller** | Stay Ambient; honest prose |
|
||
| `got_robbed` / gifts / kiss / talk / kill | Related optional but bag missing | Context bags on steal/gift/kiss/talk/kill |
|
||
| `fallen_in_love` | Status `fell_in_love` receive + bridge | Keep bridge for no-emotions |
|
||
| Civic aggregates / BehAddHappiness | Live via forceUnits / Beh* | Marked accurate |
|
||
|
||
Worksheet: `docs/event-trigger-audit.tsv` (happiness domain done).
|
||
|
||
## Status trigger pass (2026-07-16)
|
||
|
||
Full 58-id audit vs `StatusLibrary` + apply sites. Universal Activity hook:
|
||
`ActorStatusPatches` → `addNewStatusEffect` / `Status.finish` (egg loss also `InterestFeeds.EmitHatch`).
|
||
|
||
| Id | Finding | Keep-on fix |
|
||
|----|---------|-------------|
|
||
| `angry` | `addAggro`, not the `rage` combat buff | Prose → flies into a fury |
|
||
| `possessed_follower` | Possession talk converts **target** | Prose → converted into possessed follower |
|
||
| `pregnant` / `pregnant_parthenogenesis` | Finish → `BabyMaker` birth | Loss prose → gives birth (/ alone) |
|
||
| `taking_roots` | Finish → vegetative offspring | Loss prose → sprouts offspring |
|
||
| `budding` | Finish → bud offspring | Loss prose → splits off a bud offspring |
|
||
| `uprooting` | Plant babies emerging | Prose → emerges as a young plant |
|
||
| Dreams / `inspired` / combat FX | Sleep pot, finish→happiness, CombatActionLibrary | Already accurate |
|
||
|
||
Worksheet: `docs/event-trigger-audit.tsv` (status domain done).
|
||
|
||
## WorldLog / plot / trait pass (2026-07-16)
|
||
|
||
Phases 4–7 worksheet complete (all audit rows `done`).
|
||
|
||
| Area | Finding | Keep-on fix |
|
||
|------|---------|-------------|
|
||
| WorldLog `{a}`/`{b}` | `special1`/`special2` match game replacers (kingdom/king, war kingdoms) | Accurate |
|
||
| Disasters | Policy rows; camera via paired `disaster_*` WorldLog | Accurate (no DisasterManager patch) |
|
||
| Wars / eras | `WarManager` + `WarInterestFeed`; `WorldAgeManager.startNextAge` | Accurate |
|
||
| Plots | Same label for new/complete/cancel | `EventReason.Plot` phase rewrite |
|
||
| Traits | JSON said `Trait: {id} ({a})`; live was `gains`/`loses` | Catalog labels → `{a} gains {id}` |
|
||
| Boat/meta harness | Crumb strings ≠ `EventReason` | Harness uses `EventReason.Boat` / `MetaNew` |
|
||
| Building / combat | Already `EventReason.BuildingEat` / `Fight` | Accurate |
|
||
|
||
Worksheet: `docs/event-trigger-audit.tsv` (all domains done).
|
||
|
||
## Family pack join false positive (2026-07-16)
|
||
|
||
`BehFamilyGroupJoin` returns `Continue` even when `getNearbyFamily` is null (no `setFamily`).
|
||
IdleSpectator used to Emit on any Continue → orange “joins a family pack” with no Family meta.
|
||
Gate: Emit only when `hasFamily()` after execute.
|
||
|
||
## Observe → confirm → emit (2026-07-16)
|
||
|
||
Shared pipeline: `EventOutcome` predicates + `EventObservation.Confirm*` before feeds.
|
||
Relationship Beh hooks (find_lover, family group new/join/leave) migrated first.
|
||
Rule: never treat `BehResult.Continue` as semantic success.
|
||
Docs: `docs/event-observation.md`.
|
||
|