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>
This commit is contained in:
13
.githooks/pre-commit
Normal file
13
.githooks/pre-commit
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Sporel API-Doc-Convention pre-commit hook.
|
||||||
|
SPOREL_EXE="${SPOREL_EXE:-$(command -v Sporel.exe 2>/dev/null || command -v sporel 2>/dev/null)}"
|
||||||
|
if [ -z "$SPOREL_EXE" ]; then
|
||||||
|
echo "INFO: Sporel.exe not on PATH. Skipping lint." >&2
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
"$SPOREL_EXE" --lint="$(pwd)" --fix
|
||||||
|
RC=$?
|
||||||
|
if git diff --cached --name-only | grep -qx 'README.md'; then
|
||||||
|
git add README.md
|
||||||
|
fi
|
||||||
|
exit $RC
|
||||||
107
README.md
107
README.md
@@ -1,50 +1,80 @@
|
|||||||
# lib-core.interaction
|
# lib-core.interaction
|
||||||
|
|
||||||
P.0 proximity-trigger + action-dispatch lib. Register triggers with
|
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`.
|
||||||
`(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
|
||||||
- Version: `0.1.0`
|
**Lib-ID:** lib-core.interaction
|
||||||
- Spec: `meta/docs/superpowers/specs/2026-05-10-p0-lib-interaction-design.md`
|
**Requires:** lib-core.input v>=0.4.0
|
||||||
|
**Tags:** interaction, trigger, proximity, dispatch
|
||||||
|
|
||||||
Forward-compat stubs (DEPRECATED-MVP) for AABB-targets, action-effect-
|
## Topology
|
||||||
pipeline integration, visual-feedback / moodlet, action-cycling,
|
|
||||||
hold-vs-press, per-action-resolution-override, callback pcall-wrap,
|
<!-- topology:start (auto-generated; do not edit) -->
|
||||||
target-entity-binding, range-shape variants.
|
```mermaid
|
||||||
|
graph LR
|
||||||
|
this["lib-core.interaction"]
|
||||||
|
lib_core_input["lib-core.input"]
|
||||||
|
this --> lib_core_input
|
||||||
|
```
|
||||||
|
<!-- topology:end -->
|
||||||
|
|
||||||
## API
|
## API
|
||||||
- `interaction.register(target_x, target_y, range, action_name, callback) → id`
|
|
||||||
- `interaction.unregister(id)` — silent no-op if id unknown
|
### `interaction.register(target_x, target_y, range, action_name, callback)`
|
||||||
- `interaction.update(actor_x, actor_y)` — proximity-check + dispatch
|
**Syntax:** `interaction.register(target_x: number, target_y: number, range: number, action_name: string, callback: fun(info: table)) -> id`
|
||||||
- `interaction.list() → array of { id, target_x, target_y, range, action_name }`
|
|
||||||
- `interaction.trigger_count() → integer`
|
**Example:**
|
||||||
|
```lua
|
||||||
|
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:**
|
||||||
|
```lua
|
||||||
|
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_name`s 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
|
## Conventions
|
||||||
- Targets are points (not AABBs in P.0). `range` is scalar pixel-radius.
|
|
||||||
- Distance: `engine.spatial.distance(actor, target) ≤ range`.
|
- Targets are points (not AABBs in v0.1.0). `range` is scalar pixel-radius.
|
||||||
- Multi-match resolution: per `action_name`, only NEAREST in-range trigger
|
- Distance: `engine.spatial.distance(actor, target) <= range`.
|
||||||
fires per update. Different `action_name`s are independent (all may fire
|
- Multi-match resolution: per `action_name`, only NEAREST in-range trigger fires per update.
|
||||||
the same frame).
|
|
||||||
- Was-pressed semantics: `input.was_action_pressed` (single-frame edge).
|
- Was-pressed semantics: `input.was_action_pressed` (single-frame edge).
|
||||||
- Callback receives `info = { actor_x, actor_y, target_x, target_y,
|
- Silent-accept for `action_name` that hasn't been bound with `lib-core.input` — trigger simply never fires.
|
||||||
distance, trigger_id, action_name }`. Closures may ignore the arg
|
- Callback errors bubble up (no pcall-wrap in v0.1.0).
|
||||||
(`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
|
## Consumer pattern
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
local interaction = require("lib-core.interaction")
|
local interaction = require("lib-core.interaction")
|
||||||
local input = require("lib-core.input")
|
local input = require("lib-core.input")
|
||||||
|
|
||||||
input.bind("interact", { engine.input.KEY_E })
|
input.bind("interact", { "e" })
|
||||||
|
|
||||||
local sign = { x = 144, y = 144, text = "Hier steht: ..." }
|
local sign = { x = 144, y = 144, text = "Hier steht: ..." }
|
||||||
interaction.register(sign.x, sign.y, 40, "interact", function(info)
|
interaction.register(sign.x, sign.y, 40, "interact", function(info)
|
||||||
@@ -52,7 +82,18 @@ interaction.register(sign.x, sign.y, 40, "interact", function(info)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
function update(ctx, dt)
|
function update(ctx, dt)
|
||||||
-- (after player.update; reads player center)
|
|
||||||
interaction.update(player_center_x, player_center_y)
|
interaction.update(player_center_x, player_center_y)
|
||||||
end
|
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)
|
||||||
|
|||||||
3
scripts/install-hooks.sh
Normal file
3
scripts/install-hooks.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
git config core.hooksPath .githooks
|
||||||
|
echo "Hooks activated."
|
||||||
Reference in New Issue
Block a user