This commit is contained in:
2026-02-09 15:35:37 -06:00
parent dbb87c3930
commit f8b5107c92
7 changed files with 278 additions and 13 deletions
+27
View File
@@ -0,0 +1,27 @@
use clap::{Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(author, version, about)]
pub struct Cli {
#[command(subcommand)]
pub mode: Option<Mode>,
}
#[derive(Subcommand, Debug, Default)]
pub enum Mode {
/// Run a headless server (no rendering)
#[cfg(feature = "server")]
#[cfg_attr(all(feature = "server", not(feature = "client")), default)]
Headless,
/// Run a server that renders
#[cfg(feature = "server")]
Server,
/// Run the client application
#[cfg(feature = "client")]
#[cfg_attr(all(feature = "client", not(feature = "server")), default)]
Client,
/// Run both client and server in one process
#[cfg(all(feature = "client", feature = "server"))]
#[cfg_attr(all(feature = "client", feature = "server"), default)]
Host,
}
+61 -13
View File
@@ -1,27 +1,75 @@
use crate::avian::{CharacterControllerBundle, CharacterControllerPlugin};
use crate::{
avian::{CharacterControllerBundle, CharacterControllerPlugin},
cli::Cli,
};
use avian2d::{
PhysicsPlugins,
math::Vector,
prelude::{Collider, Gravity, RigidBody},
};
use bevy::{camera::ScalingMode, color::palettes::css::GREEN, prelude::*};
use clap::Parser;
pub mod avian;
pub mod cli;
pub mod net;
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
// Add physics plugins and specify a units-per-meter scaling factor, 1 meter = 20 pixels.
// The unit allows the engine to tune its parameters for the scale of the world, improving stability.
PhysicsPlugins::default().with_length_unit(20.0),
CharacterControllerPlugin,
))
.add_systems(Startup, setup)
.add_systems(Update, debug_border)
.insert_resource(Gravity(Vector::ZERO))
.run();
let cli = match Cli::try_parse() {
Ok(cli) => cli,
Err(err) => {
err.print().expect("failed to print clap error");
std::process::exit(1);
}
};
#[cfg(all(feature = "client", not(feature = "server")))]
let mode = cli.mode.unwrap_or(cli::Mode::Client);
#[cfg(all(feature = "server", not(feature = "client")))]
let mode = cli.mode.unwrap_or(cli::Mode::Server);
#[cfg(all(feature = "client", feature = "server"))]
let mode = cli.mode.unwrap_or(cli::Mode::Host);
#[cfg(all(not(feature = "client"), not(feature = "server")))]
panic!("You must enable either the client or server feature");
let mut app = App::new();
match mode {
#[cfg(feature = "server")]
cli::Mode::Headless => {
app.add_plugins((MinimalPlugins, net::server::GameServerPlugin));
}
#[cfg(feature = "server")]
cli::Mode::Server => {
app.add_plugins((DefaultPlugins, net::server::GameServerPlugin));
}
#[cfg(feature = "client")]
cli::Mode::Client => {
app.add_plugins((DefaultPlugins, net::client::GameClientPlugin));
}
#[cfg(all(feature = "client", feature = "server"))]
cli::Mode::Host => {
app.add_plugins((
DefaultPlugins,
net::server::GameServerPlugin,
net::client::GameClientPlugin,
));
}
}
app.add_plugins((
// Add physics plugins and specify a units-per-meter scaling factor, 1 meter = 20 pixels.
// The unit allows the engine to tune its parameters for the scale of the world, improving stability.
PhysicsPlugins::default().with_length_unit(20.0),
CharacterControllerPlugin,
))
.add_systems(Startup, setup)
.add_systems(Update, debug_border)
.insert_resource(Gravity(Vector::ZERO))
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
+18
View File
@@ -0,0 +1,18 @@
use bevy::prelude::*;
pub struct GameClientPlugin;
impl Plugin for GameClientPlugin {
fn build(&self, app: &mut App) {
// app.add_systems(
// FixedPreUpdate,
// // Inputs have to be buffered in the WriteClientInputs set
// buffer_input.in_set(InputSystems::WriteClientInputs),
// );
// app.add_systems(FixedUpdate, player_movement);
// app.add_systems(Update, receive_message1);
// app.add_observer(handle_predicted_spawn);
// app.add_observer(handle_interpolated_spawn);
}
}
+30
View File
@@ -0,0 +1,30 @@
use bevy::prelude::*;
#[derive(Clone)]
pub struct ProtocolPlugin;
impl Plugin for ProtocolPlugin {
fn build(&self, app: &mut App) {
// messages
app.register_message::<Message1>()
.add_direction(NetworkDirection::ServerToClient);
// inputs
app.add_plugins(input::native::InputPlugin::<Inputs>::default());
// components
app.register_component::<PlayerId>();
app.register_component::<PlayerPosition>()
.add_prediction()
.add_linear_interpolation();
app.register_component::<PlayerColor>();
// channels
app.add_channel::<Channel1>(ChannelSettings {
mode: ChannelMode::OrderedReliable(ReliableSettings::default()),
..default()
})
.add_direction(NetworkDirection::ServerToClient);
}
}
+13
View File
@@ -0,0 +1,13 @@
use bevy::prelude::*;
pub struct GameServerPlugin;
impl Plugin for GameServerPlugin {
fn build(&self, app: &mut App) {
// // the physics/FixedUpdates systems that consume inputs should be run in this set.
// app.add_systems(FixedUpdate, movement);
// app.add_observer(handle_new_client);
// app.add_observer(handle_connected);
// app.add_systems(Update, send_message);
}
}