Files
Axel Meyer 4d334274b7 docs: migrate README to API-Doc-Convention (S2-cascade.libs)
Restructured per ADR-0038: Abstract + bold-list Badges + Topology H2
+ H3-API-Subsections (one per public function) + Conventions/Consumer
pattern/CHANGELOG/References.

Topology auto-populated via Sporel.exe --lint --fix. Pre-commit hook
installed via --install-hooks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 16:38:48 +02:00

3.6 KiB

lib-core.interaction

Proximity-trigger + action-dispatch. 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.

Version: 0.1.0
Lib-ID: lib-core.interaction
Requires: lib-core.input v>=0.4.0
Tags: interaction, trigger, proximity, dispatch

Topology

graph LR
  this["lib-core.interaction"]
  lib_core_input["lib-core.input"]
  this --> lib_core_input

API

interaction.register(target_x, target_y, range, action_name, callback)

Syntax: interaction.register(target_x: number, target_y: number, range: number, action_name: string, callback: fun(info: table)) -> id

Example:

local id = interaction.register(144, 144, 40, "interact", function(info)
    engine.print("you pressed interact at distance " .. info.distance)
end)

Description: Registers a proximity-trigger. Range is scalar pixel-radius. When the action's press-edge fires inside range, the callback is called with info = { actor_x, actor_y, target_x, target_y, distance, trigger_id, action_name }. Returns an opaque id used for unregister. Loud error(...) on misuse (non-number coords, non-positive range, non-string action, non-function callback).

interaction.unregister(id)

Syntax: interaction.unregister(id: id) -> void

Description: Removes a trigger. Silent no-op if id is unknown.

interaction.update(actor_x, actor_y)

Syntax: interaction.update(actor_x: number, actor_y: number) -> void

Example:

function update(ctx, dt)
    interaction.update(player_center_x, player_center_y)
end

Description: Per-frame proximity-check + dispatch. Per action_name, only the NEAREST in-range trigger fires that frame; different action_names are independent (all may fire same frame).

interaction.list()

Syntax: interaction.list() -> {id: id, target_x: number, target_y: number, range: number, action_name: string}[]

Description: Returns an array of trigger-records. Debug + UI inspection.

interaction.trigger_count()

Syntax: interaction.trigger_count() -> integer

Description: Returns the number of currently registered triggers.

Conventions

  • Targets are points (not AABBs in v0.1.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.
  • Was-pressed semantics: input.was_action_pressed (single-frame edge).
  • Silent-accept for action_name that hasn't been bound with lib-core.input — trigger simply never fires.
  • Callback errors bubble up (no pcall-wrap in v0.1.0).

Consumer pattern

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

input.bind("interact", { "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)
    interaction.update(player_center_x, player_center_y)
end

CHANGELOG

v0.1.0 (P.0)

  • Initial release: register/unregister + per-frame proximity + nearest-per-action dispatch.

References

  • Spec v0.1.0 (P.0): meta/docs/superpowers/specs/2026-05-10-p0-lib-interaction-design.md
  • ADR-0001 (engine knows verbs, libs bring nouns)
  • ADR-0031 (pixel-convention: Y-down-positive)
  • ADR-0038 (API-Doc-Convention)