Files
sporel-lib-core.interaction/README.md

2.4 KiB

lib-core.interaction

P.0 proximity-trigger + action-dispatch lib. Register triggers with (target_x, target_y, range, action_name, callback); per-frame update(actor_x, actor_y) checks distance + was_action_pressed and fires the nearest matching trigger per action_name.

  • Lib-ID: lib-core.interaction
  • Version: 0.1.0
  • Spec: meta/docs/superpowers/specs/2026-05-10-p0-lib-interaction-design.md

Forward-compat stubs (DEPRECATED-MVP) for AABB-targets, action-effect- pipeline integration, visual-feedback / moodlet, action-cycling, hold-vs-press, per-action-resolution-override, callback pcall-wrap, target-entity-binding, range-shape variants.

API

  • interaction.register(target_x, target_y, range, action_name, callback) → id
  • interaction.unregister(id) — silent no-op if id unknown
  • interaction.update(actor_x, actor_y) — proximity-check + dispatch
  • interaction.list() → array of { id, target_x, target_y, range, action_name }
  • interaction.trigger_count() → integer

Conventions

  • Targets are points (not AABBs in P.0). range is scalar pixel-radius.
  • Distance: engine.spatial.distance(actor, target) ≤ range.
  • Multi-match resolution: per action_name, only NEAREST in-range trigger fires per update. Different action_names are independent (all may fire the same frame).
  • Was-pressed semantics: input.was_action_pressed (single-frame edge).
  • Callback receives info = { actor_x, actor_y, target_x, target_y, distance, trigger_id, action_name }. Closures may ignore the arg (function() ... end is legal).
  • Loud Lua-errors on API misuse (non-number coords, non-positive range, non-string action_name, non-function callback).
  • Silent-accept for action_name that hasn't been registered with lib-core.input — the trigger simply never fires (matches input-lib's silent-false convention).
  • Callback errors bubble up (no pcall-wrap in P.0). Resilience is E.9 refactor target.

Consumer pattern

local interaction = require("lib-core.interaction")
local input       = require("lib-core.input")

input.bind("interact", { engine.input.KEY_E })

local sign = { x = 144, y = 144, text = "Hier steht: ..." }
interaction.register(sign.x, sign.y, 40, "interact", function(info)
    engine.print(sign.text)
end)

function update(ctx, dt)
    -- (after player.update; reads player center)
    interaction.update(player_center_x, player_center_y)
end