Commit Graph

72 Commits (6340693b46c613d4161826aa3e1ff2945b5473aa)

Author SHA1 Message Date
VinPropane 6340693b46 NEON-28: run follow camera in physics after Player (fix jitter) 2026-04-10 22:23:50 -04:00
VinPropane f0ff5c9d77 NEON-28: fix occluder key check order for freed instances 2026-04-10 22:20:51 -04:00
VinPropane 15d304fa2c NEON-28: camera contracts, E6.M2 adjacency, occluder purge 2026-04-10 22:11:40 -04:00
VinPropane a66bf885f2 NEON-16: apply repo-local gdformat
Apply the repo-local gdformat output to the touched GDScript files so the pre-push formatting hook passes. This is a formatting-only follow-up to the lint-hook cleanup.
2026-04-10 00:50:29 -04:00
VinPropane 4b861a69df NEON-16: satisfy GDScript lint hooks
Refactor the bump escape helper and shared test script loading so the branch passes the repo's pre-push GDScript lint checks. This keeps the runtime behavior intact while unblocking push and PR creation.
2026-04-10 00:48:11 -04:00
VinPropane 1f5c1e7619 NEON-16: harden idle jitter follow-up
Harden idle settling so flat ground, obstacle contacts, and rare bump-edge cases stop drifting instead of looping corrective nudges. Also resolves the saved review follow-up items and syncs the runtime docs to the final feet-height and idle-anchor behavior.
2026-04-10 00:46:53 -04:00
VinPropane 0fa2c0f93b NEON-30: skip occluder bodies in ground-pick raycast loop
ground_pick.gd now checks _collider_is_occluder before the walkable
break: when the ray hits a body in the "occluder" group it advances
OCCLUDER_PICK_THROUGH past the hit point and continues, unconditionally
and regardless of OcclusionPolicy fade state.  Non-occluder click
targeting is unchanged.

Three unit tests added to ground_pick_test.gd covering occluder ancestry
detection.  Plan open questions and module doc updated.
2026-04-09 22:51:22 -04:00
VinPropane 986613fd26 NEON-27: apply gdformat to isometric_follow_camera.gd
Style-only: flatten short boolean expression in occlusion_policy_is_valid;
reformat string interpolation in push_warning calls.
2026-04-08 23:56:21 -04:00
VinPropane f1b4e50729 NEON-27: finalise review (Approved) + Godot uid files
Review verdict updated to Approved; all blocking issues and suggestions
resolved and documented. Add auto-generated Godot .uid sidecar files for
occlusion_policy.gd and occlusion_policy_test.gd.
2026-04-08 23:55:29 -04:00
VinPropane 5e16fdccc8 NEON-27: restore occluders on all _process early-return paths
Fixes review blocking issue: when the follow target is null (freed,
renamed, or path unresolved) or the Camera3D child is missing,
_restore_all_occluders() is now called before returning so geometry
cannot be left stuck semi-transparent.
2026-04-08 23:50:48 -04:00
VinPropane 15d405261f NEON-27: implement OcclusionPolicy — RayCast-based material fade
Adds OcclusionPolicy resource and wires it into IsometricFollowCamera.
Each _process frame, iterative rays from the camera eye to the player
focus detect bodies tagged "occluder"; their MeshInstance3D surfaces are
overridden with a transparent StandardMaterial3D (fade_alpha=0.25, instant).
Materials restore when the body clears the ray. Null-material surfaces
(e.g. the prototype Obstacle with no material assigned) receive a plain
transparent StandardMaterial3D so they fade correctly.

- client/scripts/occlusion_policy.gd — new Resource (enabled, fade_alpha,
  occluder_group, occluder_collision_mask, max_occluder_cast_depth,
  occluder_count_log_threshold, is_valid)
- client/resources/isometric_occlusion_policy.tres — default instance
- client/scripts/isometric_follow_camera.gd — occlusion_policy export,
  _update_occlusion pipeline, _apply_occluder_fade/_restore_occluder helpers,
  static occlusion_policy_is_valid guard, _exit_tree cleanup
- client/scenes/main.tscn — Obstacle tagged "occluder", policy assigned
- client/test/occlusion_policy_test.gd — new GdUnit4 unit tests
- client/test/isometric_follow_camera_test.gd — policy guard static tests
- docs/decomposition/modules/E1_M2_IsometricCameraController.md — NEON-27
  snapshot + readability demo gate note
- docs/plans/NEON-27-implementation-plan.md — null-material decision recorded
2026-04-08 23:34:00 -04:00
VinPropane cdf9d59bd9 NEON-26: add pre-push GDScript lint hook
Document the repo's enforced GDScript lint rules and add a local pre-push hook so gdlint/gdformat failures are caught before CI.
2026-04-08 23:10:40 -04:00
VinPropane ff830813c7 NEON-26: address code review follow-ups (zoom validation, docs) 2026-04-08 22:58:28 -04:00
VinPropane 753ce84861 NEON-26: ZoomBandConfig, discrete zoom input, CameraState sync 2026-04-08 22:32:45 -04:00
VinPropane 9f6297c46d NEON-25: gdformat isometric_follow_camera.gd 2026-04-08 00:08:00 -04:00
VinPropane 387b61b577 NEON-25: fix gdlint (line length, class-definitions-order) 2026-04-08 00:05:55 -04:00
VinPropane e96f70d889 NEON-25: follow-up from code review (missing target warn, docs, E1.M2 status) 2026-04-07 23:54:27 -04:00
VinPropane 4930fd89a6 NEON-25: isometric follow camera, CameraState, tests, and docs 2026-04-07 23:46:04 -04:00
VinPropane 791c7dad1b
Merge branch 'main' into NS-21-gdscript-unit-testing 2026-04-06 22:22:16 -04:00
VinPropane 8113e48cc8 NS-21: add GdUnit4, client tests, and CI headless run
- Vendor gdUnit4 v6.1.2 under client/addons; enable plugin in project.godot
- Tests: player.gd API, position authority HTTP flow (Node transport double),
  ground_pick walkable ancestry; test double script for injection
- position_authority_client: _create_http_request factory, Node-typed _http,
  emit move_rejected unknown for empty/missing reasonCode strings
- gdscript workflow: lint scripts+test, format check, cache Godot 4.6, GdUnit CLI
- README testing section; gitignore client/reports; testing-expectations Godot harness
2026-04-06 22:08:37 -04:00
VinPropane 72897a4924 NS-24: Fix GDScript lint (line length, gdlint, gdformat)
- Shorten file-header and doc comments to satisfy max-line-length.
- Rename bump collision preload const to BUMP_COLLISION_CONSTS_SCRIPT.
- Refactor idle floor-angle and walk-step logic for return/format rules.
2026-04-06 00:41:32 -04:00
VinPropane 7b11d4e238 NS-24: Eliminate idle jitter and movement QA bumps (Godot client)
Physics: Jolt 3D; physics_interpolation off; 120 TPS. CharacterBody3D idle
path uses dual floor_max_angle, rim/straddle and ridged-contact handling,
rim settle and random-floor-bump lip/wall escape, floor_block_on_wall,
NavigationAgent3D avoidance off, per-node interp off. No global_transform in
_process (avoid render/physics ghosting).

QA geometry: random_floor_bumps.gd (load from main.gd); each bump on its own
StaticBody3D under NavigationRegion3D; random_floor_bump_collision_constants.gd
for collider fudge and RANDOM_FLOOR_BUMP_MESH_GROUP.

Scene: player safe_margin and mesh Y lift; MoveRejectPedestal / MoveRejectFarPad
renamed from NS19*; Mat_player_capsule without polygon_offset (per follow-up).

Docs: NS-24 plan + resolution, client/README manual steps, code review
2026-04-05-NS-24.md; server/README bump height note. Code/scene identifiers
avoid ticket-based ns19_* naming.
2026-04-06 00:32:41 -04:00
VinPropane 8956545d3c NS-23: Document idle skip vs is_on_floor / move_and_slide 2026-04-05 15:02:13 -04:00
VinPropane 8fe70a75de NS-23: Comment DESCEND_GOAL_Y_MARGIN (surface Y vs mid-capsule) 2026-04-05 15:01:29 -04:00
VinPropane 39b4760270 NS-23: Skip move_and_slide when idle on floor (stop rest jitter)
Zero-velocity move_and_slide each physics tick still reapplies floor snap and
collision, which often reads as vibration. If there is no walk goal (or we
just arrived), velocity is zero, and is_on_floor(), return early.
2026-04-05 02:06:06 -04:00
VinPropane 6c73557c3b NS-23: Restore player.gd from e1beb82 (bumps ok, obstacle bee-line)
User-requested rollback to the pre-72eef09 behavior: skip nav waypoints when
auth goal.y is below body (floor pick vs mid-capsule), steering xz straight at
the goal — good for bump departure, bad for gray-box detours. Revert
floor_snap_length to 0.28 to match that snapshot.
2026-04-05 02:02:57 -04:00
VinPropane ee6c4b2718 NS-23: Simplify path-follow — drop bump/step-down heuristics
Restore a straight Godot nav pattern: steer toward get_next_path_position until
finish or final approach, then toward goal; horizontal-only arrival by xz.
Removes footprint rays, bump-step group, and step-off vy layering that fought
the engine. Slightly raise Player floor_snap_length for small ledges.
2026-04-05 02:01:17 -04:00
VinPropane 25d21c0011 NS-23: Remove bump rim velocity unstick (fixes edge vibration)
Per-frame wall-normal + goal boosts fought a flipping wall normal and capped
re-vectoring, causing back-and-forth jitter. Drop _apply_bump_rim_wall_unstick
and related helpers/constants; keep direct step-down + footprint logic only.
STEP_OFF_DESCEND_SPEED 2.2 → 1.75.
2026-04-05 01:58:57 -04:00
VinPropane 430770e5bf NS-23: Rename bump helpers; WALK_BUMP_STEP_GROUP for scene group
Remove ticket-style names from collider/footprint APIs (_collider_in_bump_step_group,
_departing_bump_step_to_lower_floor, touches_bump_step). Editor group string stays
ns19_bump in one const until main.tscn renames the group.
2026-04-05 01:57:36 -04:00
VinPropane 38aa4bfcd5 NS-23: Unstick bump rim — wall peel + goal boost when descending
Convex frustum sides turn goal steering into tangential rim slide with little
net progress. When footprint still hits ns19_bump and dest floor is lower by
at least STEP_OFF_MIN_DROP, add horizontal wall-normal push (if it does not
strongly oppose goal) plus a small goal-direction boost, cap xz speed.
Slightly raise STEP_OFF_DESCEND_SPEED for the step-off branch.
2026-04-05 01:56:56 -04:00
VinPropane 8053f08804 NS-23: Arrival footing uses footprint max_y (avoid false stop on bump lip)
Premature arrival used _floor_y_under_body() vs dest footing; at the rim that
can read floor while xz is already within ARRIVE_EPS, clearing the walk goal.
Match step-down logic: compare destination footing to footprint max_y and
cache footprint scan once per physics frame.
2026-04-05 01:54:42 -04:00
VinPropane 003750c7ae NS-23: Direct step-down while on ns19_bump up to auth horiz limit
Nav paths often wrap along bump rims when the goal is far; the 8 m cap then
disabled step-off and left rim-following. Detect NS-19 bumps via
group on footprint rays; when any hit is a bump and vertical drop is in the
NS-19 band, steer straight to the goal up to 18 m (server max step). Non-bump
podiums keep the 8 m close cap. Single footprint pass returns max_y + bump.
2026-04-05 01:52:04 -04:00
VinPropane f67705f4a3 NS-23: Step-off footing uses capsule footprint max + wider horiz
At bump lips, center/lower rays often hit the floor first while the body is
still on the rim, so drop read ~0 and nav rim-follow resumed. Max floor Y
over center, lower probe, and 8 xz offsets (cardinal + diagonal) keeps
step-down bypass active until the whole footprint clears. Raise
STEP_OFF_MAX_HORIZ to 8 m (still capped by small drop band).
2026-04-05 01:48:55 -04:00
VinPropane b1ce87c5cc NS-23: Revert global gravity; use step-off-only descend vy
Project gravity while walking made motion worse (jitter, floor fights).
Restore horizontal-only seek everywhere except the short step-down bypass,
where a fixed downward speed helps clear NS-19 bump lips without affecting
normal nav or idle air state.
2026-04-05 01:46:08 -04:00
VinPropane 127e67f02b NS-23: Apply gravity when airborne so bump ledges are not sticky
Horizontal seek only sets vx/vz; zero vy only on floor. Use project default
gravity vector when not on floor (with and without walk goal) so stepping
off NS-19 bumps can fall to the lower surface instead of hanging with vy=0.
2026-04-05 01:43:56 -04:00
VinPropane 3b4340830a NS-23: Fix bump depart — goal Y vs surface footing + arrive by footing
- Ray down at goal xz for destination surface Y; step-off compares two footings.
- Arrive when horiz close and either capsule Y matches goal or underfoot matches
  dest footing (server may send center 0.9 or pick surface 0).
2026-04-05 01:39:45 -04:00
VinPropane dbae80627f NS-23: Tighten bump step-off bypass (dual floor ray, drop band, horiz cap)
- Sample floor Y from center and lower probe; use max for bump rim.
- Only bypass nav for step-sized vertical drop with wider near-goal horiz.
- Loosen next-waypoint stickiness so rim waypoints fall back to goal sooner.
2026-04-05 01:36:32 -04:00
VinPropane 8b2b64a326 NS-23: bump step-off bypass using floor-under-feet, not body Y
Ray down for floor Y under the capsule; skip nav only when goal is a bit
lower than that surface, drop ≤0.55 m, and horiz ≤1.05 m. Matches
leaving a bump without comparing pick/body origin (which broke obstacle
pathing). Long crosses still use waypoints.
2026-04-05 01:33:57 -04:00
VinPropane 72eef09d15 NS-23: remove descend nav skip — restored obstacle pathing
goal.y < body.y matched almost every move because ray picks use floor Y
while CharacterBody3D origin is mid-capsule, so we always bee-lined and
ignored waypoints. Rely on small-xz next-waypoint fallback for bump rims
instead.
2026-04-05 01:32:02 -04:00
VinPropane e1beb82a75 NS-23: unstuck bump top — descend steers xz to goal; doc abs(dy)
Server already allows downward steps via abs(ΔY) vs MaxVerticalStep; document
that explicitly.

Client: when authoritative goal Y is below the body, skip nav waypoints and
steer horizontally toward the goal only — mesh waypoints under the rim
gave ~no horizontal speed (felt like wrong collision).
2026-04-05 01:29:31 -04:00
VinPropane b8176f8fa1 NS-23: simplify client movement — horizontal only, no bump nav hacks
Replace stacked NS-19 workarounds (underfoot rays, plateau nav skip, 3D
climb/descent steering, rim escape) with one rule: set horizontal
velocity toward waypoint/goal, force velocity.y = 0, move_and_slide +
floor_* handle height along geometry. Server MoveCommand remains the
single place for allow/deny on illegal steps.
2026-04-05 01:26:59 -04:00
VinPropane fba2c8e171 NS-19: large bump — wider underfoot rays + shallower frustum
- Add xz-offset down-rays (~0.42 m) so rim/lean on the 1 m Bump A still
  counts as on-bump for nav skip (single center column could miss).
- Widen Bump A convex base 0.65→0.72 (top 0.5 unchanged): gentler ~34°
  sides vs ~45° to reduce CharacterBody3D snags; mesh unchanged.
2026-04-05 01:19:28 -04:00
VinPropane 35d16d15db NS-23: harden bump departure (always skip nav on bump, steer dy<0)
- If any of three down-rays (body + two lower origins) hits ns19_bump,
  skip NavigationAgent waypoints unconditionally on that footprint.
- Steering: any goal lower than origin with same xz (dy < 0) uses rim
  escape; dy in (-0.04, 0) previously zeroed velocity and could hang.
2026-04-05 01:16:07 -04:00
VinPropane 66d7438a59 NS-23: broaden NS-19 bump nav bypass for departure
Plateau-only (strict flat normal + is_on_floor) missed rim poses and
convex top edges. Skip waypoints when a down ray from body or feet
offset hits ns19_bump and either the goal is lower than the body origin
(typical floor click off bump) or we are on a flatter floor normal
(~15°). Keeps waypoint routing on bump slopes when climbing past
obstacles unless the move is clearly downward.
2026-04-05 01:14:19 -04:00
VinPropane db1fe0f46b NS-23: skip nav waypoints on NS-19 bump plateaus only
Restore obstacle routing via waypoints elsewhere; on bump tops nav often
prefers a downward segment and breaks departure. Detect plateau with
is_on_floor + flat normal + ray down into group ns19_bump; then steer
only toward authoritative goal xz. Slopes keep waypoint pathing.
2026-04-05 01:12:11 -04:00
VinPropane a5ec8df4a7 NS-23: terminal collision, nav around obstacle, agent under region
- Add BoxShape3D to PrototypeTerminal (layer 1, walkable) so the player
  cannot pass through; matches terminal mesh size.
- Bake navigation from collision layer 1 only so the player (layer 2) is
  not merged into the mesh; reparent Player under NavigationRegion3D so
  NavigationAgent3D resolves a valid map.
- Restore nav waypoint following for long horizontal legs; keep horizontal
  steering toward next/goal so bump departure behavior stays sane.
2026-04-05 01:10:16 -04:00
VinPropane 05d7916cc7 NS-23: fix bump departure — stepped pick + goal-only steer
Ground pick: step the ray through steep walkable hits (0.09 < dot UP < 0.64)
so a view that grazes bump sides still resolves to flat floor beyond; walls
(dot ~0) stop the chain.

Player: drop NavigationAgent3D waypoint following; steer only toward the
server goal in xz so plateau paths are not dominated by vertical nav
segments. move_and_slide handles slopes and obstacles.
2026-04-05 01:07:02 -04:00
VinPropane 725bef1133 NS-23: allow ground pick on bump slopes (fix stuck departure)
MIN_WALKABLE_NORMAL_DOT_UP 0.82 is stricter than NS-19 frustum slopes
(~45° / dot 0.71 on Bump A, ~39° / 0.78 on B). Clicks off the plateau
often hit the slope first; the pick was dropped with no MoveCommand.
Lower to 0.64 so ramps register; vertical walls remain ~0.
2026-04-05 01:03:51 -04:00
VinPropane 4b9e30c624 NS-23: fix false arrival when leaving bump tops
VERT_ARRIVE_EPS (0.16) was larger than the bump rise (~0.12–0.15), so a
floor click beside the plateau often satisfied arrival (horiz + vert) on
the first frame and cleared the walk goal before any motion.

Tighten vertical arrival to 0.055. Add a steer fallback when the target
shares xz but is lower (plateau vs floor underfoot) so we still pick a
horizontal escape toward the rim.
2026-04-05 01:01:22 -04:00
VinPropane 7ffcf54d80 NS-23: horizontal nav steering so bump-top departure works
Path waypoints from the plateau often sit on the slope almost under the
player (same xz, lower y). 3D steer + y clamp gave almost no horizontal
velocity, so standing on top then clicking off looked stuck. Steer in xz
at MOVE_SPEED and let move_and_slide follow floor/slope; keep 3D only for
vertical climb when xz is aligned.
2026-04-05 00:58:10 -04:00