1 Commits
Author SHA1 Message Date
mitchell 3729790c31 idk 2026-05-03 15:08:18 -05:00
9 changed files with 647 additions and 310 deletions
Generated
+621 -146
View File
File diff suppressed because it is too large Load Diff
+1 -7
View File
@@ -3,13 +3,7 @@ name = "time_travel"
version = "0.1.0"
edition = "2024"
[features]
default = ["client", "server"]
client = []
server = []
[dependencies]
avian2d = "0.5.0"
bevy = "0.18.0"
clap = { version = "4.5.56", features = ["derive"] }
bevy_egui = "0.39.1"
-27
View File
@@ -1,27 +0,0 @@
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,
}
+25 -62
View File
@@ -1,75 +1,29 @@
use crate::{
avian::{CharacterControllerBundle, CharacterControllerPlugin},
cli::Cli,
};
use crate::avian::{CharacterControllerBundle, CharacterControllerPlugin};
use avian2d::{
PhysicsPlugins,
math::Vector,
prelude::{Collider, Gravity, RigidBody},
};
use bevy::{camera::ScalingMode, color::palettes::css::GREEN, prelude::*};
use clap::Parser;
use bevy_egui::{EguiContexts, EguiPlugin, EguiPrimaryContextPass, egui};
pub mod avian;
pub mod cli;
pub mod net;
fn main() {
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();
App::new()
.add_plugins((
DefaultPlugins,
EguiPlugin::default(),
// 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)
.add_systems(EguiPrimaryContextPass, connection_ui)
.insert_resource(Gravity(Vector::ZERO))
.run();
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
@@ -103,3 +57,12 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
fn debug_border(mut gizmos: Gizmos) {
gizmos.rect_2d(Isometry2d::IDENTITY, Vec2::new(1920., 1080.), GREEN);
}
fn connection_ui(mut contexts: EguiContexts) -> Result {
let mut text = String::from("hello");
egui::Window::new("Connection").show(contexts.ctx_mut()?, |ui| {
ui.label("connection:");
ui.text_edit_singleline(&mut text)
});
Ok(())
}
-18
View File
@@ -1,18 +0,0 @@
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);
}
}
-6
View File
@@ -1,6 +0,0 @@
#[cfg(feature = "client")]
pub mod client;
pub mod protocol;
#[cfg(feature = "server")]
pub mod server;
pub mod shared;
-30
View File
@@ -1,30 +0,0 @@
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
@@ -1,13 +0,0 @@
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);
}
}
-1
View File
@@ -1 +0,0 @@