Skip to content

Feat/survival prep#1065

Merged
louis-e merged 10 commits into
mainfrom
feat/survival-prep
May 26, 2026
Merged

Feat/survival prep#1065
louis-e merged 10 commits into
mainfrom
feat/survival-prep

Conversation

@louis-e
Copy link
Copy Markdown
Owner

@louis-e louis-e commented May 26, 2026

No description provided.

Copilot AI review requested due to automatic review settings May 26, 2026 20:57
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 26, 2026

⏱️ Benchmark run finished in 1m 1s
🏗️ Generation time: 28s (excl. data fetching)
🧠 Peak memory usage: 958 MB (↗ 6% more)

📈 Compared against baseline: 27s time, 900 MB memory
🧮 Delta: 34s time, 58 MB memory
🔢 Commit: d486b5a

🟢 Generation time is unchanged.
⚠️ This PR increases peak memory.

📅 Last benchmark: 2026-05-26 22:17:41 UTC

You can retrigger the benchmark by commenting retrigger-benchmark.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands world generation variety and “survival prep” features by improving tree diversity, adding Java chunk biome assignment based on land-cover, optimizing --fillground, and adding deterministic underground ore veins when --fillground is enabled.

Changes:

  • Add land-cover-driven biome palettes to Java Anvil chunk NBT (biomes per section, palette+data packing).
  • Improve vegetation variety (many new tree variants/species, density modulation, mangrove/willow handling in wetlands).
  • Optimize --fillground by bulk-filling fully buried empty sections, and add a new ore vein pass gated on --fillground.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/world_editor/mod.rs Exposes MIN_SECTION_Y and adds WorldEditor wrapper for bulk-filling buried sections.
src/world_editor/java.rs Plumbs per-chunk biome NBT into chunk creation/writing and updates tests accordingly.
src/world_editor/common.rs Adds MIN_SECTION_Y and implements/test bulk fill of empty chunk sections.
src/ground_generation.rs Uses the bulk-fill fast path to reduce transient allocations during --fillground.
src/biome.rs New module: maps ESA WorldCover to Minecraft biomes and packs 4x4 chunk biome palettes into Anvil format.
src/ore_generation.rs New module: deterministic ore vein placement pass when --fillground is enabled.
src/data_processing.rs Invokes ore generation after ground/building/natural passes when --fillground is on.
src/element_processing/tree.rs Major tree variety expansion (variants, jitter, branches, droops, new species, accents).
src/element_processing/natural.rs Expands tree pools, adds density modulation, wires mangrove/willow wetland spawning.
src/element_processing/landuse.rs Expands tree pools and adds density-modulated forest spawning; avoids cherry/flowering oak in tagged pools.
src/block_definitions.rs Repurposes some block IDs for new leaves/logs and new ore blocks.
src/main.rs Registers new biome and ore_generation modules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/ore_generation.rs
Comment thread src/world_editor/common.rs Outdated
louis-e added 8 commits May 26, 2026 23:42
…ariety

Address feedback that dense oak forests looked like cookie-cutter clones.

- 27 shape variants across 9 existing species (Oak: 5, Spruce/Birch/DarkOak: 3
  each, others: 2). Per-coord deterministic variant pick via coord_rng salt 1.
- Per-instance jitter: trunk height +/-1..+2, ~4% organic leaf gaps via
  coord-derived hash.
- Side branches with tapered octahedral leaf clusters (Manhattan dist <= 2).
- Drooping leaf tendrils for Willow / weeping Cherry (8 cardinal+diagonal
  columns, variable length per direction).
- LeafPlacer split into place_core (inner cross + droops, never accent) and
  place_surface (outermost ring + branch tip, may be accent). Trunk height
  clamped to canopy_top - 1 so caps always cover the trunk top regardless
  of jitter.
- New species using shape-only variation: Bush (leaf clump, no trunk),
  AzaleaBush, Willow, FloweringOak (oak silhouette + cherry blossom accents).
- New species using repurposed unused block IDs: Mangrove (MANGROVE_LOG=0,
  MANGROVE_LEAVES=233, AZALEA_LEAVES=234). Wired into wetland=mangrove and
  60/40 with Willow for wetland=swamp; resolves the long-standing
  "TODO implement mangrove" in natural.rs.
- Broadleaved/needleleaved/mixed tree pools in landuse.rs and natural.rs
  expanded with the new variants and species.
- Forest density modulated by value_noise_01(x, z, 32) for organic
  clearings vs thickets; average rate unchanged (~1/30).
Replaces the hardcoded minecraft:plains biome on every chunk with a per-chunk
4x4 biome palette derived from ESA WorldCover land cover, packed into the
Anvil 1.18+ per-section biomes NBT.

Mapping (latitude- and water-distance-aware):
  LC_TREE_COVER  -> taiga (>55 deg) / jungle (<23.5 deg) / forest (otherwise)
  LC_SHRUBLAND   -> savanna
  LC_GRASSLAND   -> plains
  LC_CROPLAND    -> plains
  LC_BUILT_UP    -> plains  (neutral; avoids weird ambience in cities)
  LC_BARE        -> desert
  LC_SNOW_ICE    -> snowy_plains
  LC_WATER       -> ocean (water_distance >= 8) / river (otherwise)
  LC_WETLAND     -> swamp
  LC_MANGROVES   -> mangrove_swamp
  LC_MOSS        -> taiga
  fallback       -> plains

Format-aware encoding:
- 4x4 LC samples per chunk (one per biome cell, centred in each 4-block
  footprint). Same compound is cloned across all sections in the chunk
  because LC is 2D, so biomes are y-invariant.
- Palette deduped in first-occurrence order. data array is OMITTED for
  uniform-biome chunks (palette size 1) -- the common case for arnis since
  cities sit inside a single land-cover class.
- Mixed-biome chunks pack the 64 cell indices into i64 longs using the
  post-1.16 no-straddle layout (1 bit -> 1 long, 2 bits -> 2 longs, 3 bits
  -> 4 longs with padding).

Cost analysis on a 250 km^2 generation:
- ~1-2 seconds added wall-clock (parallelised across regions via rayon)
- ~4 MB transient peak per region during save, released after region write
- No persistent fields added to Chunk / ChunkToModify / Section

Bedrock and Luanti save paths are unchanged; they still default to plains.
A separate change can wire LC-driven biomes through bedrock.rs once the
Java mapping has been validated in-game.
The "expand broadleaved/mixed tree pools" change in
8eff06c put Cherry and FloweringOak into the explicit OSM-tagged
forest pools, giving them ~14% (1 in 7) instead of the intended ~2%.
A tagged broadleaved forest ended up looking like a cherry orchard.

Both species are now only reachable via the random Tree::create pool
at the original low rates (Cherry 2%, FloweringOak 6%), so an OSM-tagged
broadleaved/mixed forest contains zero overtly pink trees while
untagged contexts (cemeteries, scrub, swamp tree spawns) still see
them as the rare specimens they're supposed to be.
--fillground writes STONE to every block from MIN_Y+1 to ground_y-3
per column. For each fresh section the very first STONE write
promotes BlockStorage::Uniform(AIR) -> Full(Vec<Block>), allocating
4 KiB. On a 250 km^2 world that is ~3 fully-buried sections per chunk
times ~977k chunks times 4 KiB = ~11 GB of transient heap that
compact_sections() later collapses back to Uniform at save time.

Add a per-chunk pre-pass that, when the chunk is fully inside both
the xzbbox and the rotated bbox, computes the highest section whose
entire 16-block y span sits strictly below ground_y - 3 for every
column, and sets each empty section in [MIN_SECTION_Y, top_buried]
directly to Uniform(STONE). The per-column path then raises its
y_min to (top_buried + 1) * 16 so it only walks the boundary section.

Sections with pre-existing content (e.g. a deep bridge pier) are
detected as non-empty, skipped, and the per-column path takes over
via the existing skip_existing branch — final block content is
bit-for-bit identical to the previous behavior.

4 new unit tests cover empty chunk, occupied chunk, below-min request,
and second-call behavior. All 141 tests pass; clippy clean.
Sprinkles vanilla-flavoured ore veins through the underground stone
produced by --fillground. Off when --fillground is off (no stone to
convert).

7 ore types: COAL, IRON, COPPER (existing IDs 127-130) plus DIAMOND,
REDSTONE, LAPIS using IDs 249-251 which were unused dead slots
("red_sand", "red_sandstone", "cactus" — never referenced by any
arnis code). Y ranges, vein sizes, and per-chunk densities are
simplified vanilla 1.21 distributions.

Each chunk is deterministically seeded from (chunk_x, chunk_z, 0xC0DE)
so re-generating the same world places ore in the same spots and the
seed can't collide with the tree-variant or biome RNGs. Each vein is
a short 3D random walk that replaces STONE only — bedrock, air above
surface, buildings, water carved by water_depth, and subway tunnels
are all left intact, so ore placement is safe in any order relative
to those passes.
Single-line // only, drop multi-line // blocks, remove section dividers
and over-detailed doc comments per project style.
…s overwritten

The previous ore placement called set_block_absolute(ore, x, y, z, None, None)
which silently no-ops over any non-AIR block. set_block_with_properties_absolute
at mod.rs:892 routes to an else { false } branch when there is an existing block
and no filters are given. So every vein step that landed on stone was a no-op.

Passing Some(&[STONE]) as the whitelist makes the existing-block path match and
write. The earlier check_for_block_absolute pre-gate is kept because, when the
target cell is AIR, the same function's else { true } branch would otherwise
write ore into the air above the surface.
Anchor each ore's Y range to the chunk's local ground level (sampled once at
chunk centre) instead of fixed absolute Y. Mountains now carry the full ore
column inside their bulk; flat terrain keeps a vanilla-like underground
distribution. One get_ground_level call per chunk — under 10 ms across a
250 km^2 world.

Drop COPPER_ORE

Also: tighten the bulk_fill_chunk_sections_below doc comment to match the
implementation (a section already Uniform(block) is treated as occupied and
counts against the "all_clean" return) per code review.
@louis-e louis-e force-pushed the feat/survival-prep branch from ee9265a to 3a29f86 Compare May 26, 2026 21:43
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

src/element_processing/tree.rs:92

  • SPRUCE_LEAVES_FILL_STANDARD contains a duplicated column definition ((0, 3, -1), (0, 10, -1)) (it appears twice). This is redundant work at placement time and may be masking an intended missing column; consider removing the duplicate or replacing it with the intended coordinate.
const SPRUCE_LEAVES_FILL_STANDARD: [(Coord, Coord); 6] = [
    ((-1, 3, 0), (-1, 10, 0)),
    ((0, 3, -1), (0, 10, -1)),
    ((1, 3, 0), (1, 10, 0)),
    ((0, 3, -1), (0, 10, -1)),

src/element_processing/tree.rs:238

  • PINE_LEAVES_FILL_STANDARD has a duplicated entry for ((0, 5, -1), (0, 12, -1)). This places the same column twice; consider removing the duplicate or replacing it with the intended missing column.
const PINE_LEAVES_FILL_STANDARD: [(Coord, Coord); 6] = [
    ((-1, 5, 0), (-1, 12, 0)),
    ((0, 5, -1), (0, 12, -1)),
    ((1, 5, 0), (1, 12, 0)),
    ((0, 5, -1), (0, 12, -1)),

Comment thread src/element_processing/tree.rs Outdated
Comment thread src/element_processing/tree.rs Outdated
Comment thread src/element_processing/tree.rs Outdated
Comment thread src/block_definitions.rs
- biome.rs: drop redundant `as u64` cast (c is already u64; -D warnings
  in CI flagged clippy::unnecessary_cast).
- tree.rs: remove duplicate `(0, _, -1)` column from SPRUCE_LEAVES_FILL_*
  and PINE_LEAVES_FILL_* (carried over from the original SPRUCE_LEAVES_FILL
  pattern). The duplicate produced the same leaves twice; trimming to 5
  entries matches the oak/birch shape and removes wasted writes.
- bedrock_block_map.rs: add explicit persistent_bit + update_bit states
  for mangrove_leaves and azalea_leaves (matching the cherry_leaves
  pattern) so Bedrock exports don't decay the new leaves.

cargo clippy --all-targets --all-features -- -D warnings clean.
@louis-e louis-e merged commit 89a0981 into main May 26, 2026
3 checks passed
@louis-e louis-e deleted the feat/survival-prep branch May 26, 2026 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants