Skip to content

Player actions

PlayerActionQueue · PlayerActionSystem

Kind Engine infrastructure (not toggleable)
Project NextIteration.Engine/PlayerActionQueue.cs, PlayerActionSystem.cs
Exposes POST /worlds/{id}/player-actions
Consumes queued actions from the API, the harness, (later) rule registration
Produces intents tagged player:<id> in the next tick's Agency phase (priority 1)
Status designed · Phase 1 (#39)
PLAN §13.3, §18.9
Player Tinkering

Everything a player does to the world is a player action: queued, converted to intents by PlayerActionSystem at the start of the next Agency phase, resolved by the resolver like any other intent, recorded by the trace with source player:<id>. No endpoint writes the graph directly.

POST /worlds/{id}/player-actions
{ "playerId": "player_1", "actions": [
  { "type": "set_attribute",    "nodeId": "inn", "key": "temperature", "value": 400.0 },
  { "type": "add_component",    "nodeId": "inn", "component": "OnFire" },
  { "type": "create_node",      "templateId": "npc_villager", "containerId": "village_square",
                                "attributeOverrides": { "personality_caution": 0.2 } },
  { "type": "destroy_node",     "nodeId": "berry_bush_3" },
  { "type": "add_edge" | "remove_edge" | "delta_attribute" | "remove_component" … }
]}
→ { "queued": 2, "willApplyAtTick": 343, "actions": [ { "index": 0, "status": "queued" }, … ] }

Actions map 1:1 to intent types. Structural validation at queue time (shape, known type, non-empty ids); semantic validation at apply time by the resolver (does the node exist, are bounds respected). Rejected actions come back with "status": "rejected" and a reason.

Guard rails

The World node and rule nodes cannot be destroyed; set_attribute on world_time or ticks_per_day is rejected. A Tinkerer can wreck a village, not the clock.

Why it is not a system

PlayerActionSystem runs first in the Agency phase but is registered outside the toggle set. The spike registered it as an ordinary system and POST …/systems/PlayerAction/deactivate silently cut the player off.

Priority

Player intents carry a high priority. Because the phase resolves as one batch, a player's Set beats a system's regardless of which ran first (PLAN §18.6).

History

Phase Change
1 Introduced; outside the toggle set; clock guard rails; the harness uses the same queue (player:harness).

See also

API · Intents and the resolver · Harness