140 lines
6.6 KiB
Markdown
140 lines
6.6 KiB
Markdown
# Feature slice: authored content and presentation data
|
|
|
|
This slice is the no-code extension boundary for content that reuses existing
|
|
behavior. It is implemented by `SimulationContentPack`, `ContentCatalog`, the
|
|
typed definition resources under `simulation/definitions/`, and the separate
|
|
`PresentationCatalog` under `world/presentation/`.
|
|
|
|
## The four layers
|
|
|
|
| Layer | Lives in | Contains | Never contains |
|
|
| --- | --- | --- | --- |
|
|
| Definition | `.tres` resources and typed `Resource` classes | immutable IDs, balance, capabilities, effects, handlers, cue IDs | mutable amount, owner, reservation, node references |
|
|
| Instance descriptor | placement/provider nodes and regional records | stable runtime ID, context/location, authored overrides | script/callable/`NodePath` authority |
|
|
| State record | `simulation/state/` | primitive mutable values, IDs, history/event references | scene assets or resource paths |
|
|
| Presentation binding | `world/presentation/` and scene providers | cue-to-scene/material/icon/animation metadata | simulation quantities or quest authority |
|
|
|
|
Definitions are current-build balance. A save stores the definition ID and
|
|
mutable instance state; it does not freeze the `.tres` path or copy the full
|
|
resource. Renaming an ID requires an alias/migration, not a silent replacement.
|
|
|
|
## Content packs and catalog publication
|
|
|
|
`SimulationContentPack` groups typed arrays for:
|
|
|
|
- actions, professions, capability tags;
|
|
- items, resources, storages;
|
|
- enemies and animals;
|
|
- situations, dialogue intents, and template catalogs;
|
|
- event types and social consequences;
|
|
- required pack IDs and required handler IDs.
|
|
|
|
`ContentCatalog.create_core()` loads `simulation/definitions/packs/core.tres`.
|
|
`ContentCatalog.rebuild()` sorts packs and every definition by stable ID,
|
|
collects references into temporary dictionaries, validates the complete graph,
|
|
and publishes only if there are no errors. A failed rebuild clears the
|
|
published catalog; it never exposes a partially valid pack.
|
|
|
|
Validation currently rejects duplicate IDs, unknown references, missing
|
|
handlers, unsupported situation predicates, missing presentation cues, invalid
|
|
categories, invalid event/consequence references, duplicate template keys, and
|
|
malformed typed action contracts. `get_authoring_report()` is the deterministic
|
|
machine-readable inventory used by tests and tooling.
|
|
|
|
The first built-in handler contract is `activity_metric_delta`. It requires an
|
|
activity target, exactly one positive safety/knowledge metric effect, typed
|
|
optional `player_multiplier`/`npc_productivity` values, a known completion
|
|
event, and a routable completion-cost item. This closes the gap where an
|
|
authored action could publish but produce a fact that the validator could not
|
|
restore.
|
|
|
|
## Adding data-only content
|
|
|
|
### New item and route
|
|
|
|
1. Add an `ItemDefinition` with a category and stable `item_id`.
|
|
2. Add a `StorageDefinition` that accepts the item ID or one of its tags, or
|
|
update an existing typed storage route.
|
|
3. Add both to a pack and make sure the `StorageRoutingPolicy` can rank a
|
|
compatible storage.
|
|
4. Add a `PresentationCueDefinition` only if the item needs a visual.
|
|
5. Add a conservation/routing test. The herb/apothecary route is the reference
|
|
example; food/pantry and wood/woodpile preserve legacy coverage.
|
|
|
|
### New resource
|
|
|
|
1. Add a `ResourceDefinition` with yielded item, gather action, capacity/yield,
|
|
regrowth, access policy, capability tags, and a cue ID.
|
|
2. Place a `ResourceNode` with a unique contextual ID and meaningful
|
|
`safety_risk`, `comfort_distance`, `discovery_priority`, and interaction
|
|
point.
|
|
3. Register it through the nearest `ActiveWorldAdapter`; do not add a global
|
|
array or manager branch.
|
|
4. Test player/NPC selection, depletion, reservation, unload/rebind, and
|
|
save/restore authority.
|
|
|
|
### New animal
|
|
|
|
1. Add an `AnimalDefinition` with behavior/routine/feed capability IDs and a
|
|
stable presentation cue.
|
|
2. Add it to `core_animals.tres` or an explicit content pack.
|
|
3. Spawn through `AnimalFactory` and persist its `animal_definition_id` in
|
|
`AnimalStateRecord`.
|
|
4. Reuse `AnimalNode`, `AnimalRoutineSite`, and the grazer visual where the
|
|
existing contract fits. The goat/sheep pair proves this path.
|
|
|
|
### New enemy
|
|
|
|
1. Add an `EnemyDefinition` with `behavior_profile_id`, faction, item/weapon
|
|
references, hostile flag, and cue ID.
|
|
2. Register it in a pack. `CombatantFactory` owns deterministic per-prefix ID
|
|
allocation and restore collision checks.
|
|
3. Spawn through `ConflictSystem.spawn_enemy()`; keep `spawn_wolf()` only as a
|
|
compatibility wrapper.
|
|
4. Reuse a behavior profile when possible. `enemy_boar` deliberately reuses
|
|
`wolf_hunt`; no combat switch was added.
|
|
|
|
### New situation or dialogue content
|
|
|
|
See [Events through dialogue](FEATURE_EVENTS_KNOWLEDGE_SITUATIONS_DIALOGUE.md).
|
|
The authored resources must reference existing predicate IDs, event types,
|
|
intent IDs, template catalogs, and action/item definitions. A definition may
|
|
describe an unresolved condition, but it cannot create substitute world facts.
|
|
|
|
## Presentation catalogs
|
|
|
|
`PresentationCatalog` accepts `PresentationCatalogResource` entries whose
|
|
`PresentationCueDefinition` contains stable cue metadata and optional asset
|
|
paths. It validates metadata headlessly and loads scenes only at the world
|
|
boundary. `AnimalDefinition`, enemy definitions, resource definitions, and
|
|
other simulation content carry only a cue ID. This keeps headless tests and
|
|
saves independent of imported meshes/materials.
|
|
|
|
Presentation catalogs may be absent in a headless `AnimalFactory` or regional
|
|
simulation. Missing optional presentation is an explicit no-visual result, not
|
|
a reason to fail simulation state loading.
|
|
|
|
## What requires code
|
|
|
|
Data-only authoring is guaranteed only when the new combination uses existing
|
|
typed predicates, capabilities, effects, handlers, behavior profiles, and cue
|
|
contracts. Add one reusable typed handler when a new mechanic needs a new
|
|
authority rule. The handler must provide validation, a reason trace, atomic
|
|
mutation semantics, world facts, save fields/migration if needed, and a real
|
|
consumer test. Do not solve a new mechanic with a reflection DSL or a script
|
|
per content asset.
|
|
|
|
## Reference tests
|
|
|
|
- `tests/content_catalog_test.gd`
|
|
- `tests/simulation_definitions_test.gd`
|
|
- `tests/unit/test_authored_situation_dialogue_content.gd`
|
|
- `tests/unit/test_activity_content_catalog_contract.gd`
|
|
- `tests/unit/test_content_routing_foundations.gd`
|
|
- `tests/animal_definition_contract_test.gd`
|
|
- `tests/unit/test_combatant_factory.gd`
|
|
- `tests/unit/test_presentation_catalog.gd`
|
|
|
|
The [simulation definitions contract](SIMULATION_DEFINITIONS.md) is the
|
|
authoritative field-level reference; this guide explains the extension path.
|