Skip to content

Commit

Permalink
Chunk: Use Air if block is not found
Browse files Browse the repository at this point in the history
So currently we trough an error and don't load the entire chunk if a block is not found in the registry, Which is often the case when loading worlds from older or newer version than Currently supported. So now we will just not load the not founded blocks and load blocks which we found
  • Loading branch information
Snowiiii committed Oct 27, 2024
1 parent d9fcbf6 commit 79d2f91
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 30 deletions.
14 changes: 5 additions & 9 deletions pumpkin-world/src/block/block_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,28 +74,24 @@ struct Shape {

#[derive(Default, Copy, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(transparent)]
pub struct BlockId {
pub data: u16,
}
pub struct BlockId(pub u16);

impl BlockId {
pub fn is_air(&self) -> bool {
self.data == 0 || self.data == 12959 || self.data == 12958
self.0 == 0 || self.0 == 12959 || self.0 == 12958
}

pub fn get_id_mojang_repr(&self) -> i32 {
self.data as i32
self.0 as i32
}

pub fn get_id(&self) -> u16 {
self.data
self.0
}
}

impl From<BlockState> for BlockId {
fn from(value: BlockState) -> Self {
Self {
data: value.get_id(),
}
Self(value.get_id())
}
}
11 changes: 5 additions & 6 deletions pumpkin-world/src/block/block_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ impl BlockState {
pub const AIR: BlockState = BlockState { state_id: 0 };

pub fn new(registry_id: &str) -> Result<Self, BlockStateError> {
let block_registry =
get_block(registry_id).ok_or(BlockStateError::BlockIdentifierNotFound)?;
let block_registry = get_block(registry_id).ok_or(
BlockStateError::BlockIdentifierNotFound(registry_id.to_string()),
)?;
Ok(Self {
state_id: block_registry.default_state_id,
})
Expand All @@ -29,8 +30,6 @@ impl BlockState {

#[derive(Error, Debug)]
pub enum BlockStateError {
#[error("The requested block identifier does not exist")]
BlockIdentifierNotFound,
#[error("The requested block state id does not exist")]
BlockStateIdNotFound,
#[error("The requested block identifier does not exist {0}")]
BlockIdentifierNotFound(String),
}
12 changes: 6 additions & 6 deletions pumpkin-world/src/chunk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,11 @@ impl ChunkData {
.palette
.iter()
.map(|entry| match BlockState::new(&entry.name) {
Err(e) => Err(e),
Ok(state) => Ok(state.into()),
// Block not found, Often the case when World has an newer or older version then block registry
Err(_) => BlockState::AIR,
Ok(state) => state,
})
.collect::<Result<Vec<_>, _>>()
.map_err(ChunkParsingError::BlockStateError)?;
.collect::<Vec<_>>();

let block_data = match block_states.data {
None => {
Expand All @@ -275,7 +275,7 @@ impl ChunkData {
'block_loop: for block in block_data.iter() {
for i in 0..blocks_in_pallete {
let index = (block >> (i * block_bit_size)) & mask;
let block = palette[index as usize];
let block = &palette[index as usize];

// TODO allow indexing blocks directly so we can just use block_index and save some time?
// this is fine because we initalized the heightmap of `blocks`
Expand All @@ -286,7 +286,7 @@ impl ChunkData {
y: Height::from_absolute((block_index / CHUNK_AREA) as u16),
x: (block_index % 16).into(),
},
block,
BlockId(block.get_id()),
);

block_index += 1;
Expand Down
4 changes: 1 addition & 3 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 +621,7 @@ impl Player {
world
.set_block(
WorldPosition(location.0 + face.to_offset()),
BlockId {
data: block.default_state_id,
},
BlockId(block.default_state_id),
)
.await;
}
Expand Down
9 changes: 3 additions & 6 deletions pumpkin/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,11 +534,8 @@ impl World {
let chunk = self.receive_chunk(chunk_coordinate).await;
chunk.write().await.blocks.set_block(relative, block_id);

self.broadcast_packet_all(&CBlockUpdate::new(
&position,
i32::from(block_id.data).into(),
))
.await;
self.broadcast_packet_all(&CBlockUpdate::new(&position, i32::from(block_id.0).into()))
.await;
}

// Stream the chunks (don't collect them and then do stuff with them)
Expand All @@ -557,7 +554,7 @@ impl World {
}

pub async fn break_block(&self, position: WorldPosition) {
self.set_block(position, BlockId { data: 0 }).await;
self.set_block(position, BlockId(0)).await;

self.broadcast_packet_all(&CWorldEvent::new(2001, &position, 11, false))
.await;
Expand Down

0 comments on commit 79d2f91

Please sign in to comment.