Skip to content

Biomes

The simplest way to get a player’s current biome:

Player player = store.getComponent(ref, Player.getComponentType());
WorldMapTracker tracker = player.getWorldMapTracker();
String biomeName = tracker.getCurrentBiomeName(); // e.g. "Forest"
// zone info is a record, not a plain string
WorldMapTracker.ZoneDiscoveryInfo zone = tracker.getCurrentZone();
String zoneName = zone != null ? zone.zoneName() : null;

The tracker updates approximately once per second. Biome and zone names are strings derived from JSON filenames.

To query the biome at an arbitrary position, access the chunk generator directly:

IWorldGen gen = world.getChunkStore().getGenerator();
if (gen instanceof ChunkGenerator chunkGen) {
int seed = (int) world.getWorldConfig().getSeed();
ZoneBiomeResult result = chunkGen.getZoneBiomeResultAt(seed, x, z);
Biome biome = result.getBiome();
String name = biome.getName();
int mapColor = biome.getMapColor();
}

This computes the biome from the world seed and position — it does not read stored data. The result is the same every time for the same coordinates.


World generation uses a Zone > Biome hierarchy:

  1. Zones are large regions (similar to Minecraft biome groups). Each zone has its own set of biomes.
  2. Tile biomes are the primary biomes within a zone, selected by cell noise with weighted probabilities.
  3. Custom biomes are sub-biomes that conditionally overlay tile biomes when noise conditions are met (e.g., a “River” replacing parts of “Plains”).

Biomes blend at boundaries using an interpolation radius (0-5 blocks), producing smooth transitions in terrain height and tint color.

Biomes are identified by:

  • String name — derived from the JSON filename (e.g., Tile.Forest.json -> "Forest")
  • Integer ID — auto-assigned sequentially at load time (0-32767), not persistent across restarts

There is no global biome registry or enum — biomes exist within the context of their zone.


Biomes define tint colors that affect block appearance (foliage, grass). Each block type has per-face tint percentages:

JSON FieldDefaultDescription
BiomeTint0Sets all faces at once (0-100)
BiomeTintUp0Top face override
BiomeTintDown0Bottom face override
BiomeTintNorth0North face override
BiomeTintSouth0South face override
BiomeTintWest0West face override
BiomeTintEast0East face override

A value of 100 means fully tinted by the biome color (grass blocks), 0 means unaffected (stone). Tint colors are computed during chunk generation and sent to the client as part of chunk data.


Biomes are defined as JSON files within zone directories. The filename prefix determines the type:

  • Tile.MyBiome.json — a primary tile biome
  • Custom.MyBiome.json — a sub-biome that overlays tile biomes
FieldTypeDescription
WeightdoubleSelection probability (default: 1.0)
SizeModifierdoubleCell size multiplier, squared internally (default: 1.0)
TerrainHeightThresholdobjectHeight threshold function
CoversobjectSurface cover blocks (grass, flowers)
LayersobjectVertical material layers (soil, fill)
PrefabsobjectStructures that generate in this biome
TintobjectNoise-based biome tint color mapping
EnvironmentobjectEnvironment ID mapping (water color, lighting)
WaterobjectWater level, block type, fluid type
InterpolationobjectBoundary blending config with DefaultRadius (0-5, default: 5) and optional per-biome overrides
MapColorStringHex RGB color for the world map (e.g. "0x2D5A1E")
HeightmapNoiseobjectCustom heightmap noise function
FadeobjectTransition fading at zone borders

Custom biomes inherit all tile biome fields and add:

FieldTypeDescription
CustomBiomeGenerator.NoiseMaskobjectNoise function + Threshold for placement
CustomBiomeGenerator.BiomeMaskString[]Parent biome names this can replace
CustomBiomeGenerator.PriorityintHigher priority = checked first

The HytaleGenerator plugin has a separate asset-based biome system. Biome assets are loaded from HytaleGenerator/Biomes/ via an AssetStore, supporting the standard asset pack structure with inheritance.


  • No setBiome() — biomes are computed from seed + position, not stored per-block. You cannot change the biome at a location at runtime.
  • No biome events — only DiscoverZoneEvent.Display fires when a player enters a new zone for the first time (cancellable). There is no event for biome changes.
  • No global biome registry — biomes are scoped to their zone. Integer IDs are ephemeral and reassigned on each server start.
  • 2D only — biome selection is based on (x, z) coordinates. There are no 3D biomes (unlike Minecraft 1.18+), though environment IDs can vary by height for cave sub-biomes.