Skip to main content

replication_demo/
replication_demo.rs

1use bevy::prelude::*;
2use bevy_networker_multiplayer::{sync, NetResource, Replicated, ReplicatedPlugin};
3
4const ADDRESS: &str = "127.0.0.1:5001";
5
6#[sync]
7#[derive(Component)]
8struct Position(Vec2);
9
10#[sync]
11#[derive(Component)]
12struct Health(u32);
13
14#[derive(Clone, Copy, PartialEq, Eq)]
15enum Mode {
16    Server,
17    Client,
18}
19
20#[derive(Resource, Clone, Copy)]
21struct DemoMode(Mode);
22
23fn main() {
24    let mode = parse_mode();
25
26    let mut app = App::new();
27    app.add_plugins(MinimalPlugins);
28    app.add_plugins(ReplicatedPlugin);
29    app.insert_resource(DemoMode(mode));
30    app.add_systems(Startup, setup);
31
32    match mode {
33        Mode::Server => {
34            app.add_systems(Update, server_motion);
35        }
36        Mode::Client => {
37            app.add_systems(Update, client_report);
38        }
39    }
40
41    app.run();
42}
43
44fn parse_mode() -> Mode {
45    match std::env::args().nth(1).as_deref() {
46        Some("server") => Mode::Server,
47        Some("client") => Mode::Client,
48        _ => {
49            eprintln!("usage: cargo run --example replication_demo -- [server|client]");
50            std::process::exit(1);
51        }
52    }
53}
54
55fn setup(mut commands: Commands, mut net: ResMut<NetResource>, mode: Res<DemoMode>) {
56    match mode.0 {
57        Mode::Server => {
58            net.start_server(5001);
59            println!("server listening on {ADDRESS}");
60            commands.spawn((
61                Replicated,
62                Position(Vec2::ZERO),
63                Health(100),
64            ));
65        }
66        Mode::Client => {
67            net.join_server(ADDRESS.to_string());
68            println!("client connected to {ADDRESS}");
69        }
70    }
71}
72
73fn server_motion(
74    time: Res<Time>,
75    mut tick: Local<f32>,
76    mut query: Query<&mut Position, With<Replicated>>,
77) {
78    *tick += time.delta_secs();
79    if *tick < 1.0 {
80        return;
81    }
82    *tick = 0.0;
83
84    if let Ok(mut position) = query.single_mut() {
85        position.0.x += 1.0;
86        position.0.y += 0.5;
87        println!("server position -> {:?}", position.0);
88    }
89}
90
91fn client_report(
92    time: Res<Time>,
93    mut tick: Local<f32>,
94    query: Query<(Entity, &Position, &Health), With<Replicated>>,
95) {
96    *tick += time.delta_secs();
97    if *tick < 1.0 {
98        return;
99    }
100    *tick = 0.0;
101
102    for (entity, position, health) in &query {
103        println!(
104            "client entity {:?} => position {:?}, health {}",
105            entity, position.0, health.0
106        );
107    }
108}