From 8e73993adf80e867d24fd2681dd2e144369d322f Mon Sep 17 00:00:00 2001 From: Daniar Mannanov Date: Mon, 17 Aug 2026 10:18:18 +0300 Subject: [PATCH] Measure per-feature ore parity --- internal/world/region_ore_parity_test.go | 92 ++++++++++++++++++++++++ internal/world/region_ores.go | 7 ++ 2 files changed, 99 insertions(+) diff --git a/internal/world/region_ore_parity_test.go b/internal/world/region_ore_parity_test.go index c425ca0..16660f0 100644 --- a/internal/world/region_ore_parity_test.go +++ b/internal/world/region_ore_parity_test.go @@ -232,6 +232,98 @@ func TestRegionOreBiomeOrderDiagnostic(t *testing.T) { } } +func TestRegionOreFeatureContributionDiagnostic(t *testing.T) { + if os.Getenv("REGIONIO_ORE_FEATURE_DIAGNOSTIC") != "1" { + t.Skip("set REGIONIO_ORE_FEATURE_DIAGNOSTIC=1 to measure individual ore features") + } + fixtures, seed := loadOreFixtureChunks(t) + od, err := worldgen.LoadOverworldFinalDensity(seed) + if err != nil { + t.Fatal(err) + } + fluidPicker := worldgen.OverworldFluidPicker(od.SeaLevel) + veins := worldgen.NewOreVeinifier(od) + carver, err := worldgen.NewCarver(od, seed) + if err != nil { + t.Fatal(err) + } + initCarverReplaceable(carver.ReplaceableBlocks()) + set := mustFeatureSet(t) + steps, err := set.FeatureSteps(possibleBiomeOrder()) + if err != nil { + t.Fatal(err) + } + for featureIndex, feature := range steps[undergroundOresStage] { + placed := set.Placed[feature] + if set.Configured[placed.Feature].Type != "minecraft:ore" { + continue + } + generated := make(map[uint16]int) + matching := make(map[uint16]int) + columnMatching := make(map[uint16]int) + for _, fixture := range fixtures { + var chunks []*Chunk + for cx := fixture.x - 1; cx <= fixture.x+1; cx++ { + for cz := fixture.z - 1; cz <= fixture.z+1; cz++ { + chunks = append(chunks, generateVanillaWithoutDecoration(od, fluidPicker, veins, carver, seed, cx, cz)) + } + } + region, err := newDecorationRegion(chunks) + if err != nil { + t.Fatal(err) + } + if err := region.setSource(fixture.x, fixture.z); err != nil { + t.Fatal(err) + } + chunk := region.chunks[[2]int32{fixture.x, fixture.z}] + base := make([]uint16, len(fixture.blocks)) + for index := range base { + y := MinY + index/(16*16) + column := index % (16 * 16) + z, x := column/16, column%16 + base[index] = chunk.GetBlock(x, y, z) + } + if err := region.placeScheduledOresFiltered(seed, possibleBiomeOrder(), 0, map[string]bool{feature: true}); err != nil { + t.Fatal(err) + } + vanillaColumns := make(map[[3]int]bool) + for index, state := range fixture.blocks { + column := index % (16 * 16) + z, x := column/16, column%16 + vanillaColumns[[3]int{int(state), x, z}] = true + } + for index, want := range fixture.blocks { + y := MinY + index/(16*16) + column := index % (16 * 16) + z, x := column/16, column%16 + got := chunk.GetBlock(x, y, z) + if got != base[index] { + generated[got]++ + if got == want { + matching[got]++ + } + if vanillaColumns[[3]int{int(got), x, z}] { + columnMatching[got]++ + } + } + } + } + var total, exact, columns, oreTotal, oreExact, oreColumns int + for state, count := range generated { + total += count + exact += matching[state] + columns += columnMatching[state] + if isOreState(state) { + oreTotal += count + oreExact += matching[state] + oreColumns += columnMatching[state] + } + } + t.Logf("%s index=%d changed=%d exact=%d same_column=%d generated_ore=%d ore_exact=%d ore_same_column=%d", + feature, featureIndex, total, exact, columns, oreTotal, oreExact, oreColumns) + } +} + type oreFixtureChunk struct { x, z int32 blocks []uint16 diff --git a/internal/world/region_ores.go b/internal/world/region_ores.go index fc105a4..6809909 100644 --- a/internal/world/region_ores.go +++ b/internal/world/region_ores.go @@ -11,6 +11,10 @@ func (r *decorationRegion) placeScheduledOresAtOffset(seed int64, featureIndexOf } func (r *decorationRegion) placeScheduledOresWithOrder(seed int64, biomeOrder []string, featureIndexOffset int) error { + return r.placeScheduledOresFiltered(seed, biomeOrder, featureIndexOffset, nil) +} + +func (r *decorationRegion) placeScheduledOresFiltered(seed int64, biomeOrder []string, featureIndexOffset int, include map[string]bool) error { set, err := worldgen.LoadFeatureSet() if err != nil { return err @@ -25,6 +29,9 @@ func (r *decorationRegion) placeScheduledOresWithOrder(seed int64, biomeOrder [] random, decorationSeed := worldgen.DecorationRandom(seed, int(r.sourceX), int(r.sourceZ)) origin := worldgen.FeaturePosition{X: int(r.sourceX) << 4, Y: MinY, Z: int(r.sourceZ) << 4} for _, scheduled := range schedule { + if include != nil && !include[scheduled.Name] { + continue + } placed := set.Placed[scheduled.Name] configured := set.Configured[placed.Feature] if configured.Type != "minecraft:ore" {