# 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).