From 8db382c1127c0257d9c5a3caa0941ca66e0cd0c2 Mon Sep 17 00:00:00 2001 From: Patrick Owen Date: Fri, 27 Oct 2023 19:34:23 -0400 Subject: [PATCH] Allow clients to handle block updates for unloaded chunks --- client/src/graphics/voxels/mod.rs | 9 +++++++++ client/src/sim.rs | 10 +++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/client/src/graphics/voxels/mod.rs b/client/src/graphics/voxels/mod.rs index f824d6df..ec72970a 100644 --- a/client/src/graphics/voxels/mod.rs +++ b/client/src/graphics/voxels/mod.rs @@ -103,6 +103,15 @@ impl Voxels { let chunk_id = ChunkId::new(chunk.node, chunk.chunk); sim.graph .populate_chunk(sim.cfg.chunk_size, chunk_id, chunk.voxels, false); + + // Now that the block is populated, we can apply any pending block updates the server + // provided that the client couldn't apply. + if let Some(block_updates) = sim.pending_modified_chunks.remove(&chunk_id) { + for block_update in block_updates { + // The chunk was just populated, so a block update should always succeed. + assert!(sim.graph.update_block(sim.cfg.chunk_size, &block_update)); + } + } } // Determine what to load/render diff --git a/client/src/sim.rs b/client/src/sim.rs index 7314c058..5a8dffa9 100644 --- a/client/src/sim.rs +++ b/client/src/sim.rs @@ -12,7 +12,7 @@ use common::{ collision_math::Ray, graph::{Graph, NodeId}, graph_ray_casting, - node::{populate_fresh_nodes, VoxelData}, + node::{populate_fresh_nodes, ChunkId, VoxelData}, proto::{ self, BlockUpdate, Character, CharacterInput, CharacterState, Command, Component, Position, }, @@ -25,6 +25,7 @@ use common::{ pub struct Sim { // World state pub graph: Graph, + pub pending_modified_chunks: FxHashMap>, pub graph_entities: GraphEntities, entity_ids: FxHashMap, pub world: hecs::World, @@ -67,6 +68,7 @@ impl Sim { populate_fresh_nodes(&mut graph); Self { graph, + pending_modified_chunks: FxHashMap::default(), graph_entities: GraphEntities::new(), entity_ids: FxHashMap::default(), world: hecs::World::new(), @@ -301,8 +303,10 @@ impl Sim { populate_fresh_nodes(&mut self.graph); for block_update in msg.block_updates.into_iter() { if !self.graph.update_block(self.cfg.chunk_size, &block_update) { - // TODO: This case should be handled to properly support multiple players. - tracing::error!("Voxel data received from server for ungenerated chunk.") + self.pending_modified_chunks + .entry(block_update.chunk_id) + .or_default() + .push(block_update); } } for (chunk_id, voxel_data) in msg.modified_chunks {