Commit Graph
77 Commits
Author SHA1 Message Date
Hermes 5d360d256e fix: replace AnimationPlayer tracks with code-driven bone rotation system
Godot 4.2.1 AnimationPlayer cannot rotate runtime-loaded GLB bones via
':rotation' track paths. The AnimationPlayer only updates bone positions,
not rotations, on runtime GLB skeletons.

This fix replaces the entire animation approach:
- Remove AnimationPlayer track-based rotation attempts
- Add code-driven system that stores animation keyframe data in
  dictionaries and applies bone rotations directly via
  skeleton.set_bone_pose_rotation() each frame
- _is_animation_broken() detects Blender GLTF track stripping
- _ensure_locomotion_animations() replaces broken GLB anims with
  procedural data
- _apply_procedural_animation() interpolates euler angles, converts
  to Quaternion via Quaternion.from_euler(), and applies per bone
2026-06-25 10:53:54 -04:00
Hermes 86a13bc782 fix: replace stripped GLB animations with procedural rotation-based animations
Blender's GLTF exporter aggressively strips animation tracks that are
near rest pose. The Miku GLB has 54 tracks per animation but all
keyframe values are essentially rest pose (max delta 0.008 units),
causing the model to appear frozen in T-pose despite the AnimationPlayer
playing animations correctly.

This fix:
- Adds _is_animation_broken() to detect near-zero motion in animations
- Changes _ensure_locomotion_animations() to replace broken animations
  (not just create when missing)
- Uses TYPE_VALUE tracks with ':rotation' suffix for proper bone rotation
- Fixes hips bounce to use position track instead of rotation
- Adds _add_rotation_track, _add_position_track, _add_position_track_catmull
  helper functions
2026-06-25 10:38:19 -04:00
Hermes d6da221583 fix(characters): preserve all animation tracks in GLTF runtime loading
remove_immutable_tracks=true (default) strips bone tracks where keyframes
match rest pose, removing 80%+ of tracks and causing T-pose.
Editor import uses false; runtime must match.

Closes T-pose bug where animations reported playing but model stayed rigid.
2026-06-25 10:04:56 -04:00
HermesandClaude 4.7 d297da4c35 fix: resolve GLB character T-pose by fixing skeleton binding order and skin update timing
Two root causes fixed:
1. Skeleton binding fix was skipped because `skeleton` variable was null at the
   time of the check (assigned AFTER the mesh fix block). Moved skeleton
   discovery BEFORE the mesh binding fix so the MeshInstance.skeleton path
   is correctly set to "..".

2. Skin deformation wasn't triggering because `_update_skin()` (which calls
   `force_update_all_bone_transforms()`) was throttled to 30fps AND ran BEFORE
   the AnimationPlayer's `_process()` due to tree order. AnimationPlayer.advance()
   sets bone poses but does NOT emit `bone_pose_changed`, so the MeshInstance
   never knew to re-compute its vertex buffers. Fixed by using `call_deferred`
   to ensure `_update_skin()` runs AFTER all `_process()` calls (including AP),
   and removing the throttling so it runs every frame.

Co-Authored-By: Claude 4.7 <[email protected]>
2026-06-25 01:29:14 -04:00
Hermes df4c70017c fix: use force_update_all_bone_transforms() instead of undeclared constant
NOTIFICATION_UPDATE_SKELETON is not accessible in GDScript scope.
Use Skeleton3D.force_update_all_bone_transforms() which recomputes the
full bone hierarchy and emits bone_pose_changed signals.

Co-Authored-By: Hermes Agent <[email protected]>
2026-06-25 01:00:34 -04:00
Hermes 43b870465b fix: correct skin deformation and scale for GLB character models
The Miku model T-posed because the previous _update_skin() used
set_bone_pose(i, get_bone_pose(i)) which is a no-op when the pose
is unchanged. Replace with skeleton.notification(NOTIFICATION_UPDATE_SKELETON)
to force the Skeleton3D to recompute bone transforms and notify the
MeshInstance to update vertex buffers.

Also fix scale: the GLB is ~1.2m tall (not 1.6m as documented), so
set scale_factor=1.25 to fit the 1.8m player capsule, and add
position_y_offset=-0.2 to align the model's feet with the player origin.

Co-Authored-By: Hermes Agent <[email protected]>
2026-06-25 00:56:25 -04:00
Hermes c4dc4ca77c fix: force skeleton skin update at runtime for GLTF models
The AnimationPlayer correctly updates bone poses (proven in tests)
but the MeshInstance visual doesn't reflect the changes. Added
throttled _update_skin() that re-applies bone poses every ~33ms
to trigger NOTIFICATION_UPDATE_SKELETON on the Skeleton3D,
which causes the MeshInstance to update its vertex buffers.

Also set AnimationPlayer process_mode to ALWAYS to ensure it
processes regardless of parent node state.
2026-06-25 00:30:28 -04:00
Hermes 73831cb418 fix: force bone pose update for GLTF runtime skin deformation
GLTF runtime loaded models may not trigger automatic MeshInstance
vertex deformation when the AnimationPlayer updates bone poses.
Added throttled _update_skin() that re-applies current bone poses
to trigger NOTIFICATION_UPDATE_SKELETON, ensuring the renderer
sees the updated vertex positions.
2026-06-25 00:26:34 -04:00
Hermes fead2cc055 fix: resolve GDScript warnings for unused vars and shadowed names
- Prefix unused variables with underscore (chest, left_hand, right_hand, l_foot, r_foot)
- Rename 'name' parameter to 'bone_name'/'anim_name' to avoid shadowing Node.name
2026-06-25 00:04:59 -04:00
Hermes 50de6df450 fix: use animated GLB with all locomotion animations and fix scaling
The skinned player model was loading miku_rigged_final.glb which only
contained a single "Idle" animation (1 track, near-rest pose). This caused
"animation 'Jump/Walk/Run' not found" spam and a T-pose appearance.

Switch to miku_rigged_animated.glb which has all 7 animations
(Crouch, Death, Idle, Idle2, Jump, Run, Walk).

Additional fixes:
- Fix scaling: the GLB is already in meters (~1.6m tall), not cm.
  Removed the unconditional 0.01 cm->m conversion that was shrinking
  the character to 1/100th size.
- Fix bone track paths: use "MikuRig/Skeleton3D:" prefix matching the
  actual scene tree structure (AnimationPlayer is sibling of MikuRig).
- Add _ensure_locomotion_animations() to create Walk/Run/Jump/Idle
  procedurally if the GLB is missing them.
- Eliminate per-frame "not found" log spam with rate-limited warnings.
- Update level_runtime.gd and test_level_builder.gd to use animated GLB.

Closes #3d-player-model animation pipeline
2026-06-24 23:58:28 -04:00
Hermes 1653d404e2 fix: use correct Godot skeleton bone animation path format
The track path must be 'MikuRig/Skeleton3D:BoneName' (no :property suffix)
and the track type must be TYPE_VALUE with Vector3 position values.
Using :rotation suffix caused the track to not resolve.

Verified: Spine pose origin changes from (0,0,0) to (0,0.1,0) during animation.
2026-06-23 19:36:15 -04:00
Hermes 39063bfe9e fix: create proper Idle animation in Godot when GLB export loses tracks
The Blender GLTF exporter was stripping animation tracks (only 1 of 51
channels survived export). Now SkinnedPlayerModel detects this at
runtime and creates a proper Idle animation programmatically using Godot's
Animation API with 5 bone tracks (Spine, Arms, Neck, Hips).

Also switched model_path back to miku_rigged_final.glb since the
re-export wasn't adding usable animations.
2026-06-23 18:55:12 -04:00
Hermes 0b0497e128 chore: clean up debug and editor scratch files 2026-06-23 17:37:49 -04:00
Hermes e2a4e3997e fix: use a.loop_mode instead of a.mode for Godot 4.x Animation 2026-06-23 12:36:53 -04:00
Hermes 0da573f11f fix: use _find_skeleton and _find_animation_player consistently 2026-06-23 12:12:10 -04:00
Hermes 89ddac072b fix: resolve parse errors in skinned_player_model and level_runtime
- Remove duplicate is_local variable in level_runtime.gd line 224
- Remove orphaned animation code from old load_model in skinned_player_model.gd
- Both files now compile cleanly
2026-06-23 11:02:22 -04:00
Hermes 5e12502a18 fix: use GLTFDocument to load GLB at runtime (no .import needed)
Godot headless/CLI can't import GLB files — the GLTF loader only works
in the editor GUI. Switched SkinnedPlayerModel to use GLTFDocument.append_from_buffer()
which parses GLB data from raw bytes at runtime.

Verified: GLB parses successfully, generates scene with MikuRig skeleton,
AnimationPlayer, and 7 animations (Crouch, Death, Idle, Idle_001, Jump, Run, Walk).

Also added characters/glb_loader.gd as a reusable utility for loading
any GLB file at runtime.
2026-06-23 01:15:37 -04:00
Hermes 85066f71f3 fix: add position offset for skinned model alignment 2026-06-23 00:35:14 -04:00
Hermes a83fa41b19 fix: use original rigged skeleton for animations, add 6 new animations
The twintails were moving as arms because the auto-rig script treated the
combined mesh as one piece. Now using the original miku_rigged_final.glb
skeleton (which has correct skin weights from the model creator) and
adding 6 new animations (Idle, Walk, Run, Jump, Crouch, Death) on top
of the existing skeleton.

- tools/add_animations.py: adds animations to an existing rigged GLB
- tools/rig_and_animate.py: updated to separate mesh into loose parts
  before rigging (for future use with other models)
- miku_rigged_animated.glb: now 7 animations with correct skin weights
2026-06-23 00:33:40 -04:00
Hermes 0672bebe7b feat: add rigged+animated Miku player model with auto-rig pipeline
- Add miku_rigged_animated.glb (3.27MB) with 18-bone skeleton and 6 animations
  (Idle, Walk, Run, Jump, Crouch, Death) via Blender auto-rig script
- Add tools/rig_and_animate.py: reusable Blender script for rigging any humanoid
  mesh with Mixamo-compatible bone naming
- Update SkinnedPlayerModel: scale_factor, first-person mode, animation state
  matching (Idle/Walk/Run/Jump/Crouch/Death)
- Update level_runtime.gd: use skinned model for local player, procedural
  humanoid for remote players
- Update skin_manager.gd and test_level_builder.gd to use animated model
- Fix Godot 4.2.1 'is not Type' syntax in 5 weapon files
- Add editor/import_miku_to_tscn.gd for editor-based GLB import
2026-06-23 00:19:52 -04:00
Hermes f7cd3571fd fix: replace f-strings with GDScript % formatting 2026-06-22 22:20:36 -04:00
Hermes a2956635c0 fix: third-person camera orbits player facing + robust animation handling
Third-person camera:
- Camera offset now follows player's forward direction using basis.z
- Smoothly orbits behind player when they turn
- Looks at player's head area (y+1.5)

SkinnedPlayerModel:
- Creates AnimationPlayer programmatically if GLB doesn't have one
- Copies animations from armature's animation_data to the player
- Handles both direct actions and NLA tracks
- More detailed debug output for scene tree and animation state
2026-06-22 22:02:30 -04:00
Hermes c033247f75 fix: rename param to 'on' to avoid shadowing Node3D.show()/is_visible() 2026-06-22 21:56:21 -04:00
Hermes 00141f80cb fix: set position before adding grenade to tree, remove duplicate add_child 2026-06-22 21:52:48 -04:00
Hermes 3e849551bd fix: rename 'name' param to 'anim_name' to avoid shadowing Node.name 2026-06-22 21:42:38 -04:00
Hermes 1372db9d0e fix: prefix unused 'impulse' param with underscore in walking_dummy 2026-06-22 21:40:56 -04:00
Hermes cd1722ce74 fix: rename 'is_visible' param to 'show' to avoid shadowing Node3D.is_visible() 2026-06-22 21:06:35 -04:00
Hermes c8fcefe7ab fix: can't use look_at() before node is in tree, use rotation_degrees instead 2026-06-22 20:36:13 -04:00
Hermes ade3d54d20 fix: rename shadowed 'visible' param, prefix unused 'impulse' with underscore 2026-06-22 20:34:02 -04:00
Hermes a1f48d9ef0 fix: string repeat() instead of * operator in GDScript 2026-06-22 20:27:26 -04:00
Hermes b1aec93fd5 fix: animation debug + F1 third-person camera
SkinnedPlayerModel:
- Added _print_tree debug to see GLB scene structure at runtime
- Auto-play Idle animation on load
- Added periodic debug output for animation state
- Only change animation when target differs from current

Third-person camera:
- F1 toggles between FPS and third-person view
- Third-person camera positioned behind/above player
- Smooth follow with lerp
- Camera tracks player position each frame
2026-06-22 19:55:54 -04:00
Hermes e84a9d641a fix: textured Miku model + ragdoll color
- Re-exported Miku with properly mapped textures (9.8MB GLB)
- Texture files saved alongside GLB for Godot import
- Fixed Blender 5.0 API: 'Base Color' (not 'BaseColor'), major_segments (not segments)
- Ragdoll now uses Miku teal color (0.0, 0.75, 0.75)
- Player 1 uses SkinnedPlayerModel (no procedural generation)
- Other players still use procedural HumanoidModel
2026-06-22 19:46:22 -04:00
Hermes e1d2d140cb fix: calculate speed from player velocity instead of non-existent property 2026-06-22 19:10:53 -04:00
Hermes 92713a681a fix(miku): correct scale + animation playback
- Fixed Blender export: remove FBX armature modifier before scaling,
  then transform_apply(scale=True) before creating new armature
- Model now exports at correct 1.8 unit height (verified in Blender)
- SkinnedPlayerModel now polls MovementStateMachine in _process
  to drive animations based on movement state
- Player 1 gets Miku at origin, others get procedural humanoid at y=-0.9
2026-06-22 18:15:03 -04:00
Hermes ae8231d31d feat(miku): proper rigged model from Sketchfab + Blender
Pipeline:
1. Downloaded TDA-style Miku model from Sketchfab (19MB FBX, 38K verts)
2. Imported to Blender, scaled to Godot humanoid proportions (1.8u tall)
3. Created clean 17-bone humanoid armature (Hips/Spine/Chest/Head/Arms/Legs)
4. Auto-weight-painted mesh to armature
5. Added Idle (breath bounce) and Run (cycle) animations
6. Exported as GLB with embedded animations (3MB)

New:
- SkinnedPlayerModel class: loads GLB with own armature+animations
- Player 1 spawns with Miku model, others get procedural humanoid
- Completely separate from procedural model system

Files:
- assets/characters/skins/miku_rigged_final.glb (3MB, 48K verts, 17 bones, 2 anims)
- characters/skinned_player_model.gd
- Removed old procedural GLB attempts
2026-06-22 17:12:24 -04:00
Hermes b0fdc508f1 feat(miku): add rigged Miku character model with armature
- Generated rigged Miku model in Blender (79 mesh parts, 17 bones)
- Bone names match Godot Humanoid skeleton (Hips, Spine, Chest, Head, etc.)
- Includes idle animation (breath bounce)
- Fixed GLB export for Blender 5.0 API compatibility
- Updated HumanoidModel.apply_skin() with orientation fix
- Player 1 spawns with Miku rigged model, others get default blue
- Preview renders in docs/characters/skins/

Pipeline established:
- Blender headless -> Python script -> GLB export -> Godot import
- Skin system: PlayerSkin resource + SkinManager
- apply_skin() handles both GLB model and procedural color tint
2026-06-22 16:51:22 -04:00
Hermes a55eaff279 feat(skin): add skin system + Miku character skin
Skin System:
- PlayerSkin resource class (model_path, color_tint, etc.)
- SkinManager with default skins: Default, Red Team, Forest, Miku
- HumanoidModel.apply_skin() supports both GLB model replacement
  and procedural color tinting
- Procedural meshes auto-hide when GLB model is loaded

Miku Skin:
- 43-part procedural model generated in Blender (headless)
- Twin tails, headphones, thigh-high socks, idol outfit
- Teal/cyan color scheme with red accents
- Exported to assets/characters/skins/miku.glb
- Applied to player 1 in test level builder

Pipeline:
- Blender 5.0.1 + MCP addon installed
- Bridge script for socket-based Blender control
- docs/3D_ASSET_PIPELINE.md documents full workflow
2026-06-22 13:53:17 -04:00
Hermes 671b36c20c fix(map): complete rewrite of arena layout
Problems fixed:
- Player spawn moved from inside central platform to open area (z=20)
- Removed broken internal stairs inside tower (disconnected ramps)
- Removed corner towers, walkways, stepping stones, wall-run corridor,
  wall-climb surfaces, grapple anchors — all were overlapping or unreachable
- Reduced arena from 96x96 to 80x80 for tighter gameplay
- Crates properly spaced (1.5u apart), no overlaps or intersections
- Reduced from 6 spawns to 4 (corners only), each with 2 L-shaped cover
  walls and clear exit routes — no more 3-wall traps
- Spawn alcoves use 2 walls max with open diagonal exits
- Dummies placed in open areas away from geometry:
  TargetDummy at (0,-25), KillableDummy at (25,0),
  WalkingDummy patrols z=-30 from x=-20 to 20
- Central platform simplified: 16x16 base (2u) + 8x8 upper (4u)
- 4 cardinal ramps properly connect ground to platform edge
- Cover walls placed in open lanes, not blocking movement
- Barrels placed along outer walls, not in pathways
2026-06-21 22:41:40 -04:00
Hermes 3584a7e6c5 feat(props): integrate Blender GLB props into movement map
- Replace primitive _crate(), _barrel(), _pillar() with GLB scene instances
- Add 7 prop preloads: crate, barrel, pillar, ramp, weapon_pickup, health_pack, ammo_pack
- Add _load_props() and _place_prop() helpers with null guards
- Add pickup placements: weapon (center), health (east/west), ammo (center/NW/SE)
- Props load at runtime via load() - appear once Godot editor imports the GLB files
- Null guard prevents crashes in headless mode before import
2026-06-21 22:28:41 -04:00
Hermes 718a1477bf feat(assets): add 3D prop meshes generated via Blender headless
Props generated with Blender 5.0.1 headless + glTF export:
- crate.glb (wooden crate)
- barrel.glb (metal barrel)
- weapon_pickup.glb (glowing platform)
- health_pack.glb (cross-shaped pickup)
- ammo_pack.glb (ammo box)
- pillar.glb (structural pillar)
- ramp.glb (ramp mesh)

Also includes Blender MCP bridge setup in blender-mcp/ for
future AI-assisted 3D modeling.
2026-06-21 01:55:39 -04:00
Hermes 462d12bee5 fix: Godot 4.2.1 compat and map builder fixes
- Fix tab character in _build_elevated_walkways() call (line 63)
- Fix untyped 'pos' variable in grapple pillar loop (line 376)
- Remove fog_sky_affinity (Godot 4.3+ only property)
- Replace preload() with load() for runtime script loading
- Replace 'is DoubleBarrelShotgun' type check with duck-typing
- Fix 'is not OfflineMultiplayerPeer' syntax in grenade spawn
- Replace absf() with abs() in state_machine, state_air, state_ground
- Update test_level.tscn to remove stale UID reference

All fixes verified: PARSE OK and scene runs without script errors
on Godot 4.2.1 headless.
2026-06-21 01:24:42 -04:00
Hermes f164afecd8 feat(map): high-quality multiplayer movement map
96x96 arena with multi-level layout, grapple points, wall-run/climb
surfaces, 6 team spawns with anti-camping cover, and varied movement
challenges.

Map Features:
- Central multi-level structure: 20x20 platform (3u), 10x10 tower (6u),
  14x14 top platform (9u) with crown cover walls and internal stairs
- 4 corner towers (5u high) with railings and top platforms
- 4 elevated mid-side walkways (3u) with railings connecting center to edges
- 8 ramps: cardinal to central, diagonal to corners, to walkways
- Quarter-pipe curve (8 segments) near NE corner
- 4 parkour stepping stone chains (NW, NE, SW, SE quadrants)
- Wall-run corridor (N side) with parallel walls, obstacles, and floor gap
- Wall-run surfaces on all 4 outer wall sections
- Wall-climb surfaces around central tower and mid-map (warm color)
- 4 grapple anchor pillars (15u tall) with visible tops at cardinal points
- Cover system: low walls, crate clusters, corridor walls, structural pillars
- Speed corridor with side rails, speed bumps, and floor markings
- 6 spawn alcoves (3 red: NW/SW/West, 3 blue: NE/SE/East) with cover walls
- Anti-spawn-camping: each alcove has 2+ exits and blocking walls
- Floor accent tiles in central area
- Atmospheric sky with procedural sky material and fog
- Directional sun + fill light + center omni + 6 spawn accent lights
- Decorative: barrels, hazard stripes, accent beams, spawn area lights
- Full multiplayer spawning, weapon system, HUD, entities preserved
- All movement states: ground, air, wall_run, wall_climb, wall_cling,
  slide, dash, grapple

Parse verified clean with Godot 4.2.1 headless.
2026-06-21 01:03:34 -04:00
Hermes 415082d866 fix: floor-aligned spawn, remove double jump, enable crouch speed 2026-06-03 17:39:09 -04:00
Hermes d21d5a8b89 fix: restore KEY_SHIFT dash binding 2026-06-03 17:36:37 -04:00
Hermes dc2cb8ca26 fix: correct axis direction, air accel, and jump/dash input handling 2026-06-03 17:35:28 -04:00
Hermes 365264e819 fix: spawn capsule floor-aligned in test level 2026-06-03 17:28:46 -04:00
Hermes d86eb53065 fix: place floor under player and clean debug spam 2026-06-03 17:24:18 -04:00
Hermes e5e7a7284e fix: bootstrap process ticks after runtime script attach 2026-06-03 17:14:09 -04:00
Hermes 30770be7c0 debug: force process/physic process ticks after runtime script attach 2026-06-03 17:10:48 -04:00
Hermes 5cb2013d6c debug: log movement controller inputs/state/velocity each frame 2026-06-03 17:05:07 -04:00
Hermes 6c57f70fb4 fix: clean state_ground and ensure duck-type state machine bootstrap 2026-06-03 16:58:48 -04:00
Hermes 9c39d79696 fix: ensure player._ready() runs before MovementStateMachine._ready() 2026-06-03 16:56:28 -04:00
Hermes c463c29031 revert bogus debug edit in state_ground; restore clean update() entry 2026-06-03 16:55:41 -04:00
Hermes 6d2f31d962 fix: rewrite TestLevelBuilder with parse-safe InputMap bootstrapping 2026-06-03 16:54:21 -04:00
Hermes f47fc4827a test: self-bootstrap InputMap actions in TestLevelBuilder 2026-06-03 16:53:04 -04:00
Hermes ea7169048f fix: manually bootstrap state machine after runtime script attachment 2026-06-03 16:49:06 -04:00
Hermes 60091932bd fix: replace movement controller with parse-safe version for 4.6.3 2026-06-03 16:46:16 -04:00
Hermes 693145fd69 refactor: remove print_debug and switch to preload for movement scripts 2026-06-03 16:42:51 -04:00
Hermes c0a90df690 fix: wire movement controller before state machine; harden machine lookup 2026-06-03 15:14:10 -04:00
Hermes 24a8651a6d fix: guard input forwarding in PlayerMovementController; add movement_runner verifier 2026-06-03 15:09:00 -04:00
Hermes ceeff6a1ab fix: add smoke verifier, camera to TestLevel, fix player collision shape 2026-06-03 15:06:26 -04:00
Hermes 1feefbf811 test: load MovementStateMachine + state scripts via set_script() at runtime
Root cause: builder created plain Node instances for the state machine
and states, so _machine.player = self in PlayerMovementController
crashed with 'Invalid assignment ... on base object of type Node'.
Now each node gets its real script attached before _ready() runs.
2026-06-03 00:36:05 -04:00
Hermes 9bdbc69ddd fix: drop type hint on @onready _machine so runtime set_script path accepts MovementStateMachine 2026-06-03 00:34:24 -04:00
Hermes 872201aa85 fix: avoid typed @onready infer crash for MovementStateMachine
player_movement_controller.gd: use Node + get_node() instead of
typed MovementStateMachine + $ shorthand so runtime set_script paths
don't crash on @implicit_ready
2026-06-03 00:33:16 -04:00
Hermes dfed237a63 fix: unused param warning + @onready type mismatch for MovementStateMachine
- state_wall_run.gd: typed ray_origin/ray_end as Vector3
- test_level_builder.gd: restructure builder to put MovementStateMachine
  + state children under Player, attach camera under Player too
- player_movement_controller.gd: @onready uses get_node so type is not inferred
2026-06-03 00:32:03 -04:00
Hermes bb6cac9d7a test: full builder rewrite with player state machine, camera, and manual _ready()
- _build_player: creates Player (CharacterBody3D) with capsule,
  MovementStateMachine + 6 state children, attaches movement script
- Calls player._ready() manually after set_script (GDScript
  set_script does not auto-trigger _ready)
- Camera parented under Player so it follows movement
- Restores _build_camera() which was accidentally dropped
2026-06-03 00:28:56 -04:00
Hermes eeb074e58a fix(movement): typed Vector3 infer in state_wall_run.detect_wall() 2026-06-03 00:18:04 -04:00
Hermes 559c4bde8f fix(debug): multi-line string literal in test_level_builder.gd 2026-06-03 00:16:41 -04:00
Hermes 5a45f3e9bb fix: make TestLevel load on 4.6.3; build geometry from GDScript
- test_level.tscn: minimal Node3D root (zero SubResource references)
- debug/test_level_builder.gd: runtime floor/walls/lighting/camera/UI
  shapes/meshes created from BoxShape3D/BoxMesh — no .tscn subresources
- project.godot: revert features to 4.6 (installed build is 4.6.3)
2026-06-02 23:49:33 -04:00
Hermes f2bcbb6ac2 fix(scene): collision + light scale in TestLevel
- Use numeric SubResource(id) instead of uid:// strings (avoids parser error)
- Light transform: remove non-uniform scale, set only rotation + position
- Keep floor@y=-1.1, walls thin (0.4), PlayerSpawn unchanged
2026-06-02 23:45:47 -04:00
Hermes 52bb5e02c7 fix: make test_level.tscn load without subresources; align project features to Godot 4.2
- Removed all SubResource BoxShape3D references from test_level.tscn
- Changed PackedStringArray feature from 4.6 to 4.2
Scene is now pure nodes + transforms, no external resource IDs
2026-06-02 23:42:53 -04:00
Hermes d6ca58932e fix(scene): replace BoxShape3D.new() with SubResource blocks in test_level
SubResource UIDs: box_floor, box_wall_north, box_wall_east, box_wall_west
Removes parse error at line 9
2026-06-02 23:36:59 -04:00
Hermes 9d043c02e0 fix(scene): remove broken debug script ref from test_level.tscn
Rewrote scene without ext_resource / subresource UIDs so it loads from the repo root.
2026-06-02 23:28:18 -04:00
Hermes ebb6d1a750 feat(debug): add TestLevel debug scene for playable testing
- scenes/test_level/test_level.tscn — playable test environment (30x30 floor + 4 walls + ramp)
  Floor at y=-1, Player spawn at (0, 1.5, 8), FpsCamera at head height (y=1.7)
  DirectionalLight + WorldEnvironment + UI label overlay (speed/state/chain)
- debug/debug_test_env.sh — launch wrapper for manual playtesting

No code changes: raw physics testbed. Intended to be opened as first scene in Godot window.

Closes #2 (test-level scene task)
2026-06-02 23:15:52 -04:00
Hermes 6cac1f4032 fix: resolve GDScript parse errors in movement states
- state_dash.gd: Basis*Vector4 → Basis*Vector3 (no Vec4 in Godot 4.2)
- state_ground.gd: shape_owner_get_shape(0) → (0, 0); typed Variant vars; typed ray/normal
- state_slide.gd: same shape API fix + unique shape vars per branch
- state_wall_run.gd: split 'and' line into single typed bool expression
2026-06-02 23:15:20 -04:00
Hermes 63a6844421 docs: add DESIGN_MASTER.md — §1–§6 master spec for Papaya-Shooter
Covers: vision, movement mechanics (ground/air/wallrun/cling/slide/dash/chain),
combat (weapons/enemies), audio/juice, content roadmap, and decision log.
2026-06-02 22:37:28 -04:00
Hermes 202f67fa32 feat(movement): add movement state machine with air/ground/wallrun/slide/dash/ground states
- MovementStateMachine: core state machine base
- MovementParams: export-rich tunable resource
- StateGround/StateAir: grounded & aeriel locomotion with coyote, buffered jump, bunny hop
- StateWallRun / StateWallCling: wall-based traversal with wall-jump off
- StateSlide: sprint-parallel slide with friction fallout
- StateDash: burst dash with momentum brake
- PlayerMovementController: entry point wiring to CharacterBody3D
- input_map.cfg: full action map reference file
- characters/player/player_base.tscn: placeholder scene
- movement/tests/test_fsm_runner.gd: 9-state unit test runner

Closes #1
2026-06-02 22:36:00 -04:00