Skip to content

These docs were made completely by AI, so they might be right, or wrong, you'll need to test them yourself. This was made for a easier understanding of everything. So use at your own risk. If anything is wrong, please don't hurt to make a PR on the page you have a problem with. ON GITHUB

World Generation

LCE generates worlds through a multi-stage pipeline that turns a 64-bit seed into a complete landscape of terrain, biomes, caves, ores, and structures. The system comes from Java Edition but has major changes by 4J Studios to support finite world sizes and parallel chunk generation.

All chunk generators implement the ChunkSource interface, which defines how chunks get created, populated, and saved. The key methods are getChunk(), create(), postProcess(), and lightChunk().

class ChunkSource {
int m_XZSize; // world size in chunks
virtual bool hasChunk(int x, int y) = 0;
virtual bool reallyHasChunk(int x, int y); // 4J added
virtual LevelChunk *getChunk(int x, int z) = 0;
virtual LevelChunk *create(int x, int z) = 0;
virtual void postProcess(ChunkSource *parent, int x, int z) = 0;
virtual void lightChunk(LevelChunk *lc); // 4J added
virtual bool saveAllEntities(); // 4J added
virtual bool save(bool force, ProgressListener *progressListener) = 0;
virtual bool tick() = 0;
virtual bool shouldSave() = 0;
virtual LevelChunk **getCache(); // 4J added
virtual void dataReceived(int x, int z); // 4J added
virtual wstring gatherStats() = 0;
virtual vector<Biome::MobSpawnerData *> *getMobsAt(...) = 0;
virtual TilePos *findNearestMapFeature(...) = 0;
};
ClassDimensionBase blockLiquid
RandomLevelSourceOverworldTile::rockTile::calmWater
CustomLevelSourceOverworld (heightmap-based)Tile::rockTile::calmWater
FlatLevelSourceSuperflatConfigured layersNone
HellRandomLevelSourceNetherTile::hellRockTile::calmLava
TheEndLevelRandomLevelSourceThe EndTile::whiteStoneNone

CustomLevelSource reads heightmap data from binary files (heightmap.bin and waterheight.bin) and uses those instead of noise-generated terrain. It’s used for console-specific pre-authored worlds (content packages). When the _OVERRIDE_HEIGHTMAP define is set (which it is for non-content-package builds), CustomLevelSource also has its own cave/canyon/structure features. RandomLevelSource does the full noise-driven terrain generation described below.

World size is defined by constants in ChunkSource.h:

ConstantValueDescription
LEVEL_MAX_WIDTH320 (large) or 54 (small)Overworld size in chunks
LEVEL_MIN_WIDTH54Minimum overworld size
LEVEL_LEGACY_WIDTH54Legacy (pre-TU9) overworld size
HELL_LEVEL_MAX_SCALE8 (large) or 3 (small)Nether scale factor
HELL_LEVEL_MIN_SCALE3Minimum nether scale
HELL_LEVEL_LEGACY_SCALE3Legacy nether scale
HELL_LEVEL_MAX_WIDTHLEVEL_MAX_WIDTH / HELL_LEVEL_MAX_SCALENether width in chunks
HELL_LEVEL_MIN_WIDTH18Minimum nether width
END_LEVEL_SCALE3End scale factor
END_LEVEL_MAX_WIDTH18End width (fixed for all platforms)
END_LEVEL_MIN_WIDTH18End minimum width

The large world constants use _LARGE_WORLDS compile-time define. When large worlds are enabled, LEVEL_MAX_WIDTH = 5 * 64 = 320 chunks, and the Nether uses the full 1:8 scale from Java. On small worlds, the Nether scale is only 1:3 to keep it playable.

RandomLevelSource::getChunk() runs these stages in order:

random->setSeed(xOffs * 341873128712L + zOffs * 132897987541L);

Each chunk gets a deterministic seed based on its coordinates and two large prime-like constants.

This stage computes a low-resolution 3D density field and upsamples it into a 16x128x16 block array.

The density field is sampled on a grid of (CHUNK_WIDTH=4) blocks horizontally and (CHUNK_HEIGHT=8) blocks vertically. The grid dimensions are 5x17x5 (including boundary samples for interpolation).

Seven Perlin noise octave generators contribute to the density value at each sample point:

Noise generatorOctavesRole
lperlinNoise116Lower noise bound (amplitude A)
lperlinNoise216Upper noise bound (amplitude B)
perlinNoise18Interpolation selector between A and B
scaleNoise10Per-column terrain scale factor
depthNoise16Per-column depth variation
floatingIslandScale10Floating island scale (unused, FLOATING_ISLANDS = false)
floatingIslandNoise16Floating island noise (unused)

The master frequency constant is 684.412. Noise inputs are scaled by this value divided by various factors (e.g. s / 80.0 for the selector noise, s directly for the bound noises).

Biome influence: A 5x5 neighborhood of biomes around each column is sampled. Each biome’s depth and scale fields get distance-weighted (using a precomputed pows kernel of 10 / sqrt(dx^2 + dz^2 + 0.2)) to produce smoothed per-column depth and scale values. These shift and compress the density curve, creating the right terrain height and roughness for each biome.

Density computation per sample point:

yCenter = ySize / 2.0 + depth * 4
yOffs = (y - yCenter) * 12 * 128 / genDepth / scale
if (yOffs < 0) yOffs *= 4 // steeper underground falloff
val = lerp(selector, lowerBound, upperBound) - yOffs

If val > 0, the sample becomes Tile::rock. If below sea level, it becomes Tile::calmWater. The final block array is produced by trilinear interpolation of these samples to full resolution.

Edge-of-world falloff (4J addition): Within 32 blocks of the world boundary, a compensation value ramps from 0 to 128, subtracting from the density threshold. This makes terrain gradually drop below sea level at the map edges, blending into the infinite ocean surrounding the finite world.

After height preparation, surfaces get painted based on biome data:

  • A 4-octave perlinNoise3 generates a per-column runDepth controlling how deep the surface layer goes.
  • Starting from the top of the column and working down, the first stone encountered is replaced with the biome’s topMaterial (usually grass) and subsequent stone blocks become the biome’s material (usually dirt).
  • Sand surfaces get sandstone layers beneath them.
  • Cold biomes (temperature < 0.15) get ice instead of water at the surface.
  • Bedrock is placed at Y=0-2 using y <= 1 + random->nextInt(2) (Y=0 and Y=1 are always bedrock, Y=2 is 50% chance). 4J changed this from Java’s y <= 0 + random->nextInt(5) range (Y=0-4) to prevent players from getting stuck.
caveFeature->apply(this, level, xOffs, zOffs, blocks);
canyonFeature->apply(this, level, xOffs, zOffs, blocks);

Both are LargeFeature subclasses that scan a neighborhood of radius = 8 chunks around the target chunk. See the Cave generation section below.

When generateStructures is true:

mineShaftFeature->apply(...);
villageFeature->apply(...);
strongholdFeature->apply(...);
scatteredFeature->apply(...);

The order is intentional. Canyons run first so they can’t cut through structures. This was changed in the 1.2 merge (the original 1.8 order placed canyons last).

Post-processing runs after the chunk is stored in the cache. It uses a separate pprandom RNG so it can run at the same time as chunk creation on other threads (a 4J optimization). Steps:

  1. Structure interiors: Mine shafts, villages, and strongholds place their interior blocks.
  2. Water lakes: 1-in-4 chance per chunk, random Y.
  3. Lava lakes: 1-in-8 chance, biased toward lower Y. Above sea level needs an additional 1-in-10 check.
  4. Dungeons (monster rooms): 8 attempts per chunk at random positions.
  5. Biome decoration: Hands off to BiomeDecorator (see Feature placement).
  6. Mob spawning: Initial passive mob population.
  7. Snow and ice: Cold biomes get snow layers on exposed blocks and ice on water surfaces.

PerlinNoise stacks multiple ImprovedNoise octaves. Each octave doubles in frequency and halves in amplitude:

value = sum(noise[i].getValue(x * 2^i, y * 2^i, z * 2^i) / 2^i)

ImprovedNoise implements Ken Perlin’s improved noise function with a 512-entry permutation table seeded from the world Random. It supports both 2D and 3D evaluation and bulk region sampling through getRegion().

The Synth base class provides the shared getValue(x, y) interface.

PerlinSimplexNoise stacks SimplexNoise octaves using the same summation pattern. SimplexNoise implements 2D and 3D simplex noise using a gradient table (grad3[12][3]) and skew factors F2, G2, F3, G3. It’s used for biome temperature and downfall calculations.

A separate FastNoise implementation exists for performance-sensitive paths.

The addFeature() method figures out how many cave systems to generate per chunk:

int caves = random->nextInt(random->nextInt(random->nextInt(40) + 1) + 1);
if (random->nextInt(15) != 0) caves = 0;

This triple-nested random produces a heavily skewed distribution. Most chunks have no caves, but some can have many. There’s a 14/15 chance of getting zero caves entirely.

Each cave system starts at a random position. There’s a 1-in-4 chance of creating a room (a wide spherical cavity), followed by 1-4 tunnels carved outward from that point.

Tunnel carving (addTunnel):

  • Tunnels step forward in a direction defined by yRot (horizontal angle) and xRot (vertical pitch).
  • The radius at each step follows a sine curve over the tunnel length, adjusted by a random thickness parameter.
  • Direction changes through random angular acceleration (yRota, xRota), with dampening factors.
  • Tunnels can split at a random midpoint into two diverging branches (if thickness > 1).
  • Steep tunnels decay their vertical angle more slowly (0.92 vs 0.7).
  • Blocks below Y=10 are replaced with lava instead of air.
  • Caves won’t carve through water. If water is found in the carving region, that step is skipped.
  • Only carves through stone (Tile::rock), dirt (Tile::dirt), and grass (Tile::grass) blocks.
  • Grass blocks below carved space are restored when dirt gets exposed.

The addRoom method creates a larger spheroid cavity. It takes a seed, position, and the block array, carving a roughly spherical space before spawning tunnels outward.

CaveFeature generates smaller ellipsoidal cavities. It picks two endpoints in a 16-block range and carves an ellipsoid along the line between them, with some random fuzziness that makes the edges irregular. It checks for liquid nearby and avoids carving near chunk boundaries. This is a Feature subclass (not a LargeFeature), so it operates within a single chunk.

CanyonFeature extends LargeFeature and carves narrow, tall ravines using the same tunnel-stepping algorithm but with a different Y-scale parameter to create the typical vertical slot shape. It uses a pre-allocated float rs[1024] array for the ravine shape profile.

DungeonFeature extends LargeFeature and provides an alternate cave/tunnel generation system. It has addRoom() and addTunnel() methods similar to LargeCaveFeature but with a different approach. Note: this is separate from the monster room spawner dungeons placed during post-processing.

The Nether uses its own cave feature (LargeHellCaveFeature) with the same room-and-tunnel algorithm, adapted for the Nether’s hellrock terrain and lava sea. It extends LargeFeature directly (not LargeCaveFeature) and has its own addRoom() and addTunnel() methods.

All decorative world generation elements extend Feature:

class Feature {
bool doUpdate; // Whether to notify neighbors on block placement
virtual bool place(Level *level, Random *random, int x, int y, int z) = 0;
virtual bool placeWithIndex(Level *level, Random *random, int x, int y, int z,
int iIndex, int iRadius); // For indexed placement (spikes)
virtual void init(double V1, double V2, double V3); // Init with parameters
protected:
virtual void placeBlock(Level *level, int x, int y, int z, int tile);
virtual void placeBlock(Level *level, int x, int y, int z, int tile, int data);
};

The doUpdate flag controls whether placeBlock() sends neighbor update notifications. During bulk generation, this is usually false for performance.

Feature classFileWhat it generates
OreFeatureOreFeature.hOre veins (ellipsoidal clusters)
TreeFeatureTreeFeature.hOak trees (configurable trunk/leaf, optional jungle vines)
BasicTreeBasicTree.hFancy large oak trees (complex branching algorithm)
BirchFeatureBirchFeature.hBirch trees
PineFeaturePineFeature.hPine trees (taiga)
SpruceFeatureSpruceFeature.hSpruce trees (taiga)
SwampTreeFeatureSwampTreeFeature.hSwamp trees with vines
MegaTreeFeatureMegaTreeFeature.hLarge 2x2 trees (jungle)
GroundBushFeatureGroundBushFeature.hSmall jungle bushes (1-block trunk, leaf dome)
HugeMushroomFeatureHugeMushroomFeature.hGiant mushrooms (brown=flat top, red=dome top)
FlowerFeatureFlowerFeature.hFlowers (any single-block plant)
TallGrassFeatureTallGrassFeature.hTall grass patches
CactusFeatureCactusFeature.hCactus columns
ReedsFeatureReedsFeature.hSugar cane
VinesFeatureVinesFeature.hHanging vines on blocks
ClayFeatureClayFeature.hClay patches
SandFeatureSandFeature.hSand/gravel patches
LakeFeatureLakeFeature.hSurface/underground lakes
SpringFeatureSpringFeature.hWater/lava springs
HellSpringFeatureHellSpringFeature.hNether lava springs
HellFireFeatureHellFireFeature.hNether random fire patches
LightGemFeatureLightGemFeature.hGlowstone clusters
HellPortalFeatureHellPortalFeature.hNether portal placement
DungeonFeatureDungeonFeature.hMonster spawner rooms
DesertWellFeatureDesertWellFeature.hDesert wells
BonusChestFeatureBonusChestFeature.hStarting bonus chest
SpikeFeatureSpikeFeature.hEnd obsidian pillars
EndPodiumFeatureEndPodiumFeature.hEnd exit podium

Each tree feature has different characteristics:

FeatureConstructorGenerates
TreeFeature(doUpdate)BasicStandard oak tree, 4+ blocks tall
TreeFeature(doUpdate, baseHeight, trunkType, leafType, addJungleFeatures)ConfigurableCustom tree with specific blocks and optional vines
BasicTree(doUpdate)ComplexFancy large oak with branches. Uses init(height, width, foliageDensity)
BirchFeature(doUpdate)SimpleBirch tree
PineFeatureSimplePine tree (layered cone shape)
SpruceFeature(doUpdate)SimpleSpruce tree (taiga)
SwampTreeFeatureSimpleSwamp oak with vines draped on leaves
MegaTreeFeature(doUpdate, baseHeight, trunkType, leafType)2x2 trunkLarge jungle trees
GroundBushFeature(trunkType, leafType)SimpleSmall 1-block jungle bushes

BasicTree is the most complex tree generator. It uses:

  • An axisConversionArray for 3D coordinate transforms
  • foliageCoords for cluster positions
  • crossection() for circular leaf layers
  • limb() and taperedLimb() for branch geometry
  • treeShape() and foliageShape() for overall proportions
  • checkLine() and checkLocation() for collision testing

BiomeDecorator::decorate() is called during post-processing and places features in this order:

decorateOres() places ore veins using OreFeature. Each vein picks two endpoints and carves an ellipsoidal shape between them, replacing the target block (default: stone) with the ore type.

OreVein sizeAttempts/chunkY range
Dirt32200 to genDepth
Gravel32100 to genDepth
Coal16200 to genDepth
Iron8200 to genDepth/2
Gold820 to genDepth/4
Redstone780 to genDepth/8
Diamond710 to genDepth/8
Lapis lazuli61Centered at genDepth/8 (triangular distribution)

Lapis uses decorateDepthAverage() which samples random->nextInt(span) + random->nextInt(span) + (mid - span), producing a triangular distribution centered on genDepth/8.

After ores, features are placed in order:

  1. Sand patches (3 attempts) and clay patches (1 attempt) at the top solid block.
  2. Gravel patches (1 attempt).
  3. Trees: Base count is treeCount (biome-specific) with a 1-in-10 chance of +1. Each tree type is picked by Biome::getTreeFeature(), which returns one of TreeFeature, BasicTree, BirchFeature, SwampTreeFeature, MegaTreeFeature, or GroundBushFeature depending on the biome and a random roll.
  4. Huge mushrooms: Only in mushroom island biome (hugeMushrooms count).
  5. Flowers: Yellow flowers and roses (1-in-4 chance per flower attempt).
  6. Tall grass: Biome-specific through Biome::getGrassFeature().
  7. Dead bushes: Desert biomes.
  8. Water lilies: Swamp biome.
  9. Mushrooms: Small chance on the surface plus guaranteed underground attempts.
  10. Sugar cane (reeds): reedsCount attempts plus 10 extra always.
  11. Pumpkins: 1-in-32 chance per chunk.
  12. Cacti: Desert biomes.
  13. Water springs: 50 attempts at random heights.
  14. Lava springs: 20 attempts biased toward lower Y.
MethodParametersBehavior
decorateDepthSpan(count, feature, y0, y1)count, feature, min Y, max YPlaces count times at random Y between y0 and y1
decorateDepthAverage(count, feature, yMid, ySpan)count, feature, center Y, spreadPlaces near a center height (triangular distribution)
decorate(count, feature)count, featurePlaces at surface height

Several biomes change decorator counts by declaring their decorator class as a friend and tweaking the fields:

BiomeNotable changes
DesertBiomedeadBushCount = 2, cactusCount = 10, reedsCount = 50, treeCount = -999, sand/sand surface
ForestBiometreeCount = 10, grassCount = 2
PlainsBiometreeCount = -999, flowerCount = 4, grassCount = 10
SwampBiometreeCount = 2, flowerCount = -999, deadBushCount = 1, waterlilyCount = 4, mushroomCount = 8, reedsCount = 10
TaigaBiometreeCount = 10, grassCount = 1
JungleBiometreeCount = 50, grassCount = 25, flowerCount = 4
MushroomIslandBiomehugeMushrooms = 1, mushroomCount = 1, trees/flowers/grass all set to -100
BeachBiometreeCount = -999, deadBushCount = 0, reedsCount = 0, cactusCount = 0, sand/sand surface

Some biomes override Biome::decorate() to add features beyond what BiomeDecorator handles:

  • DesertBiome: 1/1000 chance per chunk to place a DesertWellFeature
  • ExtremeHillsBiome: Places emerald ore veins (3-8 per chunk at Y 4 to genDepth/4) when GENERATE_EMERALD_ORE is true
  • JungleBiome: Places 50 VinesFeature instances per chunk after base decoration

Biome selection uses a chain of Layer objects that turn a seed into a 2D grid of biome IDs. Each layer wraps a parent layer and applies a transformation. The chain is built in Layer::getDefaultLayers().

IslandLayer(1)
-> FuzzyZoomLayer(2000)
-> AddIslandLayer(1)
-> ZoomLayer(2001)
-> AddIslandLayer(2)
-> AddSnowLayer(2)
-> ZoomLayer(2002)
-> AddIslandLayer(3)
-> ZoomLayer(2003)
-> AddIslandLayer(4)

This base chain produces a rough continental layout. It then forks into two parallel branches:

River branch:

base -> ZoomLayer(1000) -> RiverInitLayer(100)
-> ZoomLayer x(zoomLevel+2)
-> RiverLayer(1) -> SmoothLayer(1000)

Biome branch:

base -> ZoomLayer(1000) -> BiomeInitLayer(200, levelType)
-> ZoomLayer x2 -> RegionHillsLayer(1000)
-> ZoomLayer x zoomLevel (with island/mushroom/shore inserts)
-> SmoothLayer(1000)

The two branches get merged by RiverMixerLayer, which overlays river biomes onto the terrain biomes. A final VoronoiZoom layer provides block-level biome resolution from the chunk-level data.

LayerPurpose
IslandLayerGenerates initial random land/ocean pattern
FuzzyZoomLayer2x zoom with random neighbor selection
ZoomLayer2x zoom with majority-rule interpolation
AddIslandLayerConverts some ocean cells to land
AddSnowLayerMarks cold regions for snow biomes
BiomeInitLayerAssigns specific biome IDs based on temperature/moisture
RegionHillsLayerAdds hill variants of biomes
ShoreLayerAdds beach/shore transitions at land-ocean boundaries
RiverInitLayerSeeds river generation with random values
RiverLayerDetects edges in the river seed to form river paths
RiverMixerLayerOverlays rivers onto the biome map
SmoothLayerRemoves single-cell noise from the biome map
SwampRiversLayerAdjusts river placement in swamp biomes
AddMushroomIslandLayerPlaces mushroom island biomes (4J moved to later zoom for smaller islands)
GrowMushroomIslandLayerExpands mushroom islands via region growing (4J addition)
VoronoiZoomBlock-resolution zoom using Voronoi cell assignment
BiomeOverrideLayerDebug override layer (non-release builds only)

The zoomLevel is 4 for normal worlds and 6 for large biome worlds. Each zoom doubles the map scale.

Each layer uses a deterministic PRNG seeded from the world seed, the layer’s seedMixup constant, and the (x, z) coordinates. The mixing function uses the LCG constant 6364136223846793005 with increment 1442695040888963407. The nextRandom(max) method extracts bits via (rval >> 24) % max.

The PS Vita build includes a special fast-divide optimization (libdivide) for the modulo operation in nextRandom().

Biome::biomes[256] holds all 23 registered biomes (BIOME_COUNT = 23):

ocean, plains, desert, extremeHills, forest, taiga, swampland, river, hell, sky, frozenOcean, frozenRiver, iceFlats, iceMountains, mushroomIsland, mushroomIslandShore, beaches, desertHills, forestHills, taigaHills, smallerExtremeHills, jungle, jungleHills.

Each biome carries depth, scale, temperature, downfall, topMaterial, and material properties that shape the terrain and surface.

BiomeSource wraps the layer system and provides caching (BiomeCache) for biome lookups. It also exposes containsOnly() for structure placement validation and findBiome() for locating specific biomes.

Structures extend StructureFeature, which extends LargeFeature. The system works in two phases:

  1. Carving phase (addFeature / apply): During chunk creation, isFeatureChunk() checks if a chunk should have a structure start. If so, createStructureStart() builds the structure layout and StructureStart stores the component pieces. The pieces carve their footprint into the block array.

  2. Population phase (postProcess): During post-processing, structure interiors are placed (chests, spawners, rails, etc.).

StructureClassNotes
StrongholdStrongholdFeature1 per world (Java has 3), limited to allowedBiomes, up to 30 placement attempts on large worlds
VillageVillageFeatureNeeds allowedBiomes validation via BiomeSource::containsOnly(), accepts a villageSizeModifier
Mine shaftMineShaftFeatureStandard generation
Nether fortressNetherBridgeFeatureNether-only, provides special mob spawning list (bridgeEnemies)
Scattered featuresRandomScatteredLargeFeatureDesert temples, jungle temples

StructureFeature keeps a cachedStructures map (unordered_map keyed by a 64-bit hash of chunk coordinates) to prevent duplicate generation.

enum EFeatureTypes {
eFeature_Mineshaft,
eFeature_NetherBridge,
eFeature_Temples,
eFeature_Stronghold,
eFeature_Village,
};

This enum maps to values in the game rules XML and is used by LevelGenerationOptions::isFeatureChunk() to force structure placement at specific coordinates.

HellRandomLevelSource generates the Nether with these differences from the Overworld:

  • Terrain shape: Uses a cosine-based Y-offset array that creates the signature ceiling-and-floor shape. The hs (height scale) is 684.412 * 3, making the vertical noise much more compressed.
  • Five noise generators: lperlinNoise1 (16 octaves), lperlinNoise2 (16), perlinNoise1 (8), plus two extra: perlinNoise2 (4) and perlinNoise3 (4) for surface material placement.
  • Lava sea at Y=32 (instead of water at sea level).
  • Surface materials: Netherrack, soul sand, and gravel are placed using the two additional 4-octave noise generators that pick sand and gravel regions.
  • Nether wart: 4J added a 1-in-16 chance of placing nether wart on soul sand surfaces outside of fortresses.
  • Bedrock on both floor (Y=0-4) and ceiling (Y=123-127).
  • Boundary walls: 4J builds bedrock walls around the Nether perimeter, with a randomized jagged edge.
  • Cave carver: LargeHellCaveFeature instead of LargeCaveFeature.
  • World scale: The Nether is 1/3 to 1/8 the Overworld size (HELL_LEVEL_MAX_SCALE is 3 on legacy, 8 on large worlds).
  • Fortress: NetherBridgeFeature is a member of HellRandomLevelSource and handles fortress placement.

Post-processing places:

  • 8 lava spring attempts (HellSpringFeature)
  • Random fire patches (HellFireFeature)
  • Glowstone clusters (LightGemFeature)
  • Nether quartz ore (13-block veins, 16 attempts, targeting hellrock)
  • Brown and red mushrooms
  • Nether portals (HellPortalFeature)

TheEndLevelRandomLevelSource generates The End dimension:

  • Fixed size: 18x18 chunks (END_LEVEL_MAX_WIDTH), regardless of world size.
  • Chunk parameters: CHUNK_HEIGHT = 4, CHUNK_WIDTH = 8 (reversed from the Overworld’s 8 and 4).
  • Island shape: Uses a distance-based offset (100 - sqrt(xd^2 + zd^2) * 8) that creates a floating island tapering off with distance from the origin. This is clamped between -100 and 80.
  • No sea level: blocks below the island are just void (air).
  • End stone (Tile::whiteStone) is the only terrain block.
  • Noise scale is doubled (s *= 2) compared to the Overworld, giving rougher terrain.
  • Three noise generators: lperlinNoise1, lperlinNoise2, perlinNoise1, plus scaleNoise, depthNoise, and forestNoise.
  • No caves or structures are carved.

The End’s biome decorator (TheEndBiomeDecorator) places:

  • 8 obsidian spikes in a circle of radius 40 around the origin, with increasing radii (2-4 blocks). Spike data is stored in a static SpikeValA[8] array with chunk coordinates, position, and radius.
  • The Ender Dragon at position (0, 128, 0) when chunk (0, 0) is processed.
  • The exit podium (EndPodiumFeature) at the origin, placed when chunk (-16, -16) is processed.

The SpikeFeature supports both regular place() and placeWithIndex() for placing a specific spike with a given index and radius.

FlatLevelSource generates superflat worlds using a FlatLayer configuration. The terrain is just a simple stack of configured block layers with no noise, caves, or terrain variation. Only village structures are generated if generateStructures is enabled. It has a VillageFeature member but no other structure features.

Like the other chunk sources, FlatLevelSource uses separate random and pprandom RNGs for thread-safe generation.

FileDescription
RandomLevelSource.cpp/.hMain Overworld terrain generator
CustomLevelSource.cpp/.hHeightmap-based Overworld generator
HellRandomLevelSource.cpp/.hNether terrain generator
TheEndLevelRandomLevelSource.cpp/.hEnd terrain generator
FlatLevelSource.cpp/.hSuperflat generator
ChunkSource.hBase interface for all chunk generators
LevelSource.hBlock/tile access interface for rendering
PerlinNoise.cpp/.hOctave Perlin noise
ImprovedNoise.cpp/.hSingle-octave improved Perlin noise
PerlinSimplexNoise.cpp/.hOctave simplex noise
SimplexNoise.cpp/.hSingle-octave simplex noise
Synth.hBase noise interface
LargeFeature.cpp/.hBase class for chunk-spanning features
LargeCaveFeature.cpp/.hOverworld cave carver
LargeHellCaveFeature.hNether cave carver
CaveFeature.cpp/.hSmall ellipsoidal cave feature
CanyonFeature.cpp/.hRavine/canyon carver
DungeonFeature.cpp/.hAlternate cave/tunnel carver
Feature.cpp/.hBase class for all placed features
BiomeDecorator.cpp/.hFeature placement orchestrator
TheEndBiomeDecorator.cpp/.hEnd-specific decoration (spikes, dragon, podium)
OreFeature.cpp/.hOre vein placement
TreeFeature.hOak trees
BasicTree.hFancy oak trees
BirchFeature.hBirch trees
PineFeature.hPine trees
SpruceFeature.hSpruce trees
SwampTreeFeature.hSwamp trees
MegaTreeFeature.hLarge jungle trees
GroundBushFeature.hJungle bushes
HugeMushroomFeature.hGiant mushrooms
VinesFeature.hVine placement
SpikeFeature.hEnd obsidian pillars
EndPodiumFeature.hEnd exit podium
LakeFeature.hSurface/underground lakes
SpringFeature.hWater/lava springs
HellSpringFeature.hNether lava springs
HellFireFeature.hNether fire patches
LightGemFeature.hGlowstone clusters
HellPortalFeature.hNether portal placement
DesertWellFeature.hDesert wells
BonusChestFeature.hStarting bonus chest
Layer.cpp/.hBase biome layer + getDefaultLayers() pipeline
BiomeSource.cpp/.hBiome lookup with caching
Biome.hBiome registry and properties
StructureFeature.cpp/.hBase class for generated structures
StrongholdFeature.hStronghold placement
VillageFeature.hVillage placement
MineShaftFeature.hMine shaft placement
NetherBridgeFeature.hNether fortress placement
RandomScatteredLargeFeature.hDesert/jungle temples

The world generation system is mostly the same between LCEMP and MC, since both target the same Minecraft version’s terrain. The main differences are:

  • Flat world configuration: MC adds FlatGeneratorInfo and FlatLayerInfo classes for configurable superflat world presets. LCEMP just has a basic FlatLayer system with hardcoded layers.
  • Structure persistence: MC adds StructureFeatureIO and StructureFeatureSavedData for saving structure bounding boxes to NBT and loading them back on world reload. In LCEMP, structure data only lives in memory during generation.
  • Witch huts: MC adds a SwamplandHut piece type to ScatteredFeaturePieces with its own enemy spawn list (just Witch). In LCEMP, the RandomScatteredLargeFeature only generates desert pyramids and jungle temples. MC adds Swampland to the allowed biomes list for scattered features.
  • Nether wart tile: MC has a separate NetherWartTile class. LCEMP uses NetherStalkTile for the same block.
  • Glowstone tile: MC has a dedicated GlowstoneTile class. LCEMP just uses a basic Tile with LightGemTile for the same purpose.