mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
sync - introduceconcept of a rewind_tick
This commit is contained in:
parent
4343dd3aea
commit
820b3f06b0
@ -39,7 +39,7 @@ use common::{
|
|||||||
mounting::Rider,
|
mounting::Rider,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
recipe::{ComponentRecipeBook, RecipeBook},
|
recipe::{ComponentRecipeBook, RecipeBook},
|
||||||
resources::{DeltaTime, GameMode, MonotonicTime, PlayerEntity, Time, TimeOfDay},
|
resources::{MonotonicTime, GameMode, PlayerEntity, Time, TimeOfDay},
|
||||||
spiral::Spiral2d,
|
spiral::Spiral2d,
|
||||||
terrain::{
|
terrain::{
|
||||||
block::Block, map::MapConfig, neighbors, site::DungeonKindMeta, BiomeKind,
|
block::Block, map::MapConfig, neighbors, site::DungeonKindMeta, BiomeKind,
|
||||||
@ -64,7 +64,7 @@ use common_net::{
|
|||||||
sync::WorldSyncExt,
|
sync::WorldSyncExt,
|
||||||
};
|
};
|
||||||
use common_state::State;
|
use common_state::State;
|
||||||
use common_systems::add_local_systems;
|
use common_systems::{add_local_systems, add_rewind_systems};
|
||||||
use comp::BuffKind;
|
use comp::BuffKind;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use image::DynamicImage;
|
use image::DynamicImage;
|
||||||
@ -237,6 +237,7 @@ pub struct Client {
|
|||||||
|
|
||||||
local_command_gen: CommandGenerator,
|
local_command_gen: CommandGenerator,
|
||||||
next_control: Controller,
|
next_control: Controller,
|
||||||
|
inter_tick_rewind_time: Option<Duration>,
|
||||||
|
|
||||||
network: Option<Network>,
|
network: Option<Network>,
|
||||||
participant: Option<Participant>,
|
participant: Option<Participant>,
|
||||||
@ -721,6 +722,7 @@ impl Client {
|
|||||||
|
|
||||||
local_command_gen: CommandGenerator::default(),
|
local_command_gen: CommandGenerator::default(),
|
||||||
next_control: Controller::default(),
|
next_control: Controller::default(),
|
||||||
|
inter_tick_rewind_time: None,
|
||||||
|
|
||||||
network: Some(network),
|
network: Some(network),
|
||||||
participant: Some(participant),
|
participant: Some(participant),
|
||||||
@ -1699,6 +1701,7 @@ impl Client {
|
|||||||
|
|
||||||
// 1) Build up a list of events for this frame, to be passed to the frontend.
|
// 1) Build up a list of events for this frame, to be passed to the frontend.
|
||||||
let mut frontend_events = Vec::new();
|
let mut frontend_events = Vec::new();
|
||||||
|
self.inter_tick_rewind_time = None;
|
||||||
|
|
||||||
// Prepare for new events
|
// Prepare for new events
|
||||||
{
|
{
|
||||||
@ -1728,6 +1731,36 @@ impl Client {
|
|||||||
// Handle new messages from the server.
|
// Handle new messages from the server.
|
||||||
frontend_events.append(&mut self.handle_new_messages()?);
|
frontend_events.append(&mut self.handle_new_messages()?);
|
||||||
|
|
||||||
|
// Simulate Ahead
|
||||||
|
if let Some(_rewind_time) = self.inter_tick_rewind_time {
|
||||||
|
let _time = self.state.ecs().read_resource::<Time>().0 as f64;
|
||||||
|
let simulate_ahead = self
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<RemoteController>()
|
||||||
|
.get(self.entity())
|
||||||
|
.map(|rc| rc.simulate_ahead())
|
||||||
|
.unwrap_or_default();
|
||||||
|
let simulate_ahead = simulate_ahead.max(dt) - dt;
|
||||||
|
tracing::warn!(?simulate_ahead, ?dt, "simulating ahead again");
|
||||||
|
self.state.rewind_tick(
|
||||||
|
simulate_ahead.max(dt) - dt,
|
||||||
|
|dispatch_builder| {
|
||||||
|
add_rewind_systems(dispatch_builder);
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state.tick(
|
||||||
|
dt,
|
||||||
|
|dispatch_builder| {
|
||||||
|
add_local_systems(dispatch_builder);
|
||||||
|
add_foreign_systems(dispatch_builder);
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
// 2) Handle input from frontend.
|
// 2) Handle input from frontend.
|
||||||
// Pass character actions from frontend input to the player's entity.
|
// Pass character actions from frontend input to the player's entity.
|
||||||
if self.presence.is_some() {
|
if self.presence.is_some() {
|
||||||
@ -2158,17 +2191,17 @@ impl Client {
|
|||||||
prof_span!("handle_server_in_game_msg");
|
prof_span!("handle_server_in_game_msg");
|
||||||
match msg {
|
match msg {
|
||||||
ServerGeneral::TimeSync(time) => {
|
ServerGeneral::TimeSync(time) => {
|
||||||
let dt = self.state.ecs().read_resource::<DeltaTime>().0 as f64;
|
let old_time = self.state.ecs().read_resource::<Time>().0;
|
||||||
let simulate_ahead = self
|
let diff = old_time - time.0;
|
||||||
.state
|
self.state.ecs().write_resource::<Time>().0 = time.0;
|
||||||
.ecs()
|
if diff > 0.0 {
|
||||||
.read_storage::<RemoteController>()
|
tracing::warn!(?old_time, ?diff, "Time was reverted by server");
|
||||||
.get(self.entity())
|
let rewind_time = self.inter_tick_rewind_time.unwrap_or_default()
|
||||||
.map(|rc| rc.simulate_ahead())
|
+ Duration::from_secs_f64(diff);
|
||||||
.unwrap_or_default();
|
self.inter_tick_rewind_time = Some(rewind_time);
|
||||||
//remove dt as it is applied in state.tick again
|
} else {
|
||||||
self.state.ecs().write_resource::<Time>().0 =
|
tracing::warn!(?old_time, ?diff, "Time was advanced by server");
|
||||||
time.0 + simulate_ahead.as_secs_f64() - dt;
|
}
|
||||||
},
|
},
|
||||||
ServerGeneral::AckControl(acked_ids, _time) => {
|
ServerGeneral::AckControl(acked_ids, _time) => {
|
||||||
if let Some(remote_controller) = self
|
if let Some(remote_controller) = self
|
||||||
|
@ -590,6 +590,28 @@ impl State {
|
|||||||
self.ecs.write_resource::<TerrainChanges>().modified_blocks = modified_blocks;
|
self.ecs.write_resource::<TerrainChanges>().modified_blocks = modified_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rewind local changes after the server send some old state
|
||||||
|
pub fn rewind_tick(
|
||||||
|
&mut self,
|
||||||
|
simulate_ahead: Duration,
|
||||||
|
add_systems: impl Fn(&mut DispatcherBuilder),
|
||||||
|
update_terrain_and_regions: bool,
|
||||||
|
) {
|
||||||
|
let time_of_day = self.ecs.read_resource::<TimeOfDay>().0;
|
||||||
|
let _time = self.ecs.read_resource::<Time>().0;
|
||||||
|
let monotonic_time = self.ecs.read_resource::<MonotonicTime>().0;
|
||||||
|
let delta_time = self.ecs.read_resource::<DeltaTime>().0;
|
||||||
|
|
||||||
|
self.tick(simulate_ahead, add_systems, update_terrain_and_regions);
|
||||||
|
|
||||||
|
// rewind changes
|
||||||
|
|
||||||
|
self.ecs.write_resource::<TimeOfDay>().0 = time_of_day;
|
||||||
|
//self.ecs.write_resource::<Time>().0 = time;
|
||||||
|
self.ecs.write_resource::<MonotonicTime>().0 = monotonic_time;
|
||||||
|
self.ecs.write_resource::<DeltaTime>().0 = delta_time;
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute a single tick, simulating the game state by the given duration.
|
/// Execute a single tick, simulating the game state by the given duration.
|
||||||
pub fn tick(
|
pub fn tick(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -39,3 +39,23 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
|||||||
dispatch::<beam::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
|
dispatch::<beam::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
|
||||||
dispatch::<aura::Sys>(dispatch_builder, &[]);
|
dispatch::<aura::Sys>(dispatch_builder, &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_rewind_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||||
|
//TODO: don't run interpolation on server
|
||||||
|
dispatch::<interpolation::Sys>(dispatch_builder, &[]);
|
||||||
|
dispatch::<mount::Sys>(dispatch_builder, &[]);
|
||||||
|
dispatch::<controller::Sys>(dispatch_builder, &[&mount::Sys::sys_name()]);
|
||||||
|
dispatch::<character_behavior::Sys>(dispatch_builder, &[&controller::Sys::sys_name()]);
|
||||||
|
dispatch::<buff::Sys>(dispatch_builder, &[]);
|
||||||
|
dispatch::<stats::Sys>(dispatch_builder, &[&buff::Sys::sys_name()]);
|
||||||
|
dispatch::<phys::Sys>(dispatch_builder, &[
|
||||||
|
&interpolation::Sys::sys_name(),
|
||||||
|
&controller::Sys::sys_name(),
|
||||||
|
&mount::Sys::sys_name(),
|
||||||
|
&stats::Sys::sys_name(),
|
||||||
|
]);
|
||||||
|
dispatch::<projectile::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
|
||||||
|
dispatch::<shockwave::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
|
||||||
|
dispatch::<beam::Sys>(dispatch_builder, &[&phys::Sys::sys_name()]);
|
||||||
|
dispatch::<aura::Sys>(dispatch_builder, &[]);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user