Files
settled-reach/client/scenes/locomotion_sandbox.tscn
T
jpmschweitzerandClaude Fable 5 a7801a942a feat(client): 3D locomotion sandbox — character walks the live Gauntlet (T-1088)
New SR_LIVE sandbox scene: CharacterVisual composited in a 3D greybox world
derived from server snapshots. Per-leg constant-velocity interpolation keyed
to the stance throttle, 'server feet / client eyes' facing (wire octant while
moving, client aim octant idle), cadence-synced gait state machine on
AnimationPlayer custom blends, D-148 orthographic follow camera (-30deg
default, T-cycle presets), sim-space grid shader, camera-side wall cutaway,
accumulating never-evict tile store with four-state visibility tint.

Additive seams only: InputMapper.facing_angle_provider (2D path unchanged),
CharacterVisual.play_animation blend_time param + get_animation_player().
Visual harness gains per-scenario scene field + SR_AUTOPILOT input scripting.
210 new gdUnit assertions across five suites; verified live (230/230 total,
clean smoke, screenshot at .cache/screenshots/locomotion_idle_live.png).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:23:16 +02:00

82 lines
3.8 KiB
Plaintext

[gd_scene load_steps=7 format=3 uid="uid://c61sb2euagj4o"]
[ext_resource type="Script" path="res://scripts/sandbox/locomotion_sandbox.gd" id="1_sandbox"]
[ext_resource type="Script" path="res://scripts/sandbox/sandbox_debug_hud.gd" id="2_debughud"]
[ext_resource type="Script" path="res://scripts/sandbox/greybox_world.gd" id="3_greybox"]
[ext_resource type="Script" path="res://scripts/sandbox/locomotion_rig.gd" id="4_rig"]
[ext_resource type="Script" path="res://scripts/sandbox/follow_camera_3d.gd" id="5_followcam"]
; T-1088: 3D locomotion sandbox — live-server-driven CharacterVisual walking the
; Gauntlet greybox. Scene tree per the T-1088 design §1.2. Launch:
; T1: cd server && cargo run --bin settled-reach-server -- --test-mode
; T2: SR_LIVE=1 ~/bin/godot4 --path client res://scenes/locomotion_sandbox.tscn
; Lights + environment follow the character_creation.tscn:65-92 recipe (the toon +
; inverted-hull outline shaders need lights and a WorldEnvironment in-scene).
[sub_resource type="Environment" id="Environment_1"]
background_mode = 1
background_color = Color(0.03, 0.03, 0.06, 1)
ambient_light_source = 2
ambient_light_color = Color(0.4, 0.45, 0.55, 1)
ambient_light_energy = 0.5
[node name="LocomotionSandbox" type="Node3D"]
script = ExtResource("1_sandbox")
; D-148: THE single static map rotation — 45° yaw (0.785398 rad), set once here.
; Sim coords stay axis-aligned inside WorldRoot; the camera never rotates.
[node name="WorldRoot" type="Node3D" parent="."]
rotation = Vector3(0, 0.785398, 0)
; greybox_world.gd — accumulating tile store + MultiMesh painter (design §3, §8).
; Builds its FloorMM/WallMM MultiMeshInstance3D children in _ready().
[node name="Greybox" type="Node3D" parent="WorldRoot"]
script = ExtResource("3_greybox")
; locomotion_rig.gd — local position = interpolated sim position (metres).
; Hidden until the first-snapshot latch (locomotion_sandbox.gd); the root installs
; the provider Callables and feeds set_wire_target() per consumed snapshot.
[node name="PlayerRig" type="Node3D" parent="WorldRoot"]
visible = false
script = ExtResource("4_rig")
; ModelRoot.rotation.y = smoothed facing yaw (D-151), in WorldRoot-LOCAL space so
; octant→yaw composes with the map rotation exactly once. CharacterVisual is
; runtime-instantiated under it; its own rotation.y stays 0.
[node name="ModelRoot" type="Node3D" parent="WorldRoot/PlayerRig"]
; follow_camera_3d.gd — D-148 pivot-orbit rig, D-015 locked follow. The Camera3D
; placeholder child is adopted in _ready() and every property is rewritten from
; SandboxConstants, so the values below are editor preview only and cannot drift.
[node name="CameraRig" type="Node3D" parent="." node_paths=PackedStringArray("follow_target")]
script = ExtResource("5_followcam")
follow_target = NodePath("../WorldRoot/PlayerRig")
; Initial pose: gameplay default preset (-30° pitch from horizontal, CAM_DIST 30,
; ortho size 9 — SandboxConstants). Yaw 0, always: the diamond view is WorldRoot's 45°.
[node name="Camera3D" type="Camera3D" parent="CameraRig"]
position = Vector3(0, 15, 25.9808)
rotation = Vector3(-0.523599, 0, 0)
projection = 1
current = true
size = 9.0
near = 0.1
far = 100.0
; Key light: upper-left-front (character_creation.tscn recipe)
[node name="KeyLight" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.866, -0.354, 0.354, 0, 0.707, 0.707, -0.5, -0.612, 0.612, 2, 3, 2)
light_energy = 1.2
shadow_enabled = true
; Fill light: right side, softer, no shadows
[node name="FillLight" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.866, -0.259, -0.428, 0, 0.856, -0.517, 0.5, 0.448, 0.741, -2, 2, -1)
light_energy = 0.4
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_1")
[node name="DebugHud" type="CanvasLayer" parent="."]
script = ExtResource("2_debughud")