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

Biomes

LCE’s biome system controls terrain surface materials, vegetation, mob spawning, climate properties, and how things look (grass/foliage/water/sky colors). The code lives mainly in Minecraft.World/, with the base class in Biome.h/Biome.cpp and subclasses for each biome variant.

Biome (base class)
├── BiomeSource - selects biomes for world coordinates via Layer pipeline
│ └── FixedBiomeSource - returns a single biome everywhere (superflat worlds)
├── BiomeDecorator - places ores, trees, flowers, grass, and other features
│ └── TheEndBiomeDecorator - End-specific decoration (obsidian spikes, podium)
├── BiomeCache - caches biome lookups in 256x256 blocks
└── Layer (pipeline) - transforms noise into biome IDs through chained layers
FilePurpose
Biome.h / Biome.cppBase class, static biome registry, mob spawns, default properties
BiomeSource.h / BiomeSource.cppProvides biomes for any (x, z) coordinate using the Layer pipeline
FixedBiomeSource.hSingle-biome source for superflat worlds
BiomeDecorator.h / BiomeDecorator.cppFeature placement: ores, trees, flowers, mushrooms, springs
TheEndBiomeDecorator.hEnd decoration: obsidian spikes, podium, dragon spawning
Layer.h / Layer.cppBase layer class and getDefaultLayers() pipeline builder
BiomeInitLayer.h / BiomeInitLayer.cppAssigns initial biome IDs from a set of starter biomes
BiomeOverrideLayer.hDebug layer that overrides biome data from a 216x216 byte array

Biome stores all per-biome properties and keeps a static registry of 256 biome slots. Each biome gets created in Biome::staticCtor() using a builder-style chain.

FieldTypeDescription
idconst intNumeric biome ID (0-255), index into Biome::biomes[]
m_namewstringDisplay name
colorintMap color (RGB hex)
topMaterialbyteSurface block ID (default: grass)
materialbyteSub-surface block ID (default: dirt)
temperaturefloatTemperature value; controls snow/rain threshold
downfallfloatRainfall amount; affects humidity classification
depthfloatBase terrain height (negative = below sea level)
scalefloatTerrain height variation
leafColorintLeaf tint color
m_grassColoreMinecraftColourGrass color enum (loaded from texture pack)
m_foliageColoreMinecraftColourFoliage color enum
m_waterColoreMinecraftColourWater color enum
m_skyColoreMinecraftColourSky color enum
snowCoveredboolWhether biome has snow on the ground
_hasRainboolWhether rain is enabled
decoratorBiomeDecorator *Controls feature placement counts

The biome constructor chain uses these private/protected setters:

MethodPurpose
setTemperatureAndDownfall(float, float)Set climate values
setDepthAndScale(float, float)Set terrain shape
setName(wstring)Set display name
setColor(int)Set map color
setLeafColor(int)Set leaf tint
setSnowCovered()Mark as snow biome
setNoRain()Disable rain
setLeafFoliageWaterSkyColor(...)Set all four color enums at once (4J addition)
  • Snow: A biome has snow if rain is enabled and temperature < 0.15f.
  • Rain: A biome has rain if _hasRain == true and it doesn’t snow.
  • Humidity: A biome counts as humid when downfall > 0.85f.

Colors for grass, foliage, water, and sky are loaded from the texture pack’s color table using per-biome eMinecraftColour enums instead of being computed from temperature/downfall like vanilla Java Edition does. This is a 4J Studios change.

MethodDescription
getTreeFeature(Random*)Returns a Feature* for tree generation (biome picks the tree type)
getGrassFeature(Random*)Returns a Feature* for tall grass/fern generation
getSkyColor(float temp)Sky color at a given temperature
hasSnow()Whether the biome gets snow
hasRain()Whether the biome gets rain
isHumid()Whether downfall > 0.85
getCreatureProbability()Spawn probability for passive mobs
getDownfallInt()Integer downfall (0-255 range)
getTemperatureInt()Integer temperature (0-255 range)
getDownfall()Raw float downfall value (4J addition)
getTemperature()Raw float temperature value (4J addition)
decorate(Level*, Random*, int xo, int zo)Run biome-specific decoration
getGrassColor()Grass tint for this biome
getFolageColor()Foliage tint (note the typo in the source)
getWaterColor()Water tint (4J addition)

All 23 biomes (BIOME_COUNT = 23) are created in Biome::staticCtor(). Here’s the full table straight from the source code:

IDNameClassTempDownfallDepthScaleSurfaceSnowRain
0OceanOceanBiome0.50.5-1.00.4grass/dirtnoyes
1PlainsPlainsBiome0.80.40.10.3grass/dirtnoyes
2DesertDesertBiome2.00.00.10.2sand/sandnono
3Extreme HillsExtremeHillsBiome0.20.30.31.5grass/dirtnoyes
4ForestForestBiome0.70.80.10.3grass/dirtnoyes
5TaigaTaigaBiome0.050.80.10.4grass/dirtyesno
6SwamplandSwampBiome0.80.9-0.20.1grass/dirtnoyes
7RiverRiverBiome0.50.5-0.50.0grass/dirtnoyes
8HellHellBiome2.00.00.10.3grass/dirtnono
9Sky (The End)TheEndBiome0.50.50.10.3dirt/dirtnono
10Frozen OceanOceanBiome0.00.5-1.00.5grass/dirtyesno
11Frozen RiverRiverBiome0.00.5-0.50.0grass/dirtyesno
12Ice PlainsIceBiome0.00.50.10.3grass/dirtyesno
13Ice MountainsIceBiome0.00.50.31.3grass/dirtyesno
14Mushroom IslandMushroomIslandBiome0.91.00.21.0mycelium/dirtnoyes
15Mushroom Island ShoreMushroomIslandBiome0.91.0-1.00.1mycelium/dirtnoyes
16BeachBeachBiome0.80.40.00.1sand/sandnoyes
17Desert HillsDesertBiome2.00.00.30.8sand/sandnono
18Forest HillsForestBiome0.70.80.30.7grass/dirtnoyes
19Taiga HillsTaigaBiome0.050.80.30.8grass/dirtyesno
20Extreme Hills EdgeExtremeHillsBiome0.20.30.20.8grass/dirtnoyes
21JungleJungleBiome1.20.90.20.4grass/dirtnoyes
22Jungle HillsJungleBiome1.20.91.80.5grass/dirtnoyes

The depth and scale values directly affect how the noise generator shapes terrain:

  • depth shifts the density curve up or down. Negative depth (like Ocean at -1.0) creates terrain below sea level. Positive depth raises it above.
  • scale controls how rough and varied the terrain height is. High scale (like Extreme Hills at 1.5) means big height swings. Low scale (like Swampland at 0.1) means flat.

These values get smoothed with neighboring biomes during prepareHeights() using a 5x5 weighted kernel, so you don’t get hard edges between biomes.


Each subclass tweaks mob spawns, decorator counts, tree types, and/or decoration behavior.

  • Trees are disabled (treeCount = -999)
  • Lots of grass (10), extra flowers (4)
  • Default friendly mob spawns
  • Uses the base getTreeFeature() which returns a normal oak tree (not that it matters since treeCount is negative)
  • Clears all friendly mob spawns (no passive mobs)
  • Surface: sand over sand
  • No trees, dead bushes (2), reeds (50), cacti (10)
  • Custom decorate(): 1/1000 chance per chunk to place a DesertWellFeature
  • Clears the friendlies list only (Sheep, Pig, Cow removed; chickens still spawn through friendlies_chicken)
  • Custom decorate(): generates emerald ore (3-8 veins per chunk, Y range 4 to genDepth / 4)
  • GENERATE_EMERALD_ORE is a compile-time constant set to true
  • Wolves added to friendlies_wolf (weight 5)
  • Trees: 10 per chunk; 1/5 chance birch, 1/10 chance fancy oak, otherwise normal oak
  • Grass count: 2
  • getTreeFeature() returns BirchFeature, BasicTree, or TreeFeature based on random rolls
  • Wolves added (weight 8)
  • Trees: 10 per chunk; 1/3 chance pine, otherwise spruce
  • Temperature set to 0.05 (snow-covered)
  • Grass count: 1
  • getTreeFeature() returns either PineFeature or SpruceFeature
  • Trees: 2 per chunk, always SwampTreeFeature
  • Flowers are disabled (flowerCount = -999)
  • Dead bushes (1), mushrooms (8), reeds (10), clay (1), waterlilies (4)
  • getTreeFeature() always returns SwampTreeFeature
  • Clears friendlies, friendlies_chicken, and friendlies_wolf (no passive land mobs on rivers)
  • Inline constructor in header; no extra decoration
  • Frozen River (ID 11) uses the same class but with temperature 0.0 and setSnowCovered()
  • Clears all default mobs
  • Enemies: Ghast (weight 50), Zombie Pigman (weight 100), Magma Cube (weight 1)
  • No rain
  • Note: Nether fortress mobs (Blaze, etc.) are handled separately by NetherBridgeFeature::getBridgeEnemies()
  • Clears all default mobs; adds Enderman (weight 10) as enemy
  • Surface: dirt/dirt
  • Uses TheEndBiomeDecorator instead of the default decorator
  • TheEndBiomeDecorator holds:
    • spikeFeature: a SpikeFeature for obsidian pillars
    • endPodiumFeature: an EndPodiumFeature for the exit portal
    • Static SpikeValA[8] array containing pre-computed spike data (chunk coordinates, world position, radius)
  • Clears friendlies, friendlies_chicken, and friendlies_wolf (no passive land mobs)
  • Inline constructor in header
  • Frozen Ocean (ID 10) uses the same class but with temperature 0.0 and setSnowCovered()
  • No extra customization beyond the base class; snow coverage is set through setSnowCovered() in staticCtor()
  • Ice Mountains (ID 13) has higher depth (0.3) and scale (1.3) for mountainous terrain
  • Clears all mob lists (enemies, friendlies, water creatures)
  • Adds Mooshroom to friendlies_mushroomcow (weight 8, groups of 4-8)
  • Surface: mycelium
  • Trees/flowers/grass all set to -100 (basically disabled); mushrooms (1), huge mushrooms (1)
  • The shore variant (ID 15) has depth -1.0 and scale 0.1 for the water-level transition
  • Clears friendlies and friendlies_chicken (Sheep, Pig, Cow, Chicken removed; friendlies_wolf isn’t cleared but wolves are never added to beaches anyway)
  • Surface: sand/sand
  • Trees disabled (treeCount = -999), dead bushes (0), reeds (0), cacti (0)
  • High tree count (50), grass (25), flowers (4)
  • Adds Ocelot to enemies (weight 2, groups of 1) and extra Chickens to friendlies (weight 10, groups of 4). Note: added to the main friendlies list, not friendlies_chicken
  • Tree selection in getTreeFeature():
    • 1/10 chance: fancy oak (BasicTree)
    • 1/2 chance: ground bush (GroundBushFeature with jungle trunk/leaf types)
    • 1/3 chance: mega jungle tree (MegaTreeFeature)
    • Otherwise: normal jungle tree (TreeFeature with jungle trunk/leaf types and vine features)
  • Custom getGrassFeature(): 1/4 chance fern, otherwise tall grass
  • Custom decorate(): places 50 VinesFeature per chunk after the base decoration
  • Not assigned to any biome ID in staticCtor(); seems to be an unused/legacy biome class
  • Tree selection: 1/3 fancy oak, otherwise normal oak

The base Biome constructor sets up default spawn lists:

CategoryMobsWeights
friendliesSheep (12), Pig (10), Cow (8)groups of 4
friendlies_chickenChicken (10)groups of 4
enemiesSpider (10), Zombie (10), Skeleton (10), Creeper (10), Slime (10), Enderman (1)groups of 4 (Enderman: 1-4)
waterFriendliesSquid (10)groups of 4

Each entry is a MobSpawnerData that extends WeighedRandomItem:

class MobSpawnerData : public WeighedRandomItem {
eINSTANCEOF mobClass; // Mob type enum
int minCount; // Minimum group size
int maxCount; // Maximum group size
};

4J Studios split chickens, wolves, and mooshrooms into their own MobCategory lists (friendlies_chicken, friendlies_wolf, friendlies_mushroomcow) for tighter spawn control. The getMobs() method looks at the MobCategory to return the right list.

This split lets the game control spawn rates for these animals independently. For example, chickens can have different spawn caps than other passive mobs.

BiomeFriendliesFriendlies (chicken)Friendlies (wolf)EnemiesWater
PlainsDefaultDefaultDefaultDefault
DesertClearedClearedDefaultDefault
Extreme HillsClearedDefaultDefaultDefault
ForestDefaultDefaultWolf (5)DefaultDefault
TaigaDefaultDefaultWolf (8)DefaultDefault
SwampDefaultDefaultDefaultDefault
RiverClearedClearedClearedDefaultDefault
HellClearedClearedGhast/ZPigman/MagmaCubeCleared
The EndClearedClearedEnderman (10)Cleared
OceanClearedClearedClearedDefaultDefault
Ice Plains/MountainsDefaultDefaultDefaultDefault
Mushroom IslandClearedClearedClearedCleared + Mooshroom
BeachClearedClearedDefaultDefault
JungleDefault + Chicken(10)DefaultDefault + Ocelot(2)Default

BiomeDecorator handles per-chunk feature placement. Each biome can override decorator counts in its constructor.

FeatureCountDescription
treeCount0Trees per chunk (10% bonus chance for +1)
flowerCount2Yellow flower placements (1/4 chance rose)
grassCount1Tall grass placements
deadBushCount0Dead bush placements
mushroomCount0Mushroom placement attempts
reedsCount0Sugar cane placements
cactusCount0Cactus placements
waterlilyCount0Waterlily placements
hugeMushrooms0Huge mushroom placements
sandCount3Sand patches
clayCount1Clay patches
gravelCount1Gravel patches
liquidstrueWhether to place water/lava springs

BiomeDecorator creates these feature objects in _init():

FieldFeature ClassPurpose
clayFeatureClayFeatureClay disk patches
sandFeatureSandFeatureSand disk patches
gravelFeatureSandFeatureGravel disk patches (same class as sand)
dirtOreFeatureOreFeatureDirt vein generation
gravelOreFeatureOreFeatureGravel vein generation
coalOreFeatureOreFeatureCoal ore veins
ironOreFeatureOreFeatureIron ore veins
goldOreFeatureOreFeatureGold ore veins
redStoneOreFeatureOreFeatureRedstone ore veins
diamondOreFeatureOreFeatureDiamond ore veins
lapisOreFeatureOreFeatureLapis lazuli ore veins
yellowFlowerFeatureFlowerFeatureDandelion placement
roseFlowerFeatureFlowerFeatureRose/poppy placement
brownMushroomFeatureFlowerFeatureBrown mushroom placement
redMushroomFeatureFlowerFeatureRed mushroom placement
hugeMushroomFeatureHugeMushroomFeatureGiant mushroom placement
reedsFeatureReedsFeatureSugar cane placement
cactusFeatureCactusFeatureCactus placement
waterlilyFeatureFlowerFeatureLily pad placement

These biome classes are declared as friend of BiomeDecorator so they can directly modify the protected count fields:

DesertBiome, ForestBiome, PlainsBiome, SwampBiome, TaigaBiome, MushroomIslandBiome, BeachBiome, JungleBiome

decorateOres() places ores with these settings:

OreVeins/chunkVein sizeMax height
Dirt2032genDepth
Gravel1032genDepth
Coal2016genDepth
Iron208genDepth/2
Gold28genDepth/4
Redstone87genDepth/8
Diamond17genDepth/8
Lapis Lazuli16Average around genDepth/8

Lapis uses decorateDepthAverage() for a triangular distribution centered at genDepth/8.

  1. Ores
  2. Sand, clay, gravel patches
  3. Trees (count + 10% bonus)
  4. Huge mushrooms
  5. Flowers (yellow + rose)
  6. Tall grass
  7. Dead bushes
  8. Waterlilies
  9. Mushrooms (brown + red)
  10. Additional brown/red mushroom attempts (global, outside biome count)
  11. Sugar cane (biome count + 10 extra)
  12. Pumpkins (1/32 chance)
  13. Cacti
  14. Water springs (50 per chunk)
  15. Lava springs (20 per chunk)

Biome selection is driven by a chain of Layer objects, built in Layer::getDefaultLayers(). Each layer transforms an integer grid (intArray) representing biome IDs or terrain categories.

Layer uses a linear congruential generator (LCG) with the constant 6364136223846793005 for deterministic pseudo-random output. The initRandom(x, y) method seeds per-cell randomness, and nextRandom(max) returns values in [0, max).

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

Key methods:

static LayerArray getDefaultLayers(__int64 seed, LevelType *levelType);
Layer(__int64 seedMixup);
virtual void init(__int64 seed);
virtual void initRandom(__int64 x, __int64 y);
virtual intArray getArea(int xo, int yo, int w, int h) = 0;
int nextRandom(int max);

The full layer chain for normal world generation:

IslandLayer(1)
-> FuzzyZoomLayer(2000)
-> AddIslandLayer(1)
-> ZoomLayer(2001)
-> AddIslandLayer(2)
-> AddSnowLayer(2)
-> ZoomLayer(2002)
-> AddIslandLayer(3)
-> ZoomLayer(2003)
-> AddIslandLayer(4)
-> [branch: river pipeline]
-> [branch: biome pipeline]

River branch:

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

Biome branch:

-> ZoomLayer (1x)
-> BiomeInitLayer(200)
-> ZoomLayer (2x)
-> RegionHillsLayer(1000)
-> [zoomLevel iterations of ZoomLayer, with:]
i=0: AddIslandLayer(3), AddMushroomIslandLayer(5)
i=1: GrowMushroomIslandLayer(5), ShoreLayer(1000), SwampRiversLayer(1000)
-> SmoothLayer(1000)
-> RiverMixerLayer(100) [merges river + biome]
-> [optional BiomeOverrideLayer for debug]
-> VoronoiZoom(10) [final zoom for block-level precision]

The zoomLevel is normally 4, or 6 for LevelType::lvl_largeBiomes.

LayerPurpose
IslandLayerInitial noise: random land (1) vs ocean (0)
FuzzyZoomLayer2x zoom with random interpolation
ZoomLayerStandard 2x zoom with bilinear-like interpolation
AddIslandLayerRandomly converts ocean cells to land
AddSnowLayerMarks cold regions (value 3+4) for snow biomes
AddMushroomIslandLayerPlaces mushroom island biome in isolated ocean
GrowMushroomIslandLayerExpands mushroom islands by region-growing (4J custom)
BiomeInitLayerAssigns actual biome IDs from the starter biome set
RegionHillsLayerConverts base biomes to their hills variants
ShoreLayerAdds beach/shore transitions
SwampRiversLayerIntegrates swamp-adjacent rivers
RiverInitLayerSeeds the river noise pattern
RiverLayerGenerates river biome from noise
RiverMixerLayerCombines river and biome layers
SmoothLayerSmooths biome boundaries
VoronoiZoomFinal cell-based zoom for block-level biome resolution
BiomeOverrideLayerDebug: overrides biomes from a 216x216 byte array

The set of biomes available for initial assignment depends on LevelType:

  • lvl_normal_1_1 (pre-1.2.3): Desert, Forest, Extreme Hills, Swampland, Plains, Taiga (6 biomes)
  • Other level types: Same plus Jungle (7 biomes)

Cold regions (snow layer value >= 2) are limited to Taiga or Ice Plains.

RegionHillsLayer converts base biomes to their hills variants:

Base BiomeHills Variant
Desert (2)Desert Hills (17)
Forest (4)Forest Hills (18)
Taiga (5)Taiga Hills (19)
Extreme Hills (3)Smaller Extreme Hills (20)
Jungle (21)Jungle Hills (22)

Other biomes (Plains, Swampland, etc.) don’t have hills variants and stay the same.

4J Studios modifications to the layer pipeline

Section titled “4J Studios modifications to the layer pipeline”
  • Mushroom islands: Moved 3 zoom levels later than vanilla Java, making them roughly 1/8 the original size. A custom GrowMushroomIslandLayer then region-grows them back into compact shapes that fit within the console world boundaries.
  • Shore layer: Applied at zoom iteration 1 instead of 0.
  • Large biomes: zoomLevel bumped from 4 to 6 for lvl_largeBiomes.

BiomeSource is the main way to query biomes at world coordinates. It holds two Layer references:

  • layer: the main biome layer (used for getBiomeBlock())
  • zoomedLayer: the Voronoi-zoomed layer (used for block-level precision)
MethodDescription
getBiome(ChunkPos*)Returns the biome for a chunk position
getBiome(int x, int z)Returns the biome at block coordinates
getBiomeBlock(int x, int z, int w, int h)Returns a rectangular array of biomes
getBiomeIndexBlock(...)Returns biome indices as byte array
getRawBiomeBlock(...)Gets biome data without Voronoi zoom
getRawBiomeIndices(...)Gets raw biome indices (4J addition)
getTemperature(int x, int y, int z)Temperature at a position (scaled by altitude via scaleTemp())
getDownfall(int x, int z)Downfall value at a position
getTemperatureBlock(...)Bulk temperature query
getDownfallBlock(...)Bulk downfall query
containsOnly(int x, int z, int r, vector<Biome*> allowed)Checks if an area only has the specified biomes (used by structure placement)
containsOnly(int x, int z, int r, Biome* allowed)Single-biome version
findBiome(int x, int z, int r, Biome* toFind, Random*)Searches for a specific biome within a radius
findBiome(int x, int z, int r, vector<Biome*> allowed, Random*)Searches for any of several biomes
findSeed(LevelType*)Static method that searches for a valid seed (PS Vita has early-out support)
getPlayerSpawnBiomes()Returns the list of biomes valid for player spawning

BiomeSource::scaleTemp() adjusts temperature based on altitude. This is a 4J addition brought forward from version 1.2.3. Higher positions are colder.

Used for superflat worlds. Always returns the same biome with constant temperature and downfall values. Every spatial query returns that fixed biome.

BiomeCache caches biome data in 256x256 block regions (CACHE_DIAMETER = 256) so the system doesn’t have to re-run the layer pipeline for the same area. BiomeSource creates and manages this cache internally. Cache blocks are accessed via getBlockAt().

The biome system is basically the same between LCEMP and MC. Both have 23 biomes (BIOME_COUNT = 23) with the same IDs, names, and properties. The biome registry, layer pipeline, and decorator system are identical in structure.

The one notable difference is that MC’s SwampBiome now participates in the scattered feature system for witch hut generation. The swamp biome’s enemy list can include Witch spawns near witch hut structures. In LCEMP, swamps don’t have any special structure-related spawning.

Otherwise, the biome classes, decorator counts, and mob spawn lists are the same across both codebases.