replication_demo/
replication_demo.rs1use 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}