docs: add current developer feature index
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# Feature slice: commands, targets, and economy
|
||||
|
||||
This slice makes player and NPC interactions converge on one authority path.
|
||||
The main pieces are `ActionCommand`, `ActionOffer`, `ActionResult`,
|
||||
`ActionCommandService`, `CatalogInteractionService`,
|
||||
`ActivityActionCommandService`, `WorldTargetRegistry`, `ActiveWorldAdapter`,
|
||||
`StorageRoutingPolicy`, and `VillageEconomy`.
|
||||
|
||||
## Offer versus command
|
||||
|
||||
An offer is a read-only, copied description of what an actor could attempt.
|
||||
It may contain stable action/target IDs, capability data, copy text, a reason
|
||||
trace, expected state revision, target generation, context identity, and
|
||||
registry-instance identity. It must not contain a `Node`, provider reference,
|
||||
callable, or authoritative result.
|
||||
|
||||
The actor submits an `ActionCommand` with stable actor/action/target IDs,
|
||||
optional item and amount, and an expected state revision. The service rechecks
|
||||
everything at execution time. A valid offer is not permission to execute after
|
||||
the world changes.
|
||||
|
||||
```text
|
||||
query -> copied ActionOffer
|
||||
|
|
||||
v
|
||||
player/NPC command
|
||||
|
|
||||
v
|
||||
revalidate revision + registry instance + generation + provider
|
||||
|
|
||||
v
|
||||
revalidate actor life + capability + range + target + reservation + cost
|
||||
|
|
||||
v
|
||||
atomic mutation -> exact world fact -> copied ActionResult
|
||||
```
|
||||
|
||||
## Context-scoped targets
|
||||
|
||||
`ActiveWorldAdapter` has explicit `world_id`, `location_id`, and `context_id`
|
||||
identity. It owns one `WorldTargetRegistry` for that context. Resource,
|
||||
storage, activity, and animal providers register a `WorldTargetDescriptor`
|
||||
containing a canonical target ID, target kind, capability descriptors, and a
|
||||
transient provider binding.
|
||||
|
||||
The registry provides:
|
||||
|
||||
- O(1) canonical ID lookup;
|
||||
- cross-kind duplicate rejection within a context;
|
||||
- deterministic sorted IDs and capability filtering;
|
||||
- generation-checked transient `WorldTargetHandle` values;
|
||||
- provider registration/unregistration and stale-provider pruning.
|
||||
|
||||
The target ID and contextual scope are the authority. A handle is only a
|
||||
short-lived geometry/provider reference. Rebuilding a context restarts local
|
||||
generations, so player results also carry a registry-instance token to prevent
|
||||
ABA execution against a replacement registry.
|
||||
|
||||
`LoadedResourceSpatialIndex` accelerates finite resource queries by action and
|
||||
horizontal cell. It is disposable presentation state; amounts, reservations,
|
||||
yield, risk, and discovery priority remain in simulation records.
|
||||
|
||||
## The current shared handler
|
||||
|
||||
`ActivityActionCommandService` is the first production shared command handler.
|
||||
Patrol and study are authored `activity_metric_delta` actions. The handler:
|
||||
|
||||
1. validates the actor and expected revision;
|
||||
2. validates the action's typed handler/effect contract;
|
||||
3. validates activity target kind, live provider, registry scope/instance,
|
||||
capability, range, capacity, and task authorization;
|
||||
4. preflights and withdraws any authored completion cost through
|
||||
`VillageEconomy` and `StorageRoutingPolicy`;
|
||||
5. applies the bounded safety or knowledge metric delta;
|
||||
6. appends one scoped `activity_completed` fact;
|
||||
7. returns exact event IDs, final revision, and reason trace.
|
||||
|
||||
If the cost is unavailable, no effect is applied and one structured
|
||||
`task_blocked` fact records the action, source storage, item, and required
|
||||
amount. A capped metric does not consume a cost or emit a false delta. The
|
||||
primary event keeps the command revision; synchronous situation/commitment
|
||||
consequences may append a causal suffix, and the result reports the final
|
||||
revision.
|
||||
|
||||
NPCs must use their actual current action, target, task state, completion flag,
|
||||
alive state, and context scope. An idle, dead, downed, wrong-target, or
|
||||
wrong-world direct command fails without mutation. Players use the dedicated
|
||||
player boundary, which requires all stale-offer tokens rather than accepting
|
||||
sentinel defaults. Both paths share definition validation, economy, event, and
|
||||
state checks.
|
||||
|
||||
## Typed effects and transactional planning
|
||||
|
||||
`ActionEffectPlanner` turns authored `ActionEffect` resources into an explicit
|
||||
`ActionEffectPlan` with stable operation IDs, authored order, parameters, and a
|
||||
reason trace. It supports the bounded typed effects currently registered:
|
||||
metric/need changes, exact inventory/storage/cargo transfers, damage/healing,
|
||||
relationship changes, scheduling ordinary work, and site-condition changes.
|
||||
|
||||
`TransactionalActionEffectCommitter` is the extension seam for a mechanic that
|
||||
needs more than the built-in activity handler. A committer must apply one whole
|
||||
plan atomically, return unique event IDs on success, or return a rollback-safe
|
||||
failure with no event IDs. Plans reject unknown kinds, duplicate/reordered
|
||||
operations, non-primitive values, non-finite numbers, same-role transfers, and
|
||||
empty effect sets.
|
||||
|
||||
## Economy and routing
|
||||
|
||||
`VillageEconomy` owns exact storage/NPC/player inventory mutations. The
|
||||
pantry, woodpile, apothecary, resource yields, animal feeding, player carry
|
||||
loop, and action costs use the same transaction boundary. `village.food` and
|
||||
`village.wood` are synchronized aggregate views, not second mutation paths.
|
||||
|
||||
`StorageRoutingPolicy` selects compatible storage by accepted item ID/tag,
|
||||
priority, capacity, settlement scope, and stable target ID. The herb →
|
||||
apothecary route proves that routing is no longer a food/wood switch. The
|
||||
production Jajce economy still has one village settlement; regional stockpiles
|
||||
and markets are future work.
|
||||
|
||||
## Adding a new interaction
|
||||
|
||||
1. Add or reuse an `ActionDefinition` with target/capability/handler/effect
|
||||
fields.
|
||||
2. Add target capability data to the provider definition or scene provider.
|
||||
3. Register the provider through `ActiveWorldAdapter`.
|
||||
4. Add an offer query and a command service/handler only if the existing typed
|
||||
handler cannot express the mechanic.
|
||||
5. Revalidate all authority at command time.
|
||||
6. Mutate records, append the exact event, and test both player and NPC paths.
|
||||
7. Add loaded/abstract and stale-offer regressions where applicable.
|
||||
|
||||
Do not put persistent amounts on `StorageNode`, use abstract Vector3 fallback
|
||||
targets, or let the HUD call `SimulationManager` mutation methods directly.
|
||||
|
||||
## Reference tests and contracts
|
||||
|
||||
- `tests/world_target_registry_test.gd`
|
||||
- `tests/context_scoped_world_targets_test.gd`
|
||||
- `tests/unit/test_catalog_interaction_service.gd`
|
||||
- `tests/unit/test_activity_action_command_service.gd`
|
||||
- `tests/unit/test_activity_content_catalog_contract.gd`
|
||||
- `tests/unit/test_action_effect_planning.gd`
|
||||
- `tests/resource_node_player_parity_test.gd`
|
||||
- `tests/food_storage_loop_test.gd`
|
||||
- `tests/animal_food_delivery_test.gd`
|
||||
|
||||
For the complete action lifecycle and active-position rules, read
|
||||
[Action System Architecture](ACTION_SYSTEM_ARCHITECTURE.md). For definition
|
||||
fields, read [Simulation Definitions](SIMULATION_DEFINITIONS.md).
|
||||
Reference in New Issue
Block a user