M crates/unified/assets/config/world.wc.toml => crates/unified/assets/config/world.wc.toml +4 -4
@@ 7,11 7,11 @@ spawn_parts_interval_secs = 1
default_height = 50
default_width = 50
default_mass = 100
-joint_align_compliance = 0.000000000000000002
+joint_align_compliance = 0.0002
joint_angle_compliance = 0.00000002
-joint_limit_compliance = 0.0000006
-joint_linear_damping = 40.0
-joint_angular_damping = 20.0
+joint_limit_compliance = 0.006
+joint_linear_damping = 4.0
+joint_angular_damping = 2.0
[hearty]
thrust = 500000
M crates/unified/src/attachment.rs => crates/unified/src/attachment.rs +10 -0
@@ 4,24 4,29 @@ use serde::{Deserialize, Serialize};
use std::ops::Deref;
#[derive(Component, Serialize, Deserialize)]
+#[require(Replicated)]
/// The primary component for a ship structure
pub struct Ship;
#[derive(Component, Serialize, Deserialize, MapEntities, Deref)]
#[relationship_target(relationship = PartInShip, linked_spawn)]
+#[require(Replicated)]
pub struct Parts(#[entities] Vec<Entity>);
#[derive(Component, Serialize, Deserialize, MapEntities)]
#[relationship(relationship_target = Parts)]
+#[require(Replicated)]
pub struct PartInShip(#[entities] pub Entity);
#[derive(Component, Serialize, Deserialize)]
#[require(Transform)]
+#[require(Replicated)]
pub struct Joint {
pub id: JointId,
pub transform: Transform,
}
#[derive(Component, Serialize, Deserialize, MapEntities)]
+#[require(Replicated)]
pub struct Peer {
#[entities]
pub peer_joint_entity_id: Entity,
@@ 32,9 37,11 @@ pub struct Peer {
#[derive(Component, Serialize, Deserialize, MapEntities)]
#[relationship(relationship_target = Joints)]
+#[require(Replicated)]
pub struct JointOf(#[entities] pub Entity);
#[derive(Component, Serialize, Deserialize, MapEntities, Debug, Clone)]
#[relationship_target(relationship = JointOf)]
+#[require(Replicated)]
pub struct Joints(#[entities] Vec<Entity>);
impl Deref for Joints {
type Target = Vec<Entity>;
@@ 44,9 51,11 @@ impl Deref for Joints {
}
#[derive(Component, Serialize, Deserialize, MapEntities)]
#[relationship(relationship_target = Snaps)]
+#[require(Replicated)]
pub struct SnapOf(#[entities] pub Entity);
#[derive(Component, Serialize, Deserialize, MapEntities)]
#[relationship_target(relationship = SnapOf)]
+#[require(Replicated)]
pub struct Snaps(#[entities] Vec<Entity>);
impl Deref for Snaps {
type Target = Vec<Entity>;
@@ 66,4 75,5 @@ impl JointId {
}
#[derive(Serialize, Deserialize, Component, MapEntities)]
+#[require(Replicated)]
pub struct SnapOfJoint(#[entities] pub Entity);
M crates/unified/src/client/mod.rs => crates/unified/src/client/mod.rs +22 -18
@@ 4,7 4,7 @@ use crate::client::planet::indicators::indicators_plugin;
use crate::client::starfield::starfield_plugin;
use crate::client::ui::ui_plugin;
use crate::client::zoom::zoom_plugin;
-use crate::ecs::{Part, Player};
+use crate::ecs::{Hi, Part, Player};
use aeronet_websocket::client::WebSocketClient;
use bevy::dev_tools::picking_debug::DebugPickingMode;
use crate::prelude::*;
@@ 68,26 68,30 @@ impl Plugin for ClientPlugin {
fn find_me(
mut commands: Commands,
- q_clients: Query<(Entity, &Player, &Part), Added<Player>>,
+ mut reader: MessageReader<Hi>,
asset_server: Res<AssetServer>,
) {
- for (entity, player, part) in q_clients.iter() {
- if player.client == entity {
- commands.entity(entity).insert(Me);
- let mut heart_sprite =
- Sprite::from_image(asset_server.load("sprites/hearty_heart.png"));
- heart_sprite.custom_size = Some(Vec2::new(
- part.strong_config.physics.width,
- part.strong_config.physics.height,
- ));
- heart_sprite.color = Color::srgb(20.0, 0.0, 0.0);
- commands.spawn((
- ChildOf(entity),
- heart_sprite,
- Transform::from_xyz(0.0, 0.0, 10.0),
- ));
- }
+ for msg in reader.read() {
+ info!("^^^^^^^^^^^ IGNORE THESE WARNINGS ^^^^^^^^^^^^^^");
+ info!("they are normal! and are from the world state being replicated as it is sent over the network");
+ info!(?msg, "finding me: got hello from server");
+ commands.entity(msg.you_are).insert(Me);
+
+ /*let mut heart_sprite =
+ Sprite::from_image(asset_server.load("sprites/hearty_heart.png"));
+ heart_sprite.custom_size = Some(Vec2::new(
+ part.strong_config.physics.width,
+ part.strong_config.physics.height,
+ ));
+ heart_sprite.color = Color::srgb(20.0, 0.0, 0.0);
+
+ commands.spawn((
+ ChildOf(entity),
+ heart_sprite,
+ Transform::from_xyz(0.0, 0.0, 10.0),
+ ));
+ */
}
}
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +10 -9
@@ 35,24 35,18 @@ pub struct Part {
pub strong_config: PartConfig,
}
#[derive(Component, Debug)]
+#[require(Replicated)]
pub struct PartHandle(pub Handle<PartConfig>);
#[derive(Component, Serialize, Deserialize, Debug)]
+#[require(Replicated)]
pub struct Player {
#[entities]
pub client: Entity,
}
-#[derive(Component, Default, Serialize, Deserialize, Debug)]
-#[allow(clippy::struct_excessive_bools, reason = "It's not a state machine")]
-pub struct PlayerThrust {
- pub up: bool,
- pub down: bool,
- pub left: bool,
- pub right: bool,
-}
-
#[derive(Component, Serialize, Deserialize, Debug)]
+#[require(Replicated)]
pub struct Particles {
pub effect: String,
pub active: bool,
@@ 71,6 65,7 @@ pub struct DragRequestEvent {
}
#[derive(Component, Serialize, Deserialize, Debug)]
+#[require(Replicated)]
pub struct PlayerStorage {
pub fuel_capacity: f32,
pub fuel: f32,
@@ 80,3 75,9 @@ pub struct PlayerStorage {
#[derive(Component)]
pub struct Me;
+
+#[derive(Message, Serialize, Deserialize, Debug, MapEntities)]
+pub struct Hi {
+ #[entities]
+ pub you_are: Entity
+}<
\ No newline at end of file
M crates/unified/src/ecs/thruster.rs => crates/unified/src/ecs/thruster.rs +2 -0
@@ 4,6 4,7 @@ use bevy::math::Vec2;
use bevy::prelude::Bundle;
use serde::{Deserialize, Serialize};
use crate::prelude::{ChildOf, Component, Entity, Transform};
+use bevy_replicon::prelude::Replicated;
#[derive(Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct ThrusterId(pub String);
@@ 30,6 31,7 @@ impl Deref for PartThrusters {
pub struct ThrusterOfPart(#[entities] pub Entity);
#[derive(Component, Serialize, Deserialize)]
+#[require(Replicated)]
pub struct Thruster {
pub id: ThrusterId,
pub thrust_vector: Vec2
M crates/unified/src/server/mod.rs => crates/unified/src/server/mod.rs +3 -1
@@ 63,11 63,13 @@ impl ServerPlugin {
}
}
-#[derive(Component)]
+#[derive(Component, Debug)]
+#[require(Replicated)]
pub struct ConnectedGameEntity {
pub network_entity: Entity,
}
#[derive(Component)]
+#[require(Replicated)]
pub struct ConnectedNetworkEntity {
pub game_entity: Entity,
}
M crates/unified/src/server/part.rs => crates/unified/src/server/part.rs +1 -0
@@ 16,6 16,7 @@ pub struct SpawnPartBundle {
}
#[derive(Component)]
+#[require(Replicated)]
pub struct SpawnPartRequest(pub Handle<PartConfig>);
// wait for parts assets to be ready, then spawn the full part
M crates/unified/src/server/player.rs => crates/unified/src/server/player.rs +1 -0
@@ 25,6 25,7 @@ pub fn player_management_plugin(app: &mut App) {
}
#[derive(Component)]
+#[require(Replicated)]
struct PartiallyDisconnected;
/// Partial Disconnects are created when a part is disconnected to indicate that a disconnect has started.
M crates/unified/src/server/player/join.rs => crates/unified/src/server/player/join.rs +15 -5
@@ 1,6 1,6 @@
use crate::config::planet::Planet;
use crate::config::world::GlobalWorldConfig;
-use crate::ecs::{Player, PlayerStorage, PlayerThrust};
+use crate::ecs::{Hi, Player, PlayerStorage};
use crate::prelude::*;
use crate::server::ConnectedGameEntity;
use crate::server::part::SpawnPartRequest;
@@ 38,7 38,6 @@ fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldCo
.insert(SpawnPartRequest(
asset_server.load("config/parts/hearty.part.toml"),
))
- .insert(PlayerThrust::default())
.insert(PlayerStorage {
fuel_capacity: 25.0,
fuel: 25.0,
@@ 52,24 51,35 @@ fn join_player(joined_player: Entity, mut commands: Commands, wc: &GlobalWorldCo
}
#[derive(Component)]
+#[require(Replicated)]
pub struct PendingPlayer;
pub fn handle_new_players(
mut commands: Commands,
- q_new_clients: Query<Entity, Added<ConnectedGameEntity>>,
+ q_new_clients: Query<(Entity, &ConnectedGameEntity), Added<ConnectedGameEntity>>,
world_config: Res<WorldConfigResource>,
planets: Query<(&Transform, &Planet)>,
+ mut hi_writer: MessageWriter<ToClients<Hi>>,
asset_server: Res<AssetServer>,
) {
+ for joined_player in &q_new_clients {
+ hi_writer.write(ToClients {
+ mode: SendMode::Direct(ClientId::Client(joined_player.1.network_entity)),
+ message: Hi {
+ you_are: joined_player.0
+ }
+ });
+ }
let Some(wc) = &world_config.config else {
warn!("got a joined player, but world config is not loaded! waiting until it is...");
for joined_player in &q_new_clients {
- commands.entity(joined_player).insert(PendingPlayer);
+ commands.entity(joined_player.0).insert(PendingPlayer);
}
return;
};
for joined_player in &q_new_clients {
- join_player(joined_player, commands.reborrow(), wc, planets, &asset_server);
+ debug!(?joined_player, "new player!");
+ join_player(joined_player.0, commands.reborrow(), wc, planets, &asset_server);
}
}
pub fn handle_pending_players(
M crates/unified/src/shared_plugins.rs => crates/unified/src/shared_plugins.rs +7 -3
@@ 1,12 1,13 @@
use crate::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint};
use crate::config::planet::{Planet, PlanetConfigCollection};
-use crate::ecs::{DragRequestEvent, Part, Particles, Player, PlayerStorage};
+use crate::ecs::{DragRequestEvent, Hi, Part, Particles, Player, PlayerStorage};
use bevy::app::{App, PluginGroup, PluginGroupBuilder};
use bevy_common_assets::toml::TomlAssetPlugin;
use crate::prelude::*;
use bevy_replicon::prelude::{AppRuleExt, Channel, ClientMessageAppExt};
use crate::config::part::PartConfig;
use crate::config::world::GlobalWorldConfig;
+use crate::ecs::thruster::{Thruster, ThrusterOfPart};
use crate::physics::register_physics_components_for_replication;
use crate::thrust::ThrustSolution;
@@ 31,8 32,9 @@ impl PluginGroup for SharedPluginGroup {
pub fn register_everything(app: &mut App) {
app.add_mapped_client_message::<ThrustSolution>(Channel::Ordered)
.add_mapped_client_message::<DragRequestEvent>(Channel::Ordered)
+ .add_mapped_server_message::<Hi>(Channel::Ordered)
.replicate::<Transform>()
- .replicate::<GlobalTransform>()
+ //.replicate::<GlobalTransform>()
//.replicate::<Collider>()
//.replicate::<RigidBody>()
.replicate::<Planet>()
@@ 47,7 49,9 @@ pub fn register_everything(app: &mut App) {
.replicate::<JointOf>()
.replicate::<SnapOfJoint>()
.replicate::<SnapOf>()
- .replicate::<PlayerStorage>();
+ .replicate::<PlayerStorage>()
+ .replicate::<Thruster>()
+ .replicate::<ThrusterOfPart>();
}
fn physics_setup_plugin(app: &mut App) {