implement player id allocation (#90)

* implement player id allocation

* move `bevy/debug` to `dbg`
This commit is contained in:
PROMETHIA-27
2025-12-19 17:41:16 -05:00
committed by GitHub
parent a4488cc072
commit f6fa9ce1e4
6 changed files with 42 additions and 12 deletions

View File

@@ -20,7 +20,7 @@ client = [
"bevy_replicon_renet/client",
"bevy_trenchbroom/client",
]
dbg = ["avian3d/debug-plugin", "dep:bevy-inspector-egui"]
dbg = ["avian3d/debug-plugin", "bevy/debug", "dep:bevy-inspector-egui"]
[dependencies]
avian3d = { workspace = true }

View File

@@ -36,7 +36,7 @@ pub mod water;
use crate::{
config::NetworkingConfig,
heads_database::{HeadDatabaseAsset, HeadsDatabase},
protocol::{PlayerId, messages::AssignClientPlayer},
protocol::{PlayerIdCounter, messages::AssignClientPlayer},
tb_entities::SpawnPoint,
};
use avian3d::{PhysicsPlugins, prelude::TransformInterpolation};
@@ -198,12 +198,16 @@ fn start_solo_client(
query: Query<&Transform, With<SpawnPoint>>,
heads_db: Res<HeadsDatabase>,
mut assign_player_id: MessageWriter<AssignClientPlayer>,
mut ids: ResMut<PlayerIdCounter>,
) {
next.set(GameState::Playing);
player::spawn(commands, ClientId::Server, query, heads_db);
ids.reset();
let id = ids.alloc();
assign_player_id.write(AssignClientPlayer(PlayerId { id: 0 }));
player::spawn(commands, ClientId::Server, id, query, heads_db);
assign_player_id.write(AssignClientPlayer(id));
}
fn start_listen_server(
@@ -212,12 +216,16 @@ fn start_listen_server(
query: Query<&Transform, With<SpawnPoint>>,
heads_db: Res<HeadsDatabase>,
mut assign_player_id: MessageWriter<AssignClientPlayer>,
mut ids: ResMut<PlayerIdCounter>,
) {
next.set(GameState::Hosting);
player::spawn(commands, ClientId::Server, query, heads_db);
ids.reset();
let id = ids.alloc();
assign_player_id.write(AssignClientPlayer(PlayerId { id: 0 }));
player::spawn(commands, ClientId::Server, id, query, heads_db);
assign_player_id.write(AssignClientPlayer(id));
}
fn start_client(mut next: ResMut<NextState<GameState>>) {

View File

@@ -65,6 +65,7 @@ pub fn plugin(app: &mut App) {
pub fn spawn(
mut commands: Commands,
owner: ClientId,
id: PlayerId,
query: Query<&Transform, With<SpawnPoint>>,
heads_db: Res<HeadsDatabase>,
) -> Option<Entity> {
@@ -91,7 +92,7 @@ pub fn spawn(
transform,
Visibility::default(),
PlayerCharacterController,
PlayerId { id: 0 },
id,
),
Backpack::default(),
BackpackUiState::default(),

View File

@@ -76,6 +76,23 @@ impl From<NetworkedCollider> for Collider {
}
}
#[derive(Resource, Default)]
pub struct PlayerIdCounter {
next: u8,
}
impl PlayerIdCounter {
pub fn reset(&mut self) {
self.next = 0;
}
pub fn alloc(&mut self) -> PlayerId {
let id = PlayerId { id: self.next };
self.next += 1;
id
}
}
/// An ID, unique per player, inserted on the character controller. The `PlayerIdMap` maintains a mapping of ID -> controller entity
/// on the server
#[derive(Clone, Copy, Component, Hash, Reflect, Serialize, Deserialize, PartialEq, Eq)]

View File

@@ -74,6 +74,7 @@ pub fn plugin(app: &mut App) {
app.register_type::<TbMapIdCounter>();
app.register_type::<TbMapEntityMapping>();
app.init_resource::<PlayerIdCounter>();
app.init_resource::<PlayerIdMap>();
app.init_resource::<TbMapIdCounter>();
app.init_resource::<TbMapEntityMapping>();

View File

@@ -2,7 +2,7 @@ use crate::{
GameState, global_observer,
heads_database::HeadsDatabase,
player::ClientPlayerId,
protocol::{ClientEnteredPlaying, PlayerId, SetGameTick, messages::AssignClientPlayer},
protocol::{ClientEnteredPlaying, PlayerIdCounter, SetGameTick, messages::AssignClientPlayer},
tb_entities::SpawnPoint,
tick::GameTick,
};
@@ -38,12 +38,14 @@ pub fn plugin(app: &mut App) {
fn on_client_playing(
trigger: On<FromClient<ClientEnteredPlaying>>,
commands: Commands,
clients: Query<&ClientPlayerId>,
query: Query<&Transform, With<SpawnPoint>>,
heads_db: Res<HeadsDatabase>,
) -> Result {
info!("client has entered playing gamestate");
crate::player::spawn(commands, trigger.client_id, query, heads_db)
let id = clients.get(trigger.client_id.entity().unwrap()).unwrap();
crate::player::spawn(commands, trigger.client_id, id.0, query, heads_db)
.ok_or("failed to spawn player")?;
Ok(())
@@ -100,16 +102,17 @@ fn on_connected(
game_tick: Res<GameTick>,
mut commands: Commands,
mut assign_id: MessageWriter<ToClients<AssignClientPlayer>>,
mut ids: ResMut<PlayerIdCounter>,
) {
let client = trigger.event_target();
info!("{client} connected to server!");
let id = ClientPlayerId(PlayerId { id: 0 });
commands.entity(client).insert(id);
let id = ids.alloc();
commands.entity(client).insert(ClientPlayerId(id));
assign_id.write(ToClients {
mode: SendMode::Direct(ClientId::Client(trigger.entity)),
message: AssignClientPlayer(id.0),
message: AssignClientPlayer(id),
});
commands.server_trigger(ToClients {