Add prop interaction system and throw mechanics specification

- Introduced `stickman_prop_interactor.gd` to manage prop interactions.
- Created `phase_11_prop_interactions.md` detailing the design and implementation of prop pickup, drop, and throw mechanics.
- Defined interaction states, action lifecycles, and event triggers for prop handling.
- Specified constraints for throw actions, including target positioning and velocity calculations.
- Established acceptance criteria for prop interactions and lifecycle management.
This commit is contained in:
2026-09-25 23:42:26 -04:00
parent 730a9a966b
commit 6a1359f244
22 changed files with 3433 additions and 34 deletions
+7 -1
View File
@@ -33,7 +33,7 @@ This document tracks known technical debt, optimization opportunities, and minor
| 21 | **Phase 3c drag-reorder uses nearest-row-center, not an insertion point** — `QueuePanel` / `RulePanel` reorder computes the drop target as the row whose vertical center is nearest the mouse, then moves the dragged item to that index. | Low | Open | Functional, but the drop position can read off-by-one near row boundaries (it snaps to a whole row rather than an edge between rows). A true insertion-point indicator (a line drawn between rows) would be clearer; not worth the complexity until reordering long queues/rules is common. (2026-09-04) |
| 22 | **`--check-only --script` needs a prior `--editor` rescan for new `class_name` scripts** — a freshly added `class_name` (e.g. `QueuePanel`) is not resolvable by `--check-only --script res://scripts/sandbox_stage.gd` until `--headless --editor --quit` regenerates `.godot/global_script_class_cache.cfg`. | Low | Open | Verification-workflow gotcha only (not a runtime bug): in-editor the cache is always current. CI/headless scripts that add new `class_name`s should run an `--editor` pass before per-script `--check-only`. (2026-09-04) |
| 23 | **Phase 3c confirmation dialog is popped over an exclusive panel** — Queue delete / Clear All (`_on_queue_panel_delete_requested` / `_on_queue_panel_clear_requested`) and Rule delete / Clear All (`_on_rule_panel_delete_requested` / `_on_rule_panel_clear_requested`) call the shared `ConfirmationDialog` (`_ask_confirm`) **without first hiding the `exclusive = true` `QueuePanel` / `RulePanel`**. | Low | Open | Distinct facet of #19 (host-visibility discipline): popping a second exclusive window over a visible exclusive panel logs a **non-fatal engine warning** and the confirmation may render **non-modal**. It still functions (the panel is re-shown after the callback) — cosmetic. A fix would hide the host panel around `_ask_confirm` and re-show it in the confirm callback (and on the dialog's cancel/hide). Deliberate non-debt note: plan §11.2's separate confirmation dialog for editing `ragdoll`/`recover` actions was implemented instead as a paramless `ActionEditor` pre-fill — recorded in `docs/phase_3c_editor_spec.md` §2 decision 5, not as a debt row. (2026-09-04) |
| 24 | **Sandbox trigger rules use session-only instance IDs** — `entered_area` source/target references and action targets are `Object.get_instance_id()` integers. | Low | Open | Correct for the current in-memory rule engine and shared by the builder, matcher, visualizer, cleanup, and action executor. Rules survive `EDIT ⇄ DIRECT ⇄ PLAY` but are not serialized; a future saved-stage format needs stable authored object IDs instead of runtime instance IDs. (2026‑09‑11) |
| 24 | **Sandbox rule references use session instance IDs at runtime** — trigger sources/targets and action actors use `Object.get_instance_id()` integers; StageSceneIO remaps these through per-save `file_id` values. | Low | Open | This is correct for the current in-memory engine and save/load remapping. Phase 11’s approved spec adds persistent per-instance prop `stage_object_id` values for queue/rule prop actions and upgrades the scene format to 1.1; implementation and compatibility verification remain open. (2026‑09‑11; spec decision 2026‑09‑24) |
| 25 | **Contact direct-state timing fallback** — `PropBlock` may receive `body_entered` before a matching direct-state contact row is available. | Low | Open | `_on_body_entered()` uses the documented center-direction / prop-position fallback when the row is absent, so the signal remains safe but the normal and position are less precise on that edge. (2026-09-12) |
| 26 | **Impact speed is a coarse magnitude** — collision reactions currently scale from `prop.linear_velocity.length()`, not normal-relative velocity or an impulse computed from contact mass. | Low | Open | This keeps the signal contract simple and deterministic. Use the normal component and/or contact impulse if reaction strength needs to reflect glancing impacts accurately. (2026-09-12) |
| 27 | **Post-IK reaction timing is engine-order-sensitive** — bounded flinch offsets are applied at the end of `StickmanRig._physics_process()`, after the IK/head-pin work. | Low | Open | The current slot is verified and prevents cumulative rotation, but future changes to Skeleton2D modification ordering could overwrite or delay the visible reaction. Revisit only with a targeted engine-order regression. (2026-09-12) |
@@ -60,6 +60,8 @@ This document tracks known technical debt, optimization opportunities, and minor
| 48 | **Phase 12 paused paths use one representative ground anchor** — the nearest terrain ray below live feet or ragdoll bounds supplies the pending path origin. | Low | ✅ Resolved | Implemented the approved representative ground anchor, with a live-feet fallback when the probe finds no surface. Multi-contact path planning across a sprawled ragdoll and uneven terrain remains outside Phase 12, but the current anchor is stable and inspectable for paused queue authoring. (2026-09-24) |
| 49 | **Phase 12 event edges must be rebaselined without replay** — freezing bodies may emit contact exits/entries, and the stage polls area overlap before child rig movement. | Medium | ✅ Resolved | Event dispatch remains gated until a silent contact/overlap baseline is established on Resume. Existing overlaps do not refire because of the pause transition, and rules authored while paused apply to future events only. Reset clears runtime event edges. (2026-09-24) |
| 50 | **Phase 12 paused-edit autosave stores authored state, not the frozen snapshot** — queue/rule edits occur at `t > 0` while stage bodies are at temporary physical transforms. | Medium | ✅ Resolved | A 1.0 s debounce writes the existing `.scene` schema using authored object transforms plus current queues/rules. The timer can finish after Resume; runtime pose, velocities, reactive consequences, and action history are session-only. Paused edits therefore autosave without turning the live pose into the authored starting layout. (2026-09-24) |
| 51 | **Phase 11 throw distance and speed are shared across prop types** — the landing-target solver does not yet tune throwability by material or weight. | Low | Open | Deliberately deferred from the approved landing-target amendment. If playtesting needs it, add an explicit gameplay throwability factor based on prop weight/material; do not rely on rigid-body mass to change gravity or mutate physical mass for throw balance. Current shared limits are a 3,600 px target radius and 2,100 px/s speed cap. (2026-09-25) |
| 52 | **Throw target preview ignores earlier queued pickups** — the live preview requires `_held_prop`, so editing a pending throw after a pending pickup at `t = 0` cannot show the actual planned throw arc. | Medium | ✅ Resolved | The preview now infers a virtual held-prop state from the authored queue prefix and provides a pure, non-mutating planning trajectory using the prop/grip and predicted pickup stand-off. When a prop cannot be resolved, it shows a neutral explanation; runtime still recomputes from actual state. User verified the result. (2026-09-25) |
---
@@ -112,6 +114,10 @@ This document tracks known technical debt, optimization opportunities, and minor
| 2026-09-22 | Phase 10a whole-prop transform extension approved and implemented (`specs/phase_10a_prop_scaling.md` §3.4). The prior Resize Whole Prop toggle becomes one **Transform Whole Prop** tool that mirrors Arrange: drag visible geometry to move the whole document, drag the union rotation dot to rotate it about canonical `(0,0)`, and drag a corner for the existing uniform origin-based resize. Move translates every point and non-origin anchor (snapping the baseline delta when Snap is ON); rotate transforms every point/anchor position and adds the angle to editable anchor orientations; circle radius changes only on resize. All gestures preview from snapshots outside authoritative save state and commit once on release; Esc cancellation, selection restoration, mode lifecycle, `.prop` v1.0, and deferred document undo remain unchanged. |
| 2026-09-22 | Phase 10a implementation and final UI were user verified. The Arrange top bar is ordered **Transform Whole Prop**, **Normalize Size**, **Center Prop**, **Show Stickman Guide**; the numeric scale textbox and Apply Scale button are removed. Transform Whole Prop and Normalize Size are hidden in Reshape and Attach, while Center Prop and Show Stickman Guide remain available. Whole-prop move, 15-degree Ctrl rotation, uniform resize, anchor following, Snap movement, and Esc cancellation are documented in `docs/prop_editor_user_guide.md`; focused tests and the Prop Editor startup smoke test passed. |
| 2026-09-24 | Phase 12 Live Director implemented and editor-verified. PLAY/DIRECT pause and resume preserve simulation time and live state; the top-bar clock is visible, Space toggles on key press, and paused DIRECT supports action/event editing without object transforms. Pending-only reorder, consumed-action deletion, interrupted-action history, contact rebaseline, and authored-state autosave are documented in the README and spec. Follow-up fixes make locomotion animation resume reliably, preserve a paused recovery tween instead of re-ragdolling, and clear stale foot-contact locks so recovery does not cross the feet. Rows #46–#50 resolved; no `.scene` format change. |
| 2026-09-24 | Phase 11 Prop Interactions architecture spec written (`specs/phase_11_prop_interactions.md`) after approval of fixed stage-world throw targets, one prop in one compatible hand per stickman, and persistent per-instance prop IDs. The design adds a per-rig PropInteractor, keeps pickup auto-approach inside one authored queue action, carries existing .prop anchors into runtime, uses a bounded Godot-coordinate ballistic solver, emits events only after committed prop transitions, and migrates StageSceneIO 1.0 scenes to 1.1. Row #24 remains Open pending implementation. |
| 2026-09-25 | Phase 11 throw UX amendment approved (`specs/phase_11_prop_interactions.md` §1.1): treat the saved cursor point as aim plus power (distance maps smoothly to a 300–1,250 px/s capped speed), preview the collision-limited ballistic impact, and replace the short windup with a reach-clamped overhand arc that releases during its forward sweep. The existing `{type, target_position}` queue payload remains unchanged. |
| 2026-09-25 | Phase 11 throw landing-target amendment approved (`specs/phase_11_prop_interactions.md` §1.2): clamp the cursor's effective target to 800 px from the stickman root, solve the fastest valid descending trajectory under a 1,250 px/s cap, distinguish the raw cursor/effective target/early collision markers, and preserve the fixed world-space queue payload. Open-air targets remain valid; prop weight/material throwability is deferred under #51. |
| 2026-09-25 | Phase 11 throw-range tuning updated after user feedback: target radius 3,600 px and speed cap 2,100 px/s. The queue-aware, non-mutating target-preview amendment (`specs/phase_11_prop_interactions.md` §1.3) was approved, implemented, and user verified; row #52 is resolved. Throw limits remain shared across prop types under open row #51. |
---