Fix the bedrock floor ramp and add a gendump check for it
bedrockAt had two bugs that cancelled into a deterministic, wrong-looking floor. It took its chunkRand by value, so next() mutated a copy and all four layers drew the same 32-bit number. The layers were then decided by successive bits of that one draw, nesting them into a prefix condition instead of scattering them independently. Its ramp also ran backwards. The comment claimed d=1 -> 50% decaying upward, but `keep := 5 - d` requires more bits set the *lower* the layer, giving 1/16 at the floor and 1/2 four blocks up — bedrock was likelier further from the bottom. Vanilla ramps probability linearly from 1 at y=-64 to 0 at y=-59 and tests nextFloat() < probability, which is what it does now. Only fillLegacySurface reaches this; the normal path lets the surface rule tree place the floor from the same datapack vertical_gradient rule. Both should agree. cmd/gendump is new here: a client-free diagnostic that reports biome distribution, top surface blocks, subsurface banding, deep-layer composition and an ASCII cross-section, so generator defects can be seen without launching a client. Its bedrock-band check prints per-layer counts and fails on any air or water in the floor. On chunk (0,0) at seed 12345 it now reports y=-64 fully bedrock, 207/154/106/66 thinning above it, and zero air or water. The same output also shows the missing subsurface banding — grass sits directly on stone — which is a separate defect in above_preliminary_surface, not fixed here.
This commit is contained in:
parent
c399070f59
commit
0a2845fa76
2 changed files with 275 additions and 19 deletions
|
|
@ -254,7 +254,7 @@ func fillLegacySurface(out *[WorldHeight]uint16, solid [WorldHeight]bool, top in
|
|||
switch {
|
||||
case y <= MinY:
|
||||
out[i] = StateBedrock
|
||||
case y <= MinY+4 && solid[i] && bedrockAt(rng, y-MinY):
|
||||
case y <= MinY+4 && solid[i] && bedrockAt(&rng, y-MinY):
|
||||
out[i] = StateBedrock
|
||||
case solid[i]:
|
||||
switch {
|
||||
|
|
@ -275,26 +275,27 @@ func fillLegacySurface(out *[WorldHeight]uint16, solid [WorldHeight]bool, top in
|
|||
}
|
||||
}
|
||||
|
||||
// bedrockAt reports whether a block at layer d (1..4 above the floor) should be
|
||||
// bedrock, consuming randomness from rng. Vanilla's floor has probability ~1 at
|
||||
// the bottom layer dropping to 0 a few blocks up; we approximate the decay with
|
||||
// a 1/4 chance per step up from the solid floor.
|
||||
func bedrockAt(rng chunkRand, d int) bool {
|
||||
// Probability per layer: d=1 → 50%, d=2 → 25%, d=3 → 12.5%, d=4 → 6.25%.
|
||||
// Need (5-d) high bits from a 32-bit draw; compare against a per-step mask.
|
||||
keep := 5 - d // 4..1
|
||||
if keep <= 0 {
|
||||
// bedrockAt reports whether the block d layers above the world floor should be
|
||||
// bedrock, consuming one draw from rng. It mirrors the datapack's
|
||||
// vertical_gradient(minecraft:bedrock_floor, above_bottom 0 → above_bottom 5):
|
||||
// the probability ramps linearly from 1 at the floor to 0 five blocks up, and
|
||||
// vanilla tests nextFloat() < probability.
|
||||
//
|
||||
// rng is a pointer so successive layers draw successive values. Taking it by
|
||||
// value handed every layer the same number, which nested the layers into a
|
||||
// prefix condition instead of scattering them. The ramp also used to run the
|
||||
// wrong way — bedrock was likelier four blocks up than at the floor.
|
||||
//
|
||||
// Only fillLegacySurface calls this; the normal path lets the surface rule tree
|
||||
// place the floor from the same datapack rule.
|
||||
func bedrockAt(rng *chunkRand, d int) bool {
|
||||
if d <= 0 {
|
||||
return true
|
||||
}
|
||||
if d >= 5 {
|
||||
return false
|
||||
}
|
||||
// Each surviving bit roughly halves the chance; draw once and check `keep`
|
||||
// of its low bits.
|
||||
r := rng.next()
|
||||
for b := 0; b < keep; b++ {
|
||||
if (r>>uint(b))&1 == 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return rng.nextFloat() < 1.0-float64(d)/5.0
|
||||
}
|
||||
|
||||
// decorate places simple oak trees on grassy columns. Trunks are kept two
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue