mirror of
https://github.com/italicsjenga/valence.git
synced 2025-01-26 05:26:34 +11:00
Direct bits per idx for biomes depends on the size of the biome registry
This commit is contained in:
parent
003c2e3649
commit
e27144bc01
3 changed files with 33 additions and 20 deletions
41
src/chunk.rs
41
src/chunk.rs
|
@ -27,15 +27,18 @@ use crate::Ticks;
|
||||||
/// A container for all [`Chunks`]s in a [`World`](crate::world::World).
|
/// A container for all [`Chunks`]s in a [`World`](crate::world::World).
|
||||||
pub struct Chunks<C: Config> {
|
pub struct Chunks<C: Config> {
|
||||||
chunks: HashMap<ChunkPos, Chunk<C>>,
|
chunks: HashMap<ChunkPos, Chunk<C>>,
|
||||||
server: SharedServer<C>,
|
shared: SharedServer<C>,
|
||||||
dimension: DimensionId,
|
dimension: DimensionId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Config> Chunks<C> {
|
impl<C: Config> Chunks<C> {
|
||||||
pub(crate) fn new(server: SharedServer<C>, dimension: DimensionId) -> Self {
|
pub(crate) fn new(
|
||||||
|
shared: SharedServer<C>,
|
||||||
|
dimension: DimensionId,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
chunks: HashMap::new(),
|
chunks: HashMap::new(),
|
||||||
server,
|
shared,
|
||||||
dimension,
|
dimension,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,8 +54,14 @@ impl<C: Config> Chunks<C> {
|
||||||
/// are not spawned within unloaded chunks via
|
/// are not spawned within unloaded chunks via
|
||||||
/// [`spawn`](crate::client::Client::spawn).
|
/// [`spawn`](crate::client::Client::spawn).
|
||||||
pub fn insert(&mut self, pos: impl Into<ChunkPos>, state: C::ChunkState) -> &mut Chunk<C> {
|
pub fn insert(&mut self, pos: impl Into<ChunkPos>, state: C::ChunkState) -> &mut Chunk<C> {
|
||||||
let section_count = (self.server.dimension(self.dimension).height / 16) as u32;
|
let section_count = (self.shared.dimension(self.dimension).height / 16) as u32;
|
||||||
let chunk = Chunk::new(section_count, self.server.current_tick(), state);
|
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()) {
|
match self.chunks.entry(pos.into()) {
|
||||||
Entry::Occupied(mut oe) => {
|
Entry::Occupied(mut oe) => {
|
||||||
|
@ -140,7 +149,7 @@ impl<C: Config> Chunks<C> {
|
||||||
|
|
||||||
let chunk = self.get(chunk_pos)?;
|
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()?;
|
let y = pos.y.checked_sub(min_y)?.try_into().ok()?;
|
||||||
|
|
||||||
|
@ -168,7 +177,7 @@ impl<C: Config> Chunks<C> {
|
||||||
let chunk_pos = ChunkPos::from(pos);
|
let chunk_pos = ChunkPos::from(pos);
|
||||||
|
|
||||||
if let Some(chunk) = self.chunks.get_mut(&chunk_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 let Some(y) = pos.y.checked_sub(min_y).and_then(|y| y.try_into().ok()) {
|
||||||
if y < chunk.height() {
|
if y < chunk.height() {
|
||||||
|
@ -203,7 +212,12 @@ pub struct Chunk<C: Config> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Config> Chunk<C> {
|
impl<C: Config> Chunk<C> {
|
||||||
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 {
|
let sect = ChunkSection {
|
||||||
blocks: [BlockState::AIR.to_raw(); 4096],
|
blocks: [BlockState::AIR.to_raw(); 4096],
|
||||||
modified_count: 1, // Must be >0 so the chunk is initialized.
|
modified_count: 1, // Must be >0 so the chunk is initialized.
|
||||||
|
@ -218,7 +232,7 @@ impl<C: Config> Chunk<C> {
|
||||||
created_tick: current_tick,
|
created_tick: current_tick,
|
||||||
};
|
};
|
||||||
|
|
||||||
chunk.apply_modifications();
|
chunk.apply_modifications(biome_registry_len);
|
||||||
chunk
|
chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +377,7 @@ impl<C: Config> Chunk<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn apply_modifications(&mut self) {
|
pub(crate) fn apply_modifications(&mut self, biome_registry_len: usize) {
|
||||||
let mut any_modified = false;
|
let mut any_modified = false;
|
||||||
|
|
||||||
for sect in self.sections.iter_mut() {
|
for sect in self.sections.iter_mut() {
|
||||||
|
@ -388,18 +402,16 @@ impl<C: Config> Chunk<C> {
|
||||||
sect.blocks.iter().cloned(),
|
sect.blocks.iter().cloned(),
|
||||||
4,
|
4,
|
||||||
9,
|
9,
|
||||||
log2_ceil((BlockState::max_raw() + 1) as usize),
|
log2_ceil(BlockState::max_raw() as usize),
|
||||||
&mut sect.compact_data,
|
&mut sect.compact_data,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// TODO: The direct bits per idx changes depending on the number of biomes in
|
|
||||||
// the biome registry.
|
|
||||||
encode_paletted_container(
|
encode_paletted_container(
|
||||||
sect.biomes.iter().map(|b| b.0),
|
sect.biomes.iter().map(|b| b.0),
|
||||||
0,
|
0,
|
||||||
4,
|
4,
|
||||||
6,
|
log2_ceil(biome_registry_len),
|
||||||
&mut sect.compact_data,
|
&mut sect.compact_data,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -557,5 +569,6 @@ fn encode_paletted_container(
|
||||||
|
|
||||||
/// Calculates the log base 2 rounded up.
|
/// Calculates the log base 2 rounded up.
|
||||||
fn log2_ceil(n: usize) -> usize {
|
fn log2_ceil(n: usize) -> usize {
|
||||||
|
debug_assert_ne!(n, 0);
|
||||||
n.next_power_of_two().trailing_zeros() as usize
|
n.next_power_of_two().trailing_zeros() as usize
|
||||||
}
|
}
|
||||||
|
|
|
@ -441,7 +441,7 @@ fn do_update_loop<C: Config>(server: &mut Server<C>) -> ShutdownResult {
|
||||||
// Chunks created this tick can have their changes applied immediately because
|
// 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
|
// they have not been observed by clients yet. Clients will not have to be sent
|
||||||
// the block change packet in this case.
|
// 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<C: Config>(server: &mut Server<C>) -> ShutdownResult {
|
||||||
|
|
||||||
server.worlds.par_iter_mut().for_each(|(_, world)| {
|
server.worlds.par_iter_mut().for_each(|(_, world)| {
|
||||||
world.chunks.par_iter_mut().for_each(|(_, chunk)| {
|
world.chunks.par_iter_mut().for_each(|(_, chunk)| {
|
||||||
chunk.apply_modifications();
|
chunk.apply_modifications(server.shared.biomes().len());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::spatial_index::SpatialIndex;
|
||||||
/// A container for all [`World`]s on a [`Server`](crate::server::Server).
|
/// A container for all [`World`]s on a [`Server`](crate::server::Server).
|
||||||
pub struct Worlds<C: Config> {
|
pub struct Worlds<C: Config> {
|
||||||
slab: VersionedSlab<World<C>>,
|
slab: VersionedSlab<World<C>>,
|
||||||
server: SharedServer<C>,
|
shared: SharedServer<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An identifier for a [`World`] on the server.
|
/// An identifier for a [`World`] on the server.
|
||||||
|
@ -35,10 +35,10 @@ impl WorldId {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Config> Worlds<C> {
|
impl<C: Config> Worlds<C> {
|
||||||
pub(crate) fn new(server: SharedServer<C>) -> Self {
|
pub(crate) fn new(shared: SharedServer<C>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
slab: VersionedSlab::new(),
|
slab: VersionedSlab::new(),
|
||||||
server,
|
shared,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ impl<C: Config> Worlds<C> {
|
||||||
let (id, world) = self.slab.insert(World {
|
let (id, world) = self.slab.insert(World {
|
||||||
state,
|
state,
|
||||||
spatial_index: SpatialIndex::new(),
|
spatial_index: SpatialIndex::new(),
|
||||||
chunks: Chunks::new(self.server.clone(), dim),
|
chunks: Chunks::new(self.shared.clone(), dim),
|
||||||
meta: WorldMeta { dimension: dim },
|
meta: WorldMeta { dimension: dim },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue