Skip to content

Fix wild crops never generating when lighting is deferred - #747

Open
andystaples wants to merge 1 commit into
ExcessiveAmountsOfZombies:v4from
andystaples:fix/worldgen-crop-light-gate
Open

Fix wild crops never generating when lighting is deferred#747
andystaples wants to merge 1 commit into
ExcessiveAmountsOfZombies:v4from
andystaples:fix/worldgen-crop-light-gate

Conversation

@andystaples

Copy link
Copy Markdown

Fixes the long-standing "trees generate but crops don't" reports: #737, #689, #590.

Tested on MC 26.1.2 / NeoForge, Croptopia 4.3.1, with Terralith + Biomes O' Plenty + ScalableLux.

The bug

CroptopiaCropBlock.canSurvive delegates to CropBlock.canSurvive on the worldgen path. CropBlock.canSurvive requires hasSufficientLight, i.e. getRawBrightness(pos, 0) >= 8.

Feature placement runs at the features chunk status. The status order is:

empty → structure_starts → structure_references → biomes → noise → surface
      → carvers → features → initialize_light → light → spawn → full

features runs before initialize_light and light, so nothing has computed lighting yet when a crop is placed. What a light lookup returns at that point is up to the light engine implementation, not the world. SimpleBlockFeature.place gates entirely on state.canSurvive(level, pos), so when the engine reports 0 the gate rejects every placement and no wild crop ever generates.

This explains the pieces of the reports that never lined up:

  • Trees are unaffectedcroptopia:*_tree placements use a would_survive predicate against minecraft:oak_sapling and TreeFeature, neither of which goes through CropBlock.canSurvive.
  • Crops in village farms still appearCropBlock.canSurvive first calls canSustainPlant on the block below and returns immediately if the result is non-default. Farmland short-circuits there, before the light check is ever reached. Structure-placed crops on farmland were the only Croptopia crops in my world.
  • Why it reproduces for some people and not others (Missing crop generation while fruit/cinnamon trees spawn normally #737) — with the vanilla light engine the lookup evidently returns a passing value, which is why you see crops generate in your Tectonic world. ScalableLux replaces the light engine; ScalableLux is producing an issue similar to #590 #689 reports that disabling it restores crop generation, and that matches what I see. This patch removes the dependency on light-engine behaviour rather than papering over one engine's return value.

The fix

Check mayPlaceOn directly on the worldgen path. It is the same soil test VegetationBlock.canSurvive performs, minus the light requirement, and CroptopiaCropBlock already overrides it to accept dirt/grass/sand/farmland. The player-placement branch is untouched and keeps vanilla light behaviour, so planting rules are unchanged.

Confirmed in the compiled artifact, not just the source: the current class calls CropBlock.canSurvive twice (both branches); the patched class calls it once, only in the player-placement branch.

Before / after

Same world, same seed, same modlist. I scanned the region files directly, then purged and regenerated chunks with MCA Selector on the patched build.

Before After
Wild crop blocks on natural ground 0 11,874
Distinct wild crop types 0 41

Before, across 26,970 generated chunks — of which 19,922 (73.9%) were in a has_crop-tagged biome, including 7,651 chunks of vanilla plains, 880 jungle, 582 bamboo_jungle, 446 desert, 1,780 BOP woodland and 3,394 BOP scrubland — there was not a single crop on a natural block. The only 128 crop blocks in the entire world sat on minecraft:farmland in one CTOV village farm plot. Meanwhile 31,064 cinnamon leaves and 23,694 salt ore had generated normally.

After regeneration, ground beneath the 11,874 wild crops: 11,669 grass_block, 125 sand, 36 podzol, 29 coarse_dirt, 6 dirt. Biome spread: BOP scrubland 5,941, BOP woodland 3,353, Terralith brushland 859, sparse_jungle 737, BOP mediterranean_forest 436, Terralith rocky_jungle 293, plus savanna/jungle/forest tails.

Notes

  • This does not address the salt half of ScalableLux is producing an issue similar to #590 #689. Salt uses minecraft:diskDiskFeature, which never calls canSurvive, so it was never exposed to this gate. Salt generated normally throughout my testing (23,694 blocks, 99.4% in y48–63) with ScalableLux installed. Whatever that reporter hit on 4.1.0 / 1.21.1 is a separate matter.
  • v4-26.2 carries the identical method and should need the same one-line change.
  • Only the NeoForge jar was built and tested. I could not build :fabric — all three modules depend on com.epherical.epherolib:*:1.3.0, buildSrc declares only mavenCentral/Sponge/BlameJared, and maven.epherical.com returned HTTP 522 on every attempt. I worked around it locally for :neoforge with the EpheroLib jar from my mods folder. Not part of this PR, but you may want the repository declaration back in buildSrc.

Root-cause analysis and patch drafted with Claude Opus 5 (Claude Code), then hand-reviewed by me and verified in-game on a purged-and-regenerated world before submitting. Bytecode claims, chunk-status ordering and the before/after counts were checked against the 26.1.2 artifacts and my own save files rather than taken on trust.

🤖 Generated with Claude Code

CroptopiaCropBlock.canSurvive delegated to CropBlock.canSurvive on the
worldgen path, which requires hasSufficientLight. Feature placement runs
at the `features` chunk status, before `initialize_light` and `light`, so
the value a light lookup returns there depends on the light engine rather
than on the world. Under engines that report 0, SimpleBlockFeature's
canSurvive gate rejects every placement and no wild crop ever generates.

Check mayPlaceOn directly on the worldgen path instead. Player placement
is untouched and keeps the vanilla light requirement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ExcessiveAmountsOfZombies

Copy link
Copy Markdown
Owner

hey thanks for taking a look at this, i'll give it a test and see when i can implement

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