docs(vagrant): README sync to v0.4.3 — Subterrain-model puppet features
Updates README to describe the Subterrain-style puppet control model implemented across v0.3.1–v0.4.3. Previous README described v0.2.0 state and predated the multi-look-target, slerp, inherit_scale, procedural orientation, and tactical-twist foot behavior. Demonstrates section updated: multi-look-target (soft/aim), scale- deformation walk cycle, procedural leg orientation, foot-body-orientation (tactical twist), inherit_scale=false on feet, per-channel conflict guard, camera.begin/finish world-space rendering. Interactions section updated to describe the v0.4.3 visual behavior. Full CHANGELOG from v0.2.0 through v0.4.3 with per-version summaries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
104
README.md
104
README.md
@@ -1,11 +1,15 @@
|
|||||||
# sporel-module-vagrant-skeleton
|
# sporel-module-vagrant-skeleton
|
||||||
|
|
||||||
F.vagrant Tier-1 test-chamber: single player as puppet, WASD direct
|
F.vagrant Tier-1 test-chamber: single player as a 13-bone humanoid puppet,
|
||||||
movement, camera-chase, headtrack to mouse-cursor. Phase 1 stage.
|
WASD movement, camera-chase, multi-target look-at (body lazy-tracks mouse via
|
||||||
|
slerp, head snaps to mouse with ±60° clamp). Demonstrates the Subterrain-style
|
||||||
|
puppet control model: leg orientation decoupled from body via procedural
|
||||||
|
callback, foot-body-orientation ("tactical twist"), scale-deformation walk
|
||||||
|
cycle, and inheritance-decoupled foot sprites.
|
||||||
|
|
||||||
**Version:** 0.2.0
|
**Version:** 0.4.3
|
||||||
**Module-ID:** vagrant-skeleton
|
**Module-ID:** vagrant-skeleton
|
||||||
**Requires:** lib-core.input >=0.4.0, lib-core.camera >=0.3.0, lib-core.render >=0.1.0, lib-core.maps >=0.1.2, lib-core.puppet >=0.2.0, lib-asset.prototype-subterrain >=0.1.0
|
**Requires:** lib-core.input >=0.4.0, lib-core.camera >=0.3.0, lib-core.render >=0.1.0, lib-core.maps >=0.1.2, lib-core.puppet >=0.4.3, lib-asset.prototype-subterrain >=0.1.0
|
||||||
**Tags:** test-chamber, puppet, walking-sim
|
**Tags:** test-chamber, puppet, walking-sim
|
||||||
|
|
||||||
## Topology
|
## Topology
|
||||||
@@ -16,32 +20,45 @@ movement, camera-chase, headtrack to mouse-cursor. Phase 1 stage.
|
|||||||
## Controls
|
## Controls
|
||||||
|
|
||||||
- **W A S D** — direct movement (4-way, normalized for diagonals)
|
- **W A S D** — direct movement (4-way, normalized for diagonals)
|
||||||
- **Mouse** — head/torso look-at target
|
- **Mouse** — body + head look-at targets (same position, different smoothing)
|
||||||
- **ESC** — return to launcher
|
- **ESC** — return to launcher
|
||||||
|
|
||||||
## Demonstrates
|
## Demonstrates
|
||||||
|
|
||||||
- lib-core.puppet integration (skeleton, keyframe animation, procedural-ready, look-at constraint)
|
- lib-core.puppet v0.4.3 integration:
|
||||||
- idle <-> walk animation-state transition driven by movement input
|
- Multi-look-target: body "soft" (slerp=6, lazy) + head "aim" (instant-snap, ±60° clamp)
|
||||||
|
- Scale-deformation walk cycle: leg.scl_y cycles +1/0/-1 via keyframe animation
|
||||||
|
- Procedural leg orientation: legs face walk direction independent of body rotation
|
||||||
|
- Foot-body-orientation ("tactical twist"): feet face body direction, not leg direction
|
||||||
|
- `inherit_scale: false` on feet: feet do not Y-flip when leg.scl_y goes negative
|
||||||
|
- Per-channel conflict guard: walk animation (scl) + procedural (rot) on same leg bones
|
||||||
|
- Camera in `camera.begin()/finish()` block for correct world-space rendering
|
||||||
|
- WASD movement → walk_fwd_lower + walk_upper animation pair (speed = 0.45x)
|
||||||
|
- Idle state → idle + idle_lower animations
|
||||||
- Camera-chase via lib-core.camera target-provider
|
- Camera-chase via lib-core.camera target-provider
|
||||||
- Throwaway-content test-chamber stance: existing maps v0.1 format,
|
- Sprite-tilemap via lib-core.maps
|
||||||
hand-painted humanoid rig + 2 keyframe animations.
|
|
||||||
|
|
||||||
## Interactions
|
## Interactions
|
||||||
|
|
||||||
- WASD active -> walk animation on lower track
|
- WASD active → legs swing in walk direction; body slowly rotates to mouse; head snaps to mouse
|
||||||
- WASD released -> idle animation on upper track (subtle torso sway)
|
- WASD released → idle_lower collapses legs (scl=0); upper body returns to idle sway
|
||||||
- Mouse moved -> head-bone angle updates each frame to face cursor's
|
- Mouse moved → body lazy-rotates via slerp (look_at_slerp: 6); head snaps within ±60° of body
|
||||||
world-position (look-at constraint on bones marked `look_at: true`)
|
- Walking east while body faces north → legs perpendicular to body, hips body-relative, feet face north
|
||||||
|
|
||||||
## CI Hooks
|
## CI Hooks
|
||||||
|
|
||||||
- `SPOREL_CI=1` -> 60-frame perf canary. Emits `vagrant: frame_avg_ms=N`
|
- `SPOREL_CI=1` → 60-frame perf canary. Emits `vagrant: frame_avg_ms=N`
|
||||||
and `vagrant: render_frame_ok` (per-frame, from render hook), then exits.
|
and `vagrant: render_frame_ok` (per-frame, from render hook), then exits.
|
||||||
Used by smoke stages P0-S25a + P0-S25b.
|
Used by smoke stages P0-S25a + P0-S25b.
|
||||||
|
- `SPOREL_VAGRANT_PHASE1_DRIVE=1` → scripted synthetic WASD (frames 20-40
|
||||||
|
move east). Used by P0-S25 puppet-test integration.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
|
- `superpowers/specs/2026-05-18-puppet-subterrain-model-design.md` (design basis)
|
||||||
|
- `docs/adrs/0040-puppet-subterrain-model-pivot.md` (architectural rationale)
|
||||||
|
- `architecture/puppet.md` (lib-core.puppet reference)
|
||||||
|
- `audit/2026-05-18-puppet-subterrain-model-manual-test.md` (manual verification checklist)
|
||||||
- ADR-0028 (Launcher-Flow)
|
- ADR-0028 (Launcher-Flow)
|
||||||
- ADR-0036 (Lib-Override for multi-module reuse)
|
- ADR-0036 (Lib-Override for multi-module reuse)
|
||||||
- ADR-0037 (Tests-as-Libs)
|
- ADR-0037 (Tests-as-Libs)
|
||||||
@@ -49,23 +66,44 @@ movement, camera-chase, headtrack to mouse-cursor. Phase 1 stage.
|
|||||||
|
|
||||||
## CHANGELOG
|
## CHANGELOG
|
||||||
|
|
||||||
|
### v0.4.3
|
||||||
|
- `inherit_scale: false` on foot_l, foot_r: feet no longer Y-flip when leg.scl_y
|
||||||
|
inverts during walk cycle. foot.rest.scl reset to [1,1].
|
||||||
|
- foot procedural callback writes foot.rot to cancel leg.rot → foot.world.rot = body.world.rot.
|
||||||
|
|
||||||
|
### v0.4.2
|
||||||
|
- Procedural orientation callback writes leg.rot + foot.rot (per-channel guard allows
|
||||||
|
this alongside walk_fwd_lower which writes only leg.scl).
|
||||||
|
|
||||||
|
### v0.4.1
|
||||||
|
- head look-at uses target_local normalization (-π, π]) to fix flick at body south-facing.
|
||||||
|
|
||||||
|
### v0.4.0
|
||||||
|
- Multi-look-target: body tracks "soft", head tracks "aim" (both currently raw mouse).
|
||||||
|
- body.look_at_slerp = 6 (lazy rotation); head instant-snap with rot_min/max ±60°.
|
||||||
|
- Legs re-parented from root to body (hip-static body-relative positioning).
|
||||||
|
- Procedural "leg_foot_orientation" callback: leg faces walk direction,
|
||||||
|
foot cancels leg rotation to stay body-aligned.
|
||||||
|
- walk_fwd_lower plays at speed = 0.45x for human-feel cadence.
|
||||||
|
- Rendering wrapped in camera.begin()/camera.finish() block.
|
||||||
|
|
||||||
|
### v0.3.3
|
||||||
|
- sprite_rot applied to leg bones to compensate for sprite natural orientation.
|
||||||
|
|
||||||
|
### v0.3.2
|
||||||
|
- Persistent look_at_state; fixes rate-limit reset each frame.
|
||||||
|
|
||||||
|
### v0.3.1
|
||||||
|
- look-at atan math corrected: atan(dx, -dy) for sprite-top convention.
|
||||||
|
|
||||||
|
### v0.3.0
|
||||||
|
- Sprite-mode rendering: 13-bone humanoid puppet with multi-channel animation.
|
||||||
|
- walk_fwd_lower (lower track): leg.scl_y cycle +1/0/-1 (substrate walk_fwd_lower).
|
||||||
|
- walk_upper (upper track): arm-swing animation.
|
||||||
|
- idle + idle_lower: upper body sway + leg collapse.
|
||||||
|
- Sprite-tilemap with 4 floor variants; hardcoded furniture.
|
||||||
|
|
||||||
### v0.2.0
|
### v0.2.0
|
||||||
- Sprite-mode rendering throughout: 13-bone humanoid puppet via
|
- Sprite-mode rendering throughout: 13-bone humanoid puppet via lib-core.puppet v0.2
|
||||||
lib-core.puppet v0.2 with PROTOTYPE asset-pack textures; sprite-tilemap
|
with PROTOTYPE asset-pack textures; sprite-tilemap via lib-core.maps v0.1.2 with
|
||||||
via lib-core.maps v0.1.2 with 4 floor variants (floor_001-003 walkable,
|
4 floor variants; hardcoded furniture (bed, bench, backpack).
|
||||||
floor_004 as wall); hardcoded furniture (bed, bench, backpack) via
|
|
||||||
engine.render.draw_sprite_transform.
|
|
||||||
- Asset-pack indirection: manifest.module asset_aliases maps the alias-
|
|
||||||
keys (player, tiles, world) to lib-asset.prototype-subterrain. Rig
|
|
||||||
and tilemap atlas-ids resolved at init via puppet.load_textures and
|
|
||||||
maps.load_textures.
|
|
||||||
- Tile rotations: vagrant_test.map.json includes a tile_rotations
|
|
||||||
parallel array exercising 90 and 180-degree rotations for visual
|
|
||||||
verification of the rotation pipeline.
|
|
||||||
- Animation refinements: walk on lower track now includes foot bones
|
|
||||||
(legs + feet alternate); idle on upper track with subtle body+head
|
|
||||||
sway.
|
|
||||||
- New smoke traces emitted under SPOREL_CI=1:
|
|
||||||
vagrant: render_frame_ok (per frame from render hook),
|
|
||||||
vagrant: sprite_mode=on (once after first sprite draw),
|
|
||||||
vagrant: assets_loaded=14 (once after init).
|
|
||||||
|
|||||||
Reference in New Issue
Block a user