Skip to content

Commit

Permalink
Merge pull request #8 from Bendzae/replicon-0.25.2
Browse files Browse the repository at this point in the history
Upgrade to Replicon 0.25.3
  • Loading branch information
Bendzae authored May 25, 2024
2 parents 7e4afcd + 6f64bbf commit 0ae1308
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 229 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ description = "High-level networking crate that extends the bevy_replicon crate
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = { version = "0.13.1", default_features = false }
bevy_replicon = "0.24.1"
bevy_replicon_renet = "0.1.0"
bevy = { version = "0.13", default_features = false }
bevy_replicon = "0.25.3"
bevy_replicon_renet = "0.2.0"
serde = "1.0"

bevy_replicon_snap_macros = { version = "0.2.0", path = "macros" }
Expand Down
6 changes: 3 additions & 3 deletions examples/interpolated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use bevy_replicon_renet::{
RenetChannelsExt, RepliconRenetPlugins,
};
use bevy_replicon_snap::{
AppInterpolationExt, Interpolated, NetworkOwner, SnapshotInterpolationPlugin,
interpolation::Interpolated, AppInterpolationExt, NetworkOwner, SnapshotInterpolationPlugin,
};
use bevy_replicon_snap_macros::Interpolate;
use clap::Parser;
Expand Down Expand Up @@ -274,7 +274,7 @@ struct PlayerBundle {
owner: NetworkOwner,
position: PlayerPosition,
color: PlayerColor,
replication: Replication,
replicated: Replicated,
interpolated: Interpolated,
}

Expand All @@ -284,7 +284,7 @@ impl PlayerBundle {
owner: NetworkOwner(id.get()),
position: PlayerPosition(position),
color: PlayerColor(color),
replication: Replication,
replicated: Replicated,
interpolated: Interpolated,
}
}
Expand Down
4 changes: 2 additions & 2 deletions examples/no_interpolation_or_prediction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ struct PlayerBundle {
player: Player,
position: PlayerPosition,
color: PlayerColor,
replication: Replication,
replicated: Replicated,
}

impl PlayerBundle {
Expand All @@ -278,7 +278,7 @@ impl PlayerBundle {
player: Player(client_id),
position: PlayerPosition(position),
color: PlayerColor(color),
replication: Replication,
replicated: Replicated,
}
}
}
Expand Down
28 changes: 18 additions & 10 deletions examples/owner_predicted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ use std::{
time::SystemTime,
};

use bevy::{prelude::*, winit::WinitSettings, winit::UpdateMode::Continuous};
use bevy_replicon::{client::ServerEntityTicks, prelude::*};
use bevy::{prelude::*, winit::UpdateMode::Continuous, winit::WinitSettings};
use bevy_replicon::{
client::confirmed::{self, Confirmed},
prelude::*,
};
use bevy_replicon_renet::{
renet::{
transport::{
Expand All @@ -20,8 +23,9 @@ use bevy_replicon_renet::{
RenetChannelsExt, RepliconRenetPlugins,
};
use bevy_replicon_snap::{
AppInterpolationExt, Interpolated, NetworkOwner, OwnerPredicted, Predicted,
PredictedEventHistory, SnapshotBuffer, SnapshotInterpolationPlugin,
interpolation::Interpolated, interpolation::SnapshotBuffer, prediction::OwnerPredicted,
prediction::Predicted, prediction::PredictedEventHistory, AppInterpolationExt, NetworkOwner,
SnapshotInterpolationPlugin,
};
use bevy_replicon_snap_macros::Interpolate;
use clap::Parser;
Expand Down Expand Up @@ -246,21 +250,25 @@ impl SimpleBoxPlugin {
// Client prediction implementation
fn predicted_movement_system(
mut q_predicted_players: Query<
(Entity, &mut PlayerPosition, &SnapshotBuffer<PlayerPosition>),
(
Entity,
&mut PlayerPosition,
&SnapshotBuffer<PlayerPosition>,
&Confirmed,
),
(With<Predicted>, Without<Interpolated>),
>,
mut local_events: EventReader<MoveDirection>,
mut event_history: ResMut<PredictedEventHistory<MoveDirection>>,
server_ticks: Res<ServerEntityTicks>,
time: Res<Time>,
) {
// Apply all pending inputs to latest snapshot
for (e, mut position, snapshot_buffer) in q_predicted_players.iter_mut() {
for (e, mut position, snapshot_buffer, confirmed) in q_predicted_players.iter_mut() {
// Append the latest input event
for event in local_events.read() {
event_history.insert(
event.clone(),
(*server_ticks).get(&e).unwrap().get(),
confirmed.last_tick().get(),
time.delta_seconds(),
);
}
Expand Down Expand Up @@ -313,7 +321,7 @@ struct PlayerBundle {
owner: NetworkOwner,
position: PlayerPosition,
color: PlayerColor,
replication: Replication,
replicated: Replicated,
owner_predicted: OwnerPredicted,
}

Expand All @@ -323,7 +331,7 @@ impl PlayerBundle {
owner: NetworkOwner(id.get()),
position: PlayerPosition(position),
color: PlayerColor(color),
replication: Replication,
replicated: Replicated,
owner_predicted: OwnerPredicted,
}
}
Expand Down
2 changes: 1 addition & 1 deletion macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn derive_interpolate(input: TokenStream) -> TokenStream {
_ => panic!("expected a struct"),
};
let output = quote! {
impl ::bevy_replicon_snap::Interpolate for #ident {
impl ::bevy_replicon_snap::interpolation::Interpolate for #ident {
fn interpolate(&self, other: Self, t: f32) -> Self {
#body
}
Expand Down
94 changes: 94 additions & 0 deletions src/interpolation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
use std::collections::VecDeque;

use bevy::{
ecs::{
component::Component,
query::{With, Without},
system::{Query, Res, Resource},
},
reflect::Reflect,
time::Time,
};
use serde::{Deserialize, Serialize};

use crate::prediction::Predicted;

pub trait Interpolate {
fn interpolate(&self, other: Self, t: f32) -> Self;
}

#[derive(Component, Deserialize, Serialize, Reflect)]
pub struct Interpolated;

#[derive(Deserialize, Serialize, Reflect)]
pub struct Snapshot<T: Component + Interpolate + Clone> {
tick: u32,
value: T,
}

#[derive(Component, Deserialize, Serialize, Reflect)]
pub struct SnapshotBuffer<T: Component + Interpolate + Clone> {
pub buffer: VecDeque<T>,
pub time_since_last_snapshot: f32,
pub latest_snapshot_tick: u32,
}

#[derive(Resource, Serialize, Deserialize, Debug)]
pub struct SnapshotInterpolationConfig {
pub max_tick_rate: u16,
}

impl<T: Component + Interpolate + Clone> SnapshotBuffer<T> {
pub fn new() -> Self {
Self {
buffer: VecDeque::new(),
time_since_last_snapshot: 0.0,
latest_snapshot_tick: 0,
}
}
pub fn insert(&mut self, element: T, tick: u32) {
if self.buffer.len() > 1 {
self.buffer.pop_front();
}
self.buffer.push_back(element);
self.time_since_last_snapshot = 0.0;
self.latest_snapshot_tick = tick;
}

pub fn latest_snapshot(&self) -> T {
self.buffer.iter().last().unwrap().clone()
}

pub fn latest_snapshot_tick(&self) -> u32 {
self.latest_snapshot_tick
}

pub fn age(&self) -> f32 {
self.time_since_last_snapshot
}
}

/// Interpolate between snapshots.
pub fn snapshot_interpolation_system<T: Component + Interpolate + Clone>(
mut q: Query<(&mut T, &mut SnapshotBuffer<T>), (With<Interpolated>, Without<Predicted>)>,
time: Res<Time>,
config: Res<SnapshotInterpolationConfig>,
) {
for (mut component, mut snapshot_buffer) in q.iter_mut() {
let buffer = &snapshot_buffer.buffer;
let elapsed = snapshot_buffer.time_since_last_snapshot;
if buffer.len() < 2 {
continue;
}

let tick_duration = 1.0 / (config.max_tick_rate as f32);

if elapsed > tick_duration + time.delta_seconds() {
continue;
}

let t = (elapsed / tick_duration).clamp(0., 1.);
*component = buffer[0].interpolate(buffer[1].clone(), t);
snapshot_buffer.time_since_last_snapshot += time.delta_seconds();
}
}
Loading

0 comments on commit 0ae1308

Please sign in to comment.