Commit graph

6 commits

Author SHA1 Message Date
Master290
3a255b52e1 Real badlands clay bands and a real biome temperature table
The bandlands rule cycled four terracotta colours off a per-column random draw.
Vanilla generates a 192-entry band table once per world, from a random source
named clay_bands, and reads it at the block's height shifted by the
clay_bands_offset noise. Brown, red and light grey terracotta were never placed
anywhere; the stripes were the wrong thickness and did not line up between
neighbouring columns. All seven colours now appear.

The temperature condition matched a hand-written list of eleven biome names.
Replacing it with the temperature field read out of the jar's 65 biome JSONs
fixes one of them: deep_frozen_ocean reads cold by name but its base
temperature is 0.5, so vanilla does not freeze it. taiga and the pine taigas
were the other way round -- excluded by name, and correctly so, but by
coincidence rather than by data.

Two parts of the vanilla calculation are left out and documented where they
belong: the height adjustment that cools peaks, and the "frozen" modifier that
warms scattered patches of frozen ocean. Both need PerlinSimplexNoise. Neither
is reachable from the overworld tree in a way that shows: the single condition
that consults temperature sits under a frozen_ocean biome check, below a water
check, and decides whether a hole in the ocean floor ices over. The snowy
mountain tops come from biome selection, not from here -- which is not what the
plan for this commit assumed.

The per-column *rand.Rand threaded through SurfaceContext goes away with the
old bandlands rule; nothing needs it now that vertical_gradient rolls
positionally.
2026-07-27 02:31:10 +03:00
Master290
c19e5f0e4f Bind the surface rule tree to the world seed
The tree was parsed once, globally, and shared by every world -- so every
condition that needs the seed simply did not work. Compiling it per RandomState
fixes four of them at once.

noise_threshold sampled a per-column random draw and pretended it was
"minecraft:surface"; the other six noises it names were unsupported and returned
false. Each condition now holds its own seeded noise, sampled once per column
into a small cache the way vanilla's LazyXZCondition does. Powder snow, packed
ice and ice appear in the dump for the first time; calcite, swamp water windows
and gravel patches have their conditions back too.

vertical_gradient tapered through a per-column RNG shared with the other rules.
Vanilla rolls a positional random at the exact block, from a factory named by
the rule. More importantly the anchor decoder read only above_bottom and
discarded which kind of anchor it was, so the deepslate rule's absolute 0..8
collapsed onto y=-64 and **no deepslate existed anywhere in the world**. Anchors
now carry their kind and resolve against the real height bounds -- which also
retires a hardcoded 384 in y_above.

Two more stubs land with them: hole is surfaceDepth <= 0 rather than a constant
false, and steep reads the neighbouring column heights. steep needs the whole
chunk's heightmap, so the column pass is now two passes -- terrain and fluids
for all 256 columns, then surface rules -- which is the order vanilla uses
anyway (doFill, then buildSurface).

Deepslate was also missing from the block-ID table, and an unknown name resolved
to 0, which the caller read as "no block" and skipped. So even a correct rule
would have placed nothing. Unknown names are now a parse error, deepslate and
mud are in the table, and a rule that resolves to air genuinely places air --
the frozen-ocean surface asks for exactly that.

Below y=0 is now entirely deepslate, y=1..7 a scatter, above y=8 none.
2026-07-27 02:25:09 +03:00
Master290
1083e47211 Restore the subsurface layers: real above_preliminary_surface and surface depth
Every land column was one block of grass sitting straight on stone. No dirt
under grass, no sandstone under sand, nothing. Two stubs did it together:

above_preliminary_surface compared blockY against the column's actual top block,
so of every position in the column exactly one passed -- and the entire
biome-specific half of the surface rule tree hangs under that condition.
Vanilla compares against a minimum surface level: the preliminary surface level
sampled at the four corners of the 16-block cell, bilinearly interpolated, plus
the surface depth less 8. That is about twenty blocks of reach on ordinary
terrain, which is what the biome subtree is written against.

Surface depth was hardcoded to 0. Vanilla is surfaceNoise*2.75 + 3 with a
per-column jitter, so it comes out around three; it sets how thick the band is
and feeds every add_surface_depth term in the tree. Zero collapsed them all.

Also samples surface_secondary, so stone_depth's secondary_depth_range widens
its band instead of being parsed and dropped.

Grass columns now read grass, two to four dirt, stone -- the histogram over 256
columns is {2: 223, 3: 33}, against vanilla's 2..4. gendump prints it and fails
if the band collapses again; TestGrassColumnsHaveDirt guards it in the suite.
2026-07-27 02:15:14 +03:00
Master290
ed045ee09d Parse aquifer and ore-vein noise routers
The overworld noise_router ships fourteen keys; we read six. The eight left on
the floor are exactly the ones the aquifer, the ore veins and the preliminary
surface estimate need, so every one of those subsystems has been impossible to
write.

Wire the rest of the router into OverworldDensity: barrier,
fluid_level_floodedness, fluid_level_spread and lava for the aquifer,
vein_toggle/vein_ridged/vein_gap for the veins, and preliminary_surface_level
for both. Two node types were missing and are added with them --
minecraft:invert (the reciprocal, not negation: Mapped.Type ordinal 5 is
1.0/input) and minecraft:find_top_surface, which walks down from an upper bound
in cell_height steps looking for positive density.

PreliminarySurfaceLevelAt wraps that node the way NoiseChunk does: quart-align
the column, then memoise. The cache is per generator rather than per chunk
because the aquifer samples columns up to three chunks away, so neighbours
overlap heavily -- with a shared cache a chunk costs a few dozen evaluations
instead of a few thousand.

Also lifts sea_level, min_y, height and the aquifers/ore-veins flags out of the
settings file, and adds PositionalRandomFactory.At for the aquifer cell centres
(Mth.getSeed hashed into the low half of the factory seed).

No generator output changes yet: nothing reads the new keys.
2026-07-27 01:44:45 +03:00
Master290
4dcf938a85 Biome-aware surface rules from the vanilla rule tree
Replaces the biome-blind fillVanillaColumn heuristics with a full
interpreter for the overworld surface_rule tree (already embedded in
overworld.json): block/sequence/condition/bandlands rules plus all 11
condition tests (biome, steep, hole, water, temperature, y_above,
stone_depth, noise_threshold, not, vertical_gradient,
above_preliminary_surface).

- worldgen/blockids.go: name(+Properties)→network-ID table for surface
  blocks (grass/sand/terracotta/mycelium/podzol/coarse_dirt/sandstone/
  calcite/snow/ice/...), with snowy property variants.
- worldgen/surface.go: rule-tree parser + interpreter + SurfaceContext;
  LoadOverworldSurfaceRule caches the seed-independent tree.
- loader.go: OverworldDensity.SurfaceRule() exposes the parsed tree.
- biome_lookup.go: BiomeNameAt returns the biome name for biome tests.
- vanilla.go: samples the 2D climate + biome before column fill, threads
  the rule tree and biome name into fillVanillaColumn, and applies it
  top-down with stone as the default for non-matching (deeper) blocks.
  The above_preliminary_surface gate uses an inclusive bound so the top
  solid block reaches the biome dispatch.
- Performance: one per-column RNG and a reused SurfaceContext keep the
  overhead to ~+13ms/chunk (71ms vs 58ms baseline), within the gate.
2026-06-24 19:44:07 +03:00
Master290
a7bb9496ae Initial commit: RegionIO Minecraft server core (26.1.2/protocol 775)
Vanilla-faithful overworld generator (final_density + multi-noise biomes),
full connection lifecycle (status/login/configuration/play), chunk streaming,
creative block editing, and the protocol/nbt/registry infrastructure.
2026-06-24 00:32:51 +03:00