Surface rules: an empty biome list keeps the name lookup

An empty `biome_is` list on a surface that does not number its biomes
compiled to the id comparison, since collecting no indices never asks
`biome_index`. It then failed with MissingBiomeProvider where vanilla and
main answer false (material_condition's codec-corpus condition 49). It
keeps the name lookup main uses. Review on #3366.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ThatCakeIsAPieandClaude Opus 5.5 committed 2026-10-29 10:41:38 -05:00
1 parent 84185641bc
commit 52cc53a4f9
2 files changed
+21 -1

No files matched your search

@@ -442,6 +442,9 @@ impl<R: RandomSource> Compiled<R> {
match &context.possible_biomes {
Some(possible) if names.is_disjoint(possible) => Kind::Constant(false),
Some(possible) if possible.is_subset(&names) => Kind::Constant(true),
// An empty list would not ask whether the surface numbers
// its biomes.
_ if names.is_empty() => Kind::Biome(names),
_ => match names
.iter()
.map(|name| context.surface.biome_index(name))
@@ -23,10 +23,11 @@ struct Queries {
biomes: usize,
fail_binding: bool,
fail_temperature: bool,
any_biome: bool,
}
impl MaterialSurfaceQueries for Queries {
fn possible_biomes(&self) -> Option<BTreeSet<String>> {
Some(BTreeSet::from(["minecraft:plains".into()]))
(!self.any_biome).then(|| BTreeSet::from(["minecraft:plains".into()]))
}
fn surface_depth(&mut self, _: i32, _: i32) -> i32 {
1
@@ -117,6 +118,22 @@ fn constant_branches_keep_binding_order_and_short_circuit_queries() {
assert_eq!(q.temperatures, 0);
}
#[test]
fn an_empty_biome_list_matches_nothing_on_a_surface_without_biome_ids() {
let mut w = worker(Queries {
any_biome: true,
..Queries::default()
});
let rule = w
.add_rule(condition(
MaterialCondition::Biome(Vec::new()),
MaterialRule::Block(BlockStateId(9)),
))
.unwrap();
w.update_xz(4, 5, 0, 0);
w.update_y(1, 1, i32::MIN, 64);
assert_eq!(w.try_apply(rule, BlockPos::new(4, 64, 5)), Ok(None));
}
#[test]
fn unreachable_children_still_fail_compilation_without_adding_a_rule() {
for preceding_block in [false, true] {
let mut w = worker(Queries {