diff --git a/src/chunk.rs b/src/chunk.rs index a710367..49521b1 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -27,15 +27,18 @@ use crate::Ticks; /// A container for all [`Chunks`]s in a [`World`](crate::world::World). pub struct Chunks { chunks: HashMap>, - server: SharedServer, + shared: SharedServer, dimension: DimensionId, } impl Chunks { - pub(crate) fn new(server: SharedServer, dimension: DimensionId) -> Self { + pub(crate) fn new( + shared: SharedServer, + dimension: DimensionId, + ) -> Self { Self { chunks: HashMap::new(), - server, + shared, dimension, } } @@ -51,8 +54,14 @@ impl Chunks { /// are not spawned within unloaded chunks via /// [`spawn`](crate::client::Client::spawn). pub fn insert(&mut self, pos: impl Into, state: C::ChunkState) -> &mut Chunk { - let section_count = (self.server.dimension(self.dimension).height / 16) as u32; - let chunk = Chunk::new(section_count, self.server.current_tick(), state); + let section_count = (self.shared.dimension(self.dimension).height / 16) as u32; + let biome_registry_len = self.shared.biomes().len(); + let chunk = Chunk::new( + section_count, + self.shared.current_tick(), + biome_registry_len, + state, + ); match self.chunks.entry(pos.into()) { Entry::Occupied(mut oe) => { @@ -140,7 +149,7 @@ impl Chunks { let chunk = self.get(chunk_pos)?; - let min_y = self.server.dimension(self.dimension).min_y; + let min_y = self.shared.dimension(self.dimension).min_y; let y = pos.y.checked_sub(min_y)?.try_into().ok()?; @@ -168,7 +177,7 @@ impl Chunks { let chunk_pos = ChunkPos::from(pos); if let Some(chunk) = self.chunks.get_mut(&chunk_pos) { - let min_y = self.server.dimension(self.dimension).min_y; + let min_y = self.shared.dimension(self.dimension).min_y; if let Some(y) = pos.y.checked_sub(min_y).and_then(|y| y.try_into().ok()) { if y < chunk.height() { @@ -203,7 +212,12 @@ pub struct Chunk { } impl Chunk { - pub(crate) fn new(section_count: u32, current_tick: Ticks, data: C::ChunkState) -> Self { + pub(crate) fn new( + section_count: u32, + current_tick: Ticks, + biome_registry_len: usize, + data: C::ChunkState, + ) -> Self { let sect = ChunkSection { blocks: [BlockState::AIR.to_raw(); 4096], modified_count: 1, // Must be >0 so the chunk is initialized. @@ -218,7 +232,7 @@ impl Chunk { created_tick: current_tick, }; - chunk.apply_modifications(); + chunk.apply_modifications(biome_registry_len); chunk } @@ -363,7 +377,7 @@ impl Chunk { } } - pub(crate) fn apply_modifications(&mut self) { + pub(crate) fn apply_modifications(&mut self, biome_registry_len: usize) { let mut any_modified = false; for sect in self.sections.iter_mut() { @@ -388,18 +402,16 @@ impl Chunk { sect.blocks.iter().cloned(), 4, 9, - log2_ceil((BlockState::max_raw() + 1) as usize), + log2_ceil(BlockState::max_raw() as usize), &mut sect.compact_data, ) .unwrap(); - // TODO: The direct bits per idx changes depending on the number of biomes in - // the biome registry. encode_paletted_container( sect.biomes.iter().map(|b| b.0), 0, 4, - 6, + log2_ceil(biome_registry_len), &mut sect.compact_data, ) .unwrap(); @@ -557,5 +569,6 @@ fn encode_paletted_container( /// Calculates the log base 2 rounded up. fn log2_ceil(n: usize) -> usize { + debug_assert_ne!(n, 0); n.next_power_of_two().trailing_zeros() as usize } diff --git a/src/server.rs b/src/server.rs index ab5d037..047d57f 100644 --- a/src/server.rs +++ b/src/server.rs @@ -441,7 +441,7 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult { // Chunks created this tick can have their changes applied immediately because // they have not been observed by clients yet. Clients will not have to be sent // the block change packet in this case. - chunk.apply_modifications(); + chunk.apply_modifications(server.shared.biomes().len()); } }); @@ -461,7 +461,7 @@ fn do_update_loop(server: &mut Server) -> ShutdownResult { server.worlds.par_iter_mut().for_each(|(_, world)| { world.chunks.par_iter_mut().for_each(|(_, chunk)| { - chunk.apply_modifications(); + chunk.apply_modifications(server.shared.biomes().len()); }); }); diff --git a/src/world.rs b/src/world.rs index a5be196..947d401 100644 --- a/src/world.rs +++ b/src/world.rs @@ -14,7 +14,7 @@ use crate::spatial_index::SpatialIndex; /// A container for all [`World`]s on a [`Server`](crate::server::Server). pub struct Worlds { slab: VersionedSlab>, - server: SharedServer, + shared: SharedServer, } /// An identifier for a [`World`] on the server. @@ -35,10 +35,10 @@ impl WorldId { } impl Worlds { - pub(crate) fn new(server: SharedServer) -> Self { + pub(crate) fn new(shared: SharedServer) -> Self { Self { slab: VersionedSlab::new(), - server, + shared, } } @@ -48,7 +48,7 @@ impl Worlds { let (id, world) = self.slab.insert(World { state, spatial_index: SpatialIndex::new(), - chunks: Chunks::new(self.server.clone(), dim), + chunks: Chunks::new(self.shared.clone(), dim), meta: WorldMeta { dimension: dim }, });