From 90fa20b5a97fffd3f5f3bb6c9d8c6586d2ec9692 Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Fri, 12 Jun 2026 16:07:56 -0500 Subject: [PATCH] netcode: interpolation is less dumb and stupid; also some ntp left over just in case --- crates/unified/assets/config/world.wc.toml | 2 +- crates/unified/src/client/components/mod.rs | 13 ++++ crates/unified/src/client/interpolation.rs | 68 +++++++++++++++---- crates/unified/src/client/mod.rs | 19 ++++-- crates/unified/src/client/parts.rs | 6 +- .../src/client/planet/incoming_planets.rs | 6 +- crates/unified/src/client/server_clock.rs | 67 ++++++++++++++++++ crates/unified/src/server/client_timing.rs | 28 ++++++++ crates/unified/src/server/mod.rs | 3 + crates/unified/src/server/orbit/mod.rs | 4 +- crates/unified/src/server/player/join.rs | 5 ++ crates/unified/src/shared/ecs.rs | 4 +- crates/unified/src/shared/ecs/clock_sync.rs | 14 ++++ crates/unified/src/shared/net.rs | 4 ++ crates/unified/src/shared/plugins.rs | 3 +- 15 files changed, 208 insertions(+), 38 deletions(-) create mode 100644 crates/unified/src/client/server_clock.rs create mode 100644 crates/unified/src/server/client_timing.rs create mode 100644 crates/unified/src/shared/ecs/clock_sync.rs diff --git a/crates/unified/assets/config/world.wc.toml b/crates/unified/assets/config/world.wc.toml index f4711b8c546b7dc2d210d4f88d9b9c388ceb0f5c..5c7798d842fd39ee656a7a74a028c168fb41e8d4 100644 --- a/crates/unified/assets/config/world.wc.toml +++ b/crates/unified/assets/config/world.wc.toml @@ -3,7 +3,7 @@ gravity = 500.0 gravity_iterations = 8 spawn_parts_at = "Earth" -spawn_parts_interval_secs = 1 +spawn_parts_interval_secs = 1000 orbit_scale_factor = 4.0 [part] diff --git a/crates/unified/src/client/components/mod.rs b/crates/unified/src/client/components/mod.rs index 7d6c4d8bbd814a3a9076b04c6f58506ba82e97b8..cc51c903b073312b29aa3bf84629a283a3c44496 100644 --- a/crates/unified/src/client/components/mod.rs +++ b/crates/unified/src/client/components/mod.rs @@ -1,3 +1,5 @@ +use std::collections::VecDeque; +use bevy::prelude::{Deref, DerefMut}; use crate::prelude::{Component, Resource}; #[derive(Component)] @@ -11,3 +13,14 @@ pub struct PowerText; #[derive(Component)] pub struct Me; + +#[derive(Resource, Default)] +pub struct ServerClock { + pub rtt_queue: VecDeque, + pub rtt: f64, + pub time_offset_queue: VecDeque, + pub time_offset: f64, +} + +#[derive(Resource, Default, Deref, DerefMut)] +pub struct ServerTimeOffset(f64); \ No newline at end of file diff --git a/crates/unified/src/client/interpolation.rs b/crates/unified/src/client/interpolation.rs index 4809501c94fc15d008e636346aabaf1077d3a7aa..11359cb1edd8168dbce60ae86aa46b7c4f12b11c 100644 --- a/crates/unified/src/client/interpolation.rs +++ b/crates/unified/src/client/interpolation.rs @@ -1,7 +1,14 @@ +use std::collections::VecDeque; use std::f32::consts::PI; use std::time::{Duration}; use avian2d::parry::transformation::utils::transform; +use bevy_replicon::client::confirm_history::ConfirmHistory; +use crate::client::components::{ServerClock, ServerTimeOffset}; use crate::prelude::*; +use crate::shared::plugins::TICK_RATE; + +/// interpolation period in seconds +const INTERP: f64 = 0.150; pub fn interpolation_plugin(app: &mut App) { app @@ -12,10 +19,7 @@ pub fn interpolation_plugin(app: &mut App) { #[derive(Component, Debug)] pub struct TranslationInterpolationInfo { - pub last_dt: Duration, - pub this_tick_start: bevy::platform::time::Instant, - pub latest_position: Vec2, - pub last_position: Vec2, + pub positions: VecDeque<(f64, Vec2)>, } #[derive(Component, Debug)] pub struct RotationInterpolationInfo { @@ -27,14 +31,30 @@ pub struct RotationInterpolationInfo { } fn update_interpolation_info( - mut interpolation_pos_query: Query<(Entity, &Position, &mut TranslationInterpolationInfo), Changed>, + mut interpolation_pos_query: Query<(Entity, &Position, &mut TranslationInterpolationInfo, &ConfirmHistory), Changed>, mut interpolation_rot_query: Query<(&Rotation, &AngularVelocity, &mut RotationInterpolationInfo), Changed>, + server_clock: Res, + server_time_offset: Res, ) { - for (entity, position, mut info) in interpolation_pos_query.iter_mut() { - info.last_dt = info.this_tick_start.elapsed(); - info.this_tick_start = bevy::platform::time::Instant::now(); - info.last_position = info.latest_position; - info.latest_position = position.as_vec2(); + for (entity, position, mut info, confirm_history) in interpolation_pos_query.iter_mut() { + let now = confirm_history.last_tick().get() as f64 / TICK_RATE - **server_time_offset/* - server_clock.rtt/2.0 - server_clock.time_offset*/; + //let now = confirm_history.last_tick().get() as f32 / TICK_RATE as f32; + info.positions.push_back((now, position.as_vec2())); + let mut last_over_time = 0; + for (i, (time, _)) in info.positions.iter().enumerate() { + if *time < now - INTERP { + last_over_time = i; + } + } + if last_over_time > 0 { + //debug!("pop"); + info.positions.drain(..last_over_time); + } + //debug!("{:?}", info.positions) + /*if let Some((time, _)) = info.positions.get(0) && now.duration_since(*time) > INTERP { + debug!("pop"); + pos_info.positions.pop_front(); + }*/ } for (rotation, angular_velocity, mut info) in interpolation_rot_query.iter_mut() { info.last_dt = info.this_tick_start.elapsed(); @@ -62,12 +82,30 @@ fn sync_non_interpolated_transforms( } } fn do_interpolation( - mut interpolation_query: Query<(Entity, &mut Transform, &TranslationInterpolationInfo, &RotationInterpolationInfo)>, + mut interpolation_query: Query<(Entity, &mut Transform, &mut TranslationInterpolationInfo, &RotationInterpolationInfo)>, + time: Res