Skip to content

Commit

Permalink
updgrade to replicon 0.25.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Bendzae committed May 25, 2024
1 parent a57b990 commit 3771091
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 82 deletions.
7 changes: 4 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 All @@ -33,3 +33,4 @@ bevy = { version = "0.13.0", default-features = false, features = [
"x11",
"default_font",
] }
bevy-inspector-egui = "0.24.0"
6 changes: 4 additions & 2 deletions examples/interpolated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{
};

use bevy::{prelude::*, winit::UpdateMode::Continuous, winit::WinitSettings};
use bevy_inspector_egui::quick::WorldInspectorPlugin;
use bevy_replicon::prelude::*;
use bevy_replicon_renet::{
renet::{
Expand Down Expand Up @@ -47,6 +48,7 @@ fn main() {
SnapshotInterpolationPlugin {
max_tick_rate: MAX_TICK_RATE,
},
WorldInspectorPlugin::default(),
SimpleBoxPlugin,
))
.run();
Expand Down Expand Up @@ -274,7 +276,7 @@ struct PlayerBundle {
owner: NetworkOwner,
position: PlayerPosition,
color: PlayerColor,
replication: Replication,
replicated: Replicated,
interpolated: Interpolated,
}

Expand All @@ -284,7 +286,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
21 changes: 14 additions & 7 deletions examples/owner_predicted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use std::{
};

use bevy::{prelude::*, winit::UpdateMode::Continuous, winit::WinitSettings};
use bevy_replicon::{client::ServerEntityTicks, prelude::*};
use bevy_replicon::{
client::confirmed::{self, Confirmed},
prelude::*,
};
use bevy_replicon_renet::{
renet::{
transport::{
Expand Down Expand Up @@ -247,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 @@ -314,7 +321,7 @@ struct PlayerBundle {
owner: NetworkOwner,
position: PlayerPosition,
color: PlayerColor,
replication: Replication,
replicated: Replicated,
owner_predicted: OwnerPredicted,
}

Expand All @@ -324,7 +331,7 @@ impl PlayerBundle {
owner: NetworkOwner(id.get()),
position: PlayerPosition(position),
color: PlayerColor(color),
replication: Replication,
replicated: Replicated,
owner_predicted: OwnerPredicted,
}
}
Expand Down
21 changes: 2 additions & 19 deletions src/interpolation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@ use std::collections::VecDeque;
use bevy::{
ecs::{
component::Component,
entity::Entity,
query::{Added, Or, With, Without},
system::{Commands, Query, Res, Resource},
query::{With, Without},
system::{Query, Res, Resource},
},
reflect::Reflect,
time::Time,
};
use bevy_replicon::client::ServerEntityTicks;
use serde::{Deserialize, Serialize};

use crate::prediction::Predicted;
Expand Down Expand Up @@ -70,21 +68,6 @@ impl<T: Component + Interpolate + Clone> SnapshotBuffer<T> {
}
}

/// Initialize snapshot buffers for new entities.
pub fn snapshot_buffer_init_system<T: Component + Interpolate + Clone>(
q_new: Query<(Entity, &T), Or<(Added<Predicted>, Added<Interpolated>)>>,
mut commands: Commands,
server_ticks: Res<ServerEntityTicks>,
) {
for (e, initial_value) in q_new.iter() {
if let Some(tick) = (*server_ticks).get(&e) {
let mut buffer = SnapshotBuffer::new();
buffer.insert(initial_value.clone(), tick.get());
commands.entity(e).insert(buffer);
}
}
}

/// Interpolate between snapshots.
pub fn snapshot_interpolation_system<T: Component + Interpolate + Clone>(
mut q: Query<(&mut T, &mut SnapshotBuffer<T>), (With<Interpolated>, Without<Predicted>)>,
Expand Down
102 changes: 53 additions & 49 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,22 @@ use std::fmt::Debug;
use std::io::Cursor;

use bevy::prelude::*;
use bevy_replicon::bincode;
use bevy_replicon::bincode::deserialize_from;
use bevy_replicon::client::client_mapper::ServerEntityMap;
use bevy_replicon::core::replication_rules;
use bevy_replicon::core::replication_rules::{
serialize_component, DeserializeFn, RemoveComponentFn, SerializeFn,
use bevy_replicon::core::replication_fns::{
ctx::{RemoveCtx, WriteCtx},
rule_fns::RuleFns,
};
use bevy_replicon::core::replicon_channels::RepliconChannel;
use bevy_replicon::core::replicon_tick::RepliconTick;
use bevy_replicon::prelude::*;
use bevy_replicon::{bincode, core::command_markers::MarkerConfig};
use bevy_replicon_renet::renet::{transport::NetcodeClientTransport, RenetClient};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde::{de::DeserializeOwned, Deserialize, Serialize};

pub use bevy_replicon_snap_macros;

use crate::{
interpolation::{
snapshot_buffer_init_system, snapshot_interpolation_system, Interpolate, Interpolated,
SnapshotBuffer, SnapshotInterpolationConfig,
snapshot_interpolation_system, Interpolate, Interpolated, SnapshotBuffer,
SnapshotInterpolationConfig,
},
prediction::{
owner_prediction_init_system, predicted_snapshot_system, OwnerPredicted, Predicted,
Expand Down Expand Up @@ -79,71 +75,71 @@ impl Plugin for SnapshotInterpolationPlugin {
#[derive(Component, Deserialize, Serialize, Reflect)]
pub struct NetworkOwner(pub u64);

pub fn deserialize_snap_component<C: Clone + Interpolate + Component + DeserializeOwned>(
entity: &mut EntityWorldMut,
_entity_map: &mut ServerEntityMap,
#[derive(Component)]
pub struct RecordSnapshotsMarker;

/// Add a marker to all components requiring a snapshot buffer
pub fn snapshot_buffer_init_system<T: Component + Interpolate + Clone>(
q_new: Query<(Entity, &T), Or<(Added<Predicted>, Added<Interpolated>)>>,
mut commands: Commands,
) {
for (e, _v) in q_new.iter() {
commands.entity(e).insert(RecordSnapshotsMarker);
}
}

pub fn write_snap_component<C: Clone + Interpolate + Component + DeserializeOwned>(
ctx: &mut WriteCtx,
rule_fns: &RuleFns<C>,
entity: &mut EntityMut,
cursor: &mut Cursor<&[u8]>,
tick: RepliconTick,
) -> bincode::Result<()> {
let component: C = deserialize_from(cursor)?;
let component: C = rule_fns.deserialize(ctx, cursor)?;
if let Some(mut buffer) = entity.get_mut::<SnapshotBuffer<C>>() {
buffer.insert(component, tick.get());
buffer.insert(component, ctx.message_tick.get());
} else {
entity.insert(component);
let mut buffer = SnapshotBuffer::new();
buffer.insert(component, ctx.message_tick.get());
ctx.commands.entity(entity.id()).insert(buffer);
}

Ok(())
}

fn remove_snap_component<C: Clone + Interpolate + Component + DeserializeOwned>(
ctx: &mut RemoveCtx,
entity: &mut EntityMut,
) {
ctx.commands
.entity(entity.id())
.remove::<SnapshotBuffer<C>>()
.remove::<C>();
}

pub trait AppInterpolationExt {
/// TODO: Add docs
fn replicate_interpolated<C>(&mut self) -> &mut Self
where
C: Component + Interpolate + Clone + Serialize + DeserializeOwned;

/// TODO: Add docs
fn replicate_interpolated_with<C>(
&mut self,
serialize: SerializeFn,
deserialize: DeserializeFn,
remove: RemoveComponentFn,
) -> &mut Self
where
C: Component + Interpolate + Clone;

fn add_client_predicted_event<C>(&mut self, channel: impl Into<RepliconChannel>) -> &mut Self
where
C: Event + Serialize + DeserializeOwned + Debug + Clone;
}

impl AppInterpolationExt for App {
fn replicate_interpolated<C>(&mut self) -> &mut Self
where
C: Component + Interpolate + Clone + Serialize + DeserializeOwned,
{
self.replicate_interpolated_with::<C>(
serialize_component::<C>,
deserialize_snap_component::<C>,
replication_rules::remove_component::<C>,
)
}

fn replicate_interpolated_with<T>(
&mut self,
serialize: SerializeFn,
deserialize: DeserializeFn,
remove: RemoveComponentFn,
) -> &mut Self
fn replicate_interpolated<T>(&mut self) -> &mut Self
where
T: Component + Interpolate + Clone,
T: Component + Interpolate + Clone + Serialize + DeserializeOwned,
{
self.add_systems(
PreUpdate,
(snapshot_buffer_init_system::<T>.after(owner_prediction_init_system))
.in_set(InterpolationSet::Init)
.run_if(resource_exists::<RenetClient>),
)
.add_systems(
);
self.add_systems(
PreUpdate,
(
snapshot_interpolation_system::<T>,
Expand All @@ -152,8 +148,16 @@ impl AppInterpolationExt for App {
.chain()
.in_set(InterpolationSet::Interpolate)
.run_if(resource_exists::<RenetClient>),
);
self.replicate_with::<T>(serialize, deserialize, remove)
)
.replicate::<T>()
.register_marker_with::<RecordSnapshotsMarker>(MarkerConfig {
need_history: true,
..default()
})
.set_marker_fns::<RecordSnapshotsMarker, T>(
write_snap_component::<T>,
remove_snap_component::<T>,
)
}

fn add_client_predicted_event<C>(&mut self, channel: impl Into<RepliconChannel>) -> &mut Self
Expand Down

0 comments on commit 3771091

Please sign in to comment.