Initial work on rollback and refactor
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
//! Network stats overlay.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_egui::prelude::*;
|
||||
use bevy_ggrs::prelude::*;
|
||||
|
||||
use crate::netcode::GGRSCfg;
|
||||
|
||||
pub fn network_debug(
|
||||
mut contexts: EguiContexts,
|
||||
session: Option<Res<Session<GGRSCfg>>>,
|
||||
) -> Result {
|
||||
if let Some(sess) = session {
|
||||
match sess.as_ref() {
|
||||
Session::P2P(s) => {
|
||||
let num_players = s.num_players();
|
||||
for i in 0..num_players {
|
||||
egui::Window::new(format!("Player {}", i)).show(contexts.ctx_mut()?, |ui| {
|
||||
if let Ok(stats) = s.network_stats(i) {
|
||||
ui.label(format!("{:?}", stats));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//! Rollback networking: session setup and the engine-level rollback
|
||||
//! registrations. Gameplay components are registered by the plugin that owns
|
||||
//! them, not here.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_egui::EguiPrimaryContextPass;
|
||||
use bevy_ggrs::prelude::*;
|
||||
|
||||
pub mod debug;
|
||||
pub mod session;
|
||||
|
||||
/// The GGRS configuration for this game — notably, what a frame of input is.
|
||||
pub type GGRSCfg = GgrsConfig<crate::input::FighterInputFrame>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FighterNetcodePlugin;
|
||||
|
||||
impl Plugin for FighterNetcodePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
let plugin = GgrsPlugin::<GGRSCfg>::default();
|
||||
app.add_plugins(plugin)
|
||||
.add_systems(Startup, session::netcode_setup)
|
||||
// Engine-level components that every rolled-back entity may carry.
|
||||
// Gameplay components are registered by the plugin that owns them.
|
||||
.rollback_component_with_clone::<Transform>()
|
||||
.rollback_component_with_clone::<Name>()
|
||||
.add_systems(EguiPrimaryContextPass, debug::network_debug)
|
||||
.add_systems(Update, session::print_events_system)
|
||||
.insert_resource(RollbackFrameRate(60));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//! Bringing up the GGRS session and reporting what it does.
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_ggrs::{ggrs::UdpNonBlockingSocket, prelude::*};
|
||||
|
||||
use crate::args::Args;
|
||||
use crate::netcode::GGRSCfg;
|
||||
|
||||
pub fn netcode_setup(mut commands: Commands, args: Res<Args>) -> Result {
|
||||
let mut sess_build = SessionBuilder::<GGRSCfg>::new()
|
||||
.with_num_players(args.players)?
|
||||
.with_check_distance(args.check_distance)
|
||||
.with_input_delay(args.input_delay); // (optional) set input delay for the local player
|
||||
|
||||
for i in 0..args.players {
|
||||
sess_build = sess_build.add_player(PlayerType::Local, i)?;
|
||||
}
|
||||
|
||||
if args.synctest {
|
||||
println!("Start synctest!");
|
||||
let sess = sess_build.start_synctest_session()?;
|
||||
commands.insert_resource(Session::SyncTest(sess));
|
||||
} else {
|
||||
println!("Start p2p!");
|
||||
let socket = UdpNonBlockingSocket::bind_to_port(6969)?;
|
||||
let sess = sess_build.start_p2p_session(socket)?;
|
||||
commands.insert_resource(Session::P2P(sess));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn print_events_system(mut session: ResMut<Session<GGRSCfg>>) {
|
||||
match session.as_mut() {
|
||||
Session::P2P(s) => {
|
||||
for event in s.events() {
|
||||
match event {
|
||||
GgrsEvent::Disconnected { .. } | GgrsEvent::NetworkInterrupted { .. } => {
|
||||
warn!("GGRS event: {event:?}")
|
||||
}
|
||||
GgrsEvent::DesyncDetected { .. } => error!("GGRS event: {event:?}"),
|
||||
_ => info!("GGRS event: {event:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user