Skip to content

Commit

Permalink
feat: chunk generation system
Browse files Browse the repository at this point in the history
  • Loading branch information
AudranTourneur committed Jan 26, 2025
1 parent 355e1e3 commit 66336ea
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 61 deletions.
8 changes: 4 additions & 4 deletions client/src/network/extensions.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use bevy::prelude::*;
use bevy_renet::renet::{DefaultChannel, RenetClient};
use bevy_renet::renet::RenetClient;
use bincode::ErrorKind;
use shared::{
game_message_to_payload,
game_message_to_payload, get_default_game_channel,
messages::{ClientToServerMessage, ServerToClientMessage},
};

Expand All @@ -14,11 +14,11 @@ pub trait SendGameMessageExtension {
impl SendGameMessageExtension for RenetClient {
fn send_game_message(&mut self, message: ClientToServerMessage) {
let payload = game_message_to_payload(message);
self.send_message(DefaultChannel::ReliableOrdered, payload);
self.send_message(get_default_game_channel(), payload);
}

fn receive_game_message(&mut self) -> Result<ServerToClientMessage, Box<ErrorKind>> {
let payload = self.receive_message(DefaultChannel::ReliableOrdered);
let payload = self.receive_message(get_default_game_channel());
if let Some(payload) = payload {
// debug!("Received payload: {:?}", payload);
let res = shared::payload_to_game_message::<ServerToClientMessage>(&payload);
Expand Down
15 changes: 0 additions & 15 deletions client/src/network/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,6 @@ pub fn launch_local_server_system(
}
}

// fn poll_reliable_ordered_messages(
// _client: &mut ResMut<RenetClient>,
// _chat_state: &mut ResMut<CachedChatConversation>,
// ) {
// while let Some(message) = client.receive_game_message(DefaultChannel::ReliableOrdered) {
// let message = bincode::options().deserialize::<ChatConversation>(&message);
// match message {
// Ok(data) => {
// update_cached_chat_state(chat_state, data);
// }
// Err(e) => error!("err {}", e),
// };
// }
// }

pub fn poll_network_messages(
mut client: ResMut<RenetClient>,
// mut chat_state: ResMut<CachedChatConversation>,
Expand Down
7 changes: 5 additions & 2 deletions server/src/network/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::init::{ServerLobby, ServerTime};
use crate::network::broadcast_chat::*;
use crate::network::broadcast_world::*;
use crate::world;
use crate::world::background_generation::background_world_generation_system;
use crate::world::broadcast_world::broadcast_world_state;
use crate::world::save::SaveRequestEvent;
use crate::world::simulation::{handle_player_inputs_system, PlayerInputsEvent};
use crate::world::BlockInteractionEvent;
use bevy::prelude::*;
use bevy_renet::renet::{RenetServer, ServerEvent};
Expand All @@ -15,7 +17,6 @@ use shared::world::ServerWorldMap;
use shared::{GameServerConfig, TICKS_PER_SECOND};

use super::extensions::SendGameMessageExtension;
use super::simulation::{handle_player_inputs_system, PlayerInputsEvent};

pub fn setup_resources_and_events(app: &mut App) {
app.add_event::<SaveRequestEvent>()
Expand All @@ -37,6 +38,8 @@ pub fn register_systems(app: &mut App) {

app.add_systems(Update, handle_player_inputs_system);

app.add_systems(Update, background_world_generation_system);

app.add_systems(PostUpdate, update_server_time);
}

Expand Down
10 changes: 5 additions & 5 deletions server/src/network/extensions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bevy::prelude::*;
use bevy_renet::renet::{ClientId, DefaultChannel, RenetServer};
use shared::utils::format_bytes;
use bevy_renet::renet::{ClientId, RenetServer};
use shared::{get_default_game_channel, utils::format_bytes};

pub trait SendGameMessageExtension {
fn send_game_message(
Expand All @@ -26,7 +26,7 @@ impl SendGameMessageExtension for RenetServer {
if size > (10 * 1024) {
info!("Sending game message of size: {}", format_bytes(size));
}
self.send_message(client_id, DefaultChannel::ReliableOrdered, payload);
self.send_message(client_id, get_default_game_channel(), payload);
}

fn broadcast_game_message(&mut self, message: shared::messages::ServerToClientMessage) {
Expand All @@ -35,14 +35,14 @@ impl SendGameMessageExtension for RenetServer {
if size > (10 * 1024) {
info!("Broadcasting game message of size: {}", format_bytes(size));
}
self.broadcast_message(DefaultChannel::ReliableOrdered, payload);
self.broadcast_message(get_default_game_channel(), payload);
}

fn receive_game_message(
&mut self,
client_id: ClientId,
) -> Result<shared::messages::ClientToServerMessage, Box<bincode::ErrorKind>> {
let payload = self.receive_message(client_id, DefaultChannel::ReliableOrdered);
let payload = self.receive_message(client_id, get_default_game_channel());
if let Some(payload) = payload {
// debug!("Received payload: {:?}", payload);
let msg = shared::payload_to_game_message::<shared::messages::ClientToServerMessage>(
Expand Down
2 changes: 0 additions & 2 deletions server/src/network/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
pub mod broadcast_chat;
pub mod broadcast_world;
pub mod dispatcher;
pub mod extensions;
pub mod simulation;
28 changes: 28 additions & 0 deletions server/src/world/background_generation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use bevy::prelude::*;
use shared::world::{ServerWorldMap, WorldSeed};

use crate::world::generation::generate_chunk;

use super::broadcast_world::{get_all_active_chunks, BROADCAST_RENDER_DISTANCE};

pub fn background_world_generation_system(
mut world_map: ResMut<ServerWorldMap>,
seed: Res<WorldSeed>,
) {
let all_chunks = get_all_active_chunks(&world_map, BROADCAST_RENDER_DISTANCE);
let mut generated = 0;
for c in all_chunks {
let chunk = world_map.map.get(&c);

if chunk.is_none() {
let chunk = generate_chunk(c, seed.0);
info!("Generated chunk: {:?}", c);
world_map.map.insert(c, chunk);
generated += 1;
}

if generated >= 1 {
break;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::init::ServerTime;
use crate::network::extensions::SendGameMessageExtension;
use crate::world::generation::generate_chunk;
use bevy::math::IVec3;
use bevy::prelude::*;
use bevy_ecs::system::ResMut;
Expand All @@ -10,20 +9,19 @@ use shared::players::Player;
use shared::world::{world_position_to_chunk_position, ServerChunk, ServerWorldMap};
use std::collections::HashMap;

use shared::world::data::WorldSeed;
pub const BROADCAST_RENDER_DISTANCE: i32 = 2;

pub fn broadcast_world_state(
mut server: ResMut<RenetServer>,
time: Res<ServerTime>,
mut world_map: ResMut<ServerWorldMap>,
seed: Res<WorldSeed>,
) {
let ts = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64;

for c in get_all_active_chunks(&world_map) {
for c in get_all_active_chunks(&world_map, BROADCAST_RENDER_DISTANCE) {
let chunk = world_map.map.get(&c);

if chunk.is_none() {
Expand All @@ -36,7 +34,7 @@ pub fn broadcast_world_state(
tick: time.0,
time: ts,
player_positions: get_player_positions(&world_map),
new_map: get_world_map_chunks_to_send(&mut world_map, &seed, &player),
new_map: get_world_map_chunks_to_send(&mut world_map, &player),
mobs: world_map.mobs.clone(),
item_stacks: get_items_stacks(&world_map),
player_events: vec![],
Expand Down Expand Up @@ -66,13 +64,12 @@ fn get_player_positions(world_map: &ServerWorldMap) -> HashMap<u64, Vec3> {

fn get_world_map_chunks_to_send(
world_map: &mut ServerWorldMap,
seed: &WorldSeed,
player: &Player,
) -> HashMap<IVec3, ServerChunk> {
// Send only chunks in render distance
let mut map: HashMap<IVec3, ServerChunk> = HashMap::new();

let active_chunks = get_all_active_chunks(world_map);
let active_chunks = get_all_active_chunks(world_map, BROADCAST_RENDER_DISTANCE);
for c in active_chunks {
if map.len() >= 10 {
break;
Expand All @@ -88,15 +85,6 @@ fn get_world_map_chunks_to_send(

map.insert(c, chunk.clone());
chunk.sent_to_clients.push(player.id);
} else {
// If chunk does not exists, generate it before transmitting it
let mut chunk = generate_chunk(c, seed.0);
chunk.sent_to_clients.push(player.id);

info!("Generated chunk: {:?}", c);

map.insert(c, chunk.clone());
world_map.map.insert(c, chunk);
}
}

Expand All @@ -118,14 +106,12 @@ fn get_items_stacks(world_map: &ServerWorldMap) -> Vec<ItemStackUpdateEvent> {
.collect()
}

const RENDER_DISTANCE: i32 = 2;

pub fn get_all_active_chunks(world_map: &ServerWorldMap) -> Vec<IVec3> {
pub fn get_all_active_chunks(world_map: &ServerWorldMap, radius: i32) -> Vec<IVec3> {
let player_chunks: Vec<IVec3> = world_map
.players
.values()
.map(|v| world_position_to_chunk_position(v.position))
.flat_map(|v| get_player_nearby_chunks_coords(v, RENDER_DISTANCE))
.flat_map(|v| get_player_nearby_chunks_coords(v, radius))
.collect();

let mut chunks: Vec<IVec3> = Vec::new();
Expand Down
3 changes: 0 additions & 3 deletions server/src/world/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,4 @@ pub const SAVE_PATH: &str = "saves/";
#[derive(Serialize, Deserialize)]
pub struct Save {
pub map: HashMap<IVec3, ServerChunk>,
// pub player_pos: Vec3,
// pub inventory: HashMap<RegistryId, Item>,
// pub id_to_item: HashMap<RegistryId, String>,
}
3 changes: 3 additions & 0 deletions server/src/world/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
pub mod background_generation;
pub mod broadcast_world;
mod data;
pub mod generation;
pub mod load_from_file;
pub mod save;
pub mod simulation;
pub mod stacks;

use bevy::prelude::Event;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn handle_player_inputs_system(
mut server: ResMut<RenetServer>,
seed: Res<WorldSeed>,
) {
let active_chunks = get_all_active_chunks(&world_map);
let active_chunks = get_all_active_chunks(&world_map, 1);
for c in active_chunks {
let chunk = world_map.map.get(&c);

Expand Down
24 changes: 15 additions & 9 deletions shared/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::time::Duration;

use bevy::prelude::*;
use bevy_renet::renet::{ChannelConfig, ConnectionConfig, SendType};
use bevy_renet::renet::{ChannelConfig, ConnectionConfig, DefaultChannel, SendType};
use bincode::Options;

pub mod constants;
Expand Down Expand Up @@ -65,15 +65,17 @@ pub fn get_shared_renet_config() -> ConnectionConfig {

pub fn game_message_to_payload<T: serde::Serialize>(message: T) -> Vec<u8> {
let payload = bincode::options().serialize(&message).unwrap();
debug!(
"Original payload size: {}",
format_bytes(payload.len() as u64)
);
let output = lz4::block::compress(&payload, None, true).unwrap();
debug!(
"Compressed payload of size: {}",
format_bytes(output.len() as u64)
);
if payload.len() > 1024 {
debug!(
"Original payload size: {}",
format_bytes(payload.len() as u64)
);
debug!(
"Compressed payload of size: {}",
format_bytes(output.len() as u64)
);
}
output
}

Expand All @@ -83,3 +85,7 @@ pub fn payload_to_game_message<T: serde::de::DeserializeOwned>(
let decompressed_payload = lz4::block::decompress(payload, None)?;
bincode::options().deserialize(&decompressed_payload)
}

pub fn get_default_game_channel() -> DefaultChannel {
DefaultChannel::ReliableUnordered
}

0 comments on commit 66336ea

Please sign in to comment.