native_world_read: a block's bounds are its world's

main's read_block took the build range from Dim::min_y and max_y, which
this branch replaces with each level's shape: it now reads the bounds
of the world it reads from (the level's own, data packs included).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Ludovic MarieandClaude Opus 5.5 committed 2026-10-30 15:01:35 +01:00
1 parent 32bb54e90c
commit 736d22009e
1 file changed
+12 -9
@@ -41,20 +41,19 @@ impl Game<'_> {
self.levels.parked_world(dim)
}
.ok_or(NativeBlockReadError::UnavailableDimension)?;
read_block(world, dim, self.pack.assets.registry, pos)
read_block(world, self.pack.assets.registry, pos)
}
}
/// Resolve an existing world state, preserving unloaded and invalid states.
fn read_block(
world: &World,
dimension: Dim,
registry: &BlockRegistry,
[x, y, z]: [i32; 3],
) -> Result<BlockState, NativeBlockReadError> {
if !(-30_000_000..30_000_000).contains(&x)
|| !(-30_000_000..30_000_000).contains(&z)
|| !(dimension.min_y()..=dimension.max_y()).contains(&y)
|| !(world.shape.min_y..world.shape.max_y()).contains(&y)
{
return Err(NativeBlockReadError::OutOfBounds);
}
@@ -84,30 +83,34 @@ mod tests {
let mut world = World::new(BlockStateId(0), 0);
world.chunks.insert((-1, 0), Arc::new(Chunk::empty(-1, 0)));
world.set(-1, 64, 1, BlockStateId(1)).unwrap();
let block = read_block(&world, Dim::Overworld, &registry, [-1, 64, 1]).unwrap();
// The Nether's build range starts at y 0 (its level's shape).
let mut nether = World::new(BlockStateId(0), 0);
nether.shape = horizon_client::chunk::LevelShape::NETHER;
nether.chunks.insert((-1, 0), Arc::new(Chunk::empty(-1, 0)));
let block = read_block(&world, &registry, [-1, 64, 1]).unwrap();
assert_eq!(block.name, "test:pillar");
assert_eq!(block.properties["axis"], "x");
assert_eq!(
read_block(&world, Dim::Overworld, &registry, [-1, 65, 1])
read_block(&world, &registry, [-1, 65, 1])
.unwrap()
.name,
"minecraft:air"
);
assert_eq!(
read_block(&world, Dim::Overworld, &registry, [0, 64, 1]),
read_block(&world, &registry, [0, 64, 1]),
Err(NativeBlockReadError::Unloaded)
);
assert_eq!(
read_block(&world, Dim::Nether, &registry, [-1, -1, 1]),
read_block(&nether, &registry, [-1, -1, 1]),
Err(NativeBlockReadError::OutOfBounds)
);
assert_eq!(
read_block(&world, Dim::Overworld, &registry, [30_000_000, 64, 1]),
read_block(&world, &registry, [30_000_000, 64, 1]),
Err(NativeBlockReadError::OutOfBounds)
);
world.set(-1, 64, 1, BlockStateId(99)).unwrap();
assert_eq!(
read_block(&world, Dim::Overworld, &registry, [-1, 64, 1]),
read_block(&world, &registry, [-1, 64, 1]),
Err(NativeBlockReadError::InvalidState)
);
assert_eq!(world.chunks.len(), 1, "reads must not load chunks");