Phase-A.5 implementation per sporel-meta/docs/superpowers/specs/2026-06-09-phase-A-... Re-Entry from P.0-Actor-Deferral (Trigger 1: Composition-Aktivierung). Slim wrapper: actor.create validates properties.movement_speed > 0, delegates to composition.create. actor.position reads dotted position back as two numbers. actor.move does direct inert-write to position.x + position.y (engine §11 inert-write; Action-routing deferred). DEFERRED in v0.1: Body-Slot-Aggregator, Walk-Capability, Movement-State on entity, Action-mediated move. All have re-entry-trigger notes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lib-core.actor
Thin wrapper over lib-core.composition that enforces a baseline-speed
contract for "actor" entities. Provides convenience helpers for
position-read + position-write (inert-mediated). Doesn't track any
ephemeral movement-state (vel/dir) — that stays in player_control
or whatever drives the actor each frame.
Version: 0.1.0 Lib-ID: lib-core.actor Requires: lib-core.composition v>=0.1.0 Tags: actor, entity, movement
Topology
graph LR
this["lib-core.actor"]
lib_core_composition["lib-core.composition"]
this --> lib_core_composition
engine["engine.*"]
this --> engine
Scope (v0.1.0 — Spine)
Re-Entry from P.0-Actor-Deferral (Trigger 1: Composition-Aktivierung). v0.1 is a minimal slice; intentional non-goals:
- No Body-Slot-Aggregator. Phase D / J trigger.
- No Walk-Capability (per ADR-0002 capabilities-as-derived). Waits for a second actor-consumer that needs capability-routing.
- No Movement-State on the entity. vel / dir / direction-flags are
ephemeral; kept in
player_control(or whatever driver). Persisted ones come with a re-entry-trigger. - No Action-mediated move. v0.1 uses engine-§11 inert-write directly. Action-routing is the "right" path for game-state-weighty mutations but waits until a "move" Action is registered and event/effect routing matters.
API
actor.create(spec)
Syntax: actor.create({template: string, properties: table}) -> entity
Example:
-- Caller defines a template via composition first:
composition.define_template{
id = "player",
properties = {
position = {x = 0, y = 0},
movement_speed = 200,
sprite_color = engine.render.rgb(200, 60, 80),
sprite_w = 24,
sprite_h = 24,
},
tags = {"renderable", "player"},
}
-- Then actor.create instantiates:
local p = actor.create{
template = "player",
properties = {
position = {x = 400, y = 300},
movement_speed = 200,
},
}
Description: Validates that properties.movement_speed is a
positive number, then delegates to composition.create. Loud-Error
if movement_speed is missing, non-number, or non-positive.
The caller is responsible for composition.define_template{id=...}
before invoking. Actor doesn't auto-define templates.
actor.position(handle)
Syntax: actor.position(handle) -> x, y
Description: Returns the actor's current position as two numbers
(x, y). Reads via entity:get_property("position.x"/"position.y").
Loud-Error if handle is nil.
actor.move(handle, dx, dy)
Syntax: actor.move(handle, dx: number, dy: number) -> void
Example:
-- Typical caller (player_control update-loop):
local speed = actor.movement_speed(player)
local move_dx, move_dy = compute_input_direction()
actor.move(player, move_dx * speed * dt, move_dy * speed * dt)
Description: Adds (dx, dy) to the actor's current position via direct inert-write. Caller does dt-scaling and any speed-multiplication upstream. v0.1 uses engine §11 inert-write — Action-routing is a future re-entry trigger (see Scope above).
actor.movement_speed(handle)
Syntax: actor.movement_speed(handle) -> number
Description: Convenience read of the actor's movement_speed
property (in pixels/sec by convention; caller decides the unit).
Conventions
- Position-Format: composite-table at authoring-time
(
properties = { position = {x, y} }), flattened by composition to scalar propertiesposition.xandposition.y. See Phase-A Spec §5 A-Q5 revision (2026-06-09). - movement_speed: pixels per second. dt-scaling applied at the
caller, NOT by
actor.move.
References
- Spec:
meta/docs/superpowers/specs/2026-06-09-phase-A-inactive-entities-composition-actor-reentry-design.md - Origin:
meta/docs/superpowers/specs/2026-05-10-p0-actor-deferral.md(Trigger 1: Composition-Aktivierung) - Architecture:
meta/docs/architecture/composition-model.md(Actor as Item-with-Body-Slot in Phase D; v0.1 is composition-only wrapper) - ADR-0001 (engine knows verbs, libs bring nouns)
- ADR-0002 (capabilities as derived properties — Walk-Capability deferred)
- ADR-0010 (read/write asymmetry — v0.1 inert-write escape hatch)
- ADR-0038 (API-Doc-Convention)