From a5e2318a32b160eb6e285b98a5d3f0ed074f07a9 Mon Sep 17 00:00:00 2001 From: chazmm Date: Tue, 8 Sep 2026 17:47:44 +0100 Subject: [PATCH] Connect Ground wall-jump trajectory and capture handplant pose diagnostics --- crates/skate-game/src/physics/ground_phase.rs | 8 +++- .../src/physics/ground_runtime/launch.rs | 38 +++++++++++++++++++ crates/skate-game/src/physics/handplant.rs | 16 +++++++- docs/plants.md | 14 +++++++ 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/crates/skate-game/src/physics/ground_phase.rs b/crates/skate-game/src/physics/ground_phase.rs index 047440b4..5ab412ea 100644 --- a/crates/skate-game/src/physics/ground_phase.rs +++ b/crates/skate-game/src/physics/ground_phase.rs @@ -165,6 +165,7 @@ pub(crate) fn advance( skater: &mut SkaterRuntime, ) -> Result { super::handplant::ground_query(physics,skater); + let selector_input = super::air_phase::selector_input(physics, skater)?; let p = &skater.player_input.processed; let toolkit = skater .player_input @@ -197,8 +198,11 @@ pub(crate) fn advance( Ok(()) }; let mut launch = |info: &GroundLaunchInfo| { - life.pending_wall_jump = Some(info.clone()); - Err("Ground selected wall jump; its retained launch requires TrajectorySelector::Launch/Update".into()) + let mut input = selector_input; + input.board_vertical_velocity = info.velocity[1]; + skater.trajectory.launch(info.selector_launch(), input, &physics.world)?; + skater.trajectory.update(input, &physics.world)?; + Ok(()) }; let physical = GroundPhysicalFrame { skeleton_record: &skater.animated_skeleton.record, diff --git a/crates/skate-game/src/physics/ground_runtime/launch.rs b/crates/skate-game/src/physics/ground_runtime/launch.rs index 5a620f60..6b93c51f 100644 --- a/crates/skate-game/src/physics/ground_runtime/launch.rs +++ b/crates/skate-game/src/physics/ground_runtime/launch.rs @@ -60,6 +60,21 @@ pub(crate) struct GroundLaunchPhysical<'a> { pub time_step: f32, } impl GroundLaunchInfo { + ///The retained Ground packet and the shared selector packet have the same + ///82D33448 layout. Preserve both velocities and all override flags. + pub fn selector_launch(&self) -> skate_core::air::trajectory::LaunchInfo { + skate_core::air::trajectory::LaunchInfo { + reckoning_transform:self.system, reckoning_inverse:self.inverse_system, + start_velocity:self.velocity, com_velocity:self.angular_velocity, + skeleton_vector_160:self.skeleton_vector_16208, + skeleton_vector_176:self.skeleton_vector_16240, + board_position:self.board_position, animation_com_position:self.physical_center_of_mass, + start_position_override:self.vector_224, board_position_override:self.vector_240, + cone_angle_x:self.cone_angle_x, cone_angle_z:self.cone_angle_z, + timestep:self.time_step, player_jumped:self.wall_jump, + use_position_override:self.flag_269, trajectory_count:self.flags_270, + } + } pub fn fill(&mut self, p: &GroundLaunchPhysical<'_>, cone_angle_x: f32, cone_angle_z: f32) { self.board_position = p.board_position; self.physical_center_of_mass = p.physical_center_of_mass; @@ -81,3 +96,26 @@ impl GroundLaunchInfo { self.wall_jump = true; } } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn wall_jump_selector_receives_launch_velocity_and_physical_anchors() { + let mut info = GroundLaunchInfo { board_position:[1.0,2.0,3.0,0.0], + physical_center_of_mass:[1.2,3.0,3.1,0.0], + skeleton_vector_16208:[0.2,0.8,0.1,0.0], flags_270:7, + time_step:1.0/60.0, ..Default::default() }; + let velocity=[2.0,4.0,-3.0,0.0]; + info.wall_jump(velocity); + let launch=info.selector_launch(); + assert!(launch.player_jumped); + assert!(!launch.use_position_override); + assert_eq!(launch.start_velocity,velocity); + assert_eq!(launch.com_velocity,velocity); + assert_eq!(launch.board_position,info.board_position); + assert_eq!(launch.animation_com_position,info.physical_center_of_mass); + assert_eq!(launch.skeleton_vector_160,info.skeleton_vector_16208); + assert_eq!(launch.trajectory_count,7); + } +} diff --git a/crates/skate-game/src/physics/handplant.rs b/crates/skate-game/src/physics/handplant.rs index abcb81ab..ac2b3b11 100644 --- a/crates/skate-game/src/physics/handplant.rs +++ b/crates/skate-game/src/physics/handplant.rs @@ -275,5 +275,19 @@ pub(super) fn update(physics: &mut GamePhysics, skater: &mut SkaterRuntime) -> R heading, ); ik::update(skater, false); - plant_skeleton::advance(physics, skater, com, None) + plant_skeleton::advance(physics, skater, com, None)?; + if physics.ticks % 6 == 0 || skater.handplant.elapsed <= STEP * 1.5 { + let root = &skater.animated_skeleton.roots.animation_to_world; + let parts = [23, 1, 3, 7, 15, 19]; //hips, head, hands, toes + let targets = parts.map(|i| point(root, skater.skeleton_input.drive_frames[i][3])); + let actual = skater.skeleton.part_transforms(); + let actual = parts.map(|i| actual[i][3]); + let hands = [2, 3].map(|i| (skater.foot_ik.state.external_targets[i].world_position, + skater.foot_ik.state.limbs[i].target_blend)); + bevy::log::info!("HANDPLANT_POSE tick={} elapsed={} phase={} com={com:?} up={up:?} heading={heading:?} root={root:?} targets={targets:?} actual={actual:?} hands={hands:?} force_mode={} flags={:08x}/{:08x}/{:08x}", + physics.ticks, skater.handplant.elapsed, skater.handplant.phase, + skater.skeleton_input.force_mode, skater.player_input.processed.flags_2468, + skater.player_input.processed.flags_2472, skater.player_input.processed.flags_2476); + } + Ok(()) } diff --git a/docs/plants.md b/docs/plants.md index 54a5224d..75172e8d 100644 --- a/docs/plants.md +++ b/docs/plants.md @@ -177,3 +177,17 @@ No gameplay execution was performed during this repair. Validation for this repair: six core wipeout tests and two revert numerical tests passed. Two pre-existing game test fixtures were updated for their current map-menu and render-material API signatures so these tests could compile. + +## Folded-pose report and wall-jump exit (8 September, later run) + +Log plants-20260908-174254-418-287 entered HandPlant at tick581, returned to +PhysicsGround at603 and stopped at605 in Ground's wall-jump callback. That +callback was still an explicit error stub. It now converts the complete retained +launch packet to the existing trajectory selector and executes Launch/Update, +including the wall-jump velocity in both native velocity fields. A focused packet +transfer test passes. No gameplay was executed to validate the result. + +The user's folded-body report remains unresolved. HANDPLANT_POSE now records +COM/orientation, root transform, target versus physical hips/head/hands/toes and +external hand targets at entry and every six ticks. This distinguishes pose/IK +errors from physical tracking errors on the next user-provided reproduction.