hytale-world-gen

star 10

Documents Hytale's procedural world generation systems for plugin development. Covers the Java API (Zones, Biomes, Caves) and the data-driven node/JSON system (Density, Curves, Patterns, Material Providers, Props, Scanners, Positions, Assignments, Vector Providers, Block Masks). Use when creating custom zones, biomes, caves, terrain, world generation features, density fields, asset packs, or working with the Hytale Node Editor. Triggers - world gen, world generation, zone, biome, cave, ZonePatternGenerator, BiomePatternGenerator, CaveGenerator, CaveType, Zone, CustomBiome, TileBiome, ZoneDiscoveryConfig, ZoneGeneratorResult, CaveBiomeMaskFlags, terrain, procedural generation, border transition, biome mask, density, noise, simplex, curves, patterns, material provider, props, prefab, scanner, positions, assignments, vector provider, block mask, asset pack, HytaleGenerator, node editor.

JBurlison By JBurlison schedule Updated 3/8/2026

name: hytale-world-gen description: Documents Hytale's procedural world generation systems for plugin development. Covers the Java API (Zones, Biomes, Caves) and the data-driven node/JSON system (Density, Curves, Patterns, Material Providers, Props, Scanners, Positions, Assignments, Vector Providers, Block Masks). Use when creating custom zones, biomes, caves, terrain, world generation features, density fields, asset packs, or working with the Hytale Node Editor. Triggers - world gen, world generation, zone, biome, cave, ZonePatternGenerator, BiomePatternGenerator, CaveGenerator, CaveType, Zone, CustomBiome, TileBiome, ZoneDiscoveryConfig, ZoneGeneratorResult, CaveBiomeMaskFlags, terrain, procedural generation, border transition, biome mask, density, noise, simplex, curves, patterns, material provider, props, prefab, scanner, positions, assignments, vector provider, block mask, asset pack, HytaleGenerator, node editor.

Hytale World Generation System

Comprehensive reference for Hytale's procedural world generation systems used to create environments, biomes, and structures dynamically as players explore the world.

Related skills: For ECS fundamentals, see hytale-ecs. For persistent data/Codec patterns, see hytale-persistent-data. For entity effects, see hytale-entity-effects.

Official worldgen docs recently removed dedicated directionality coverage. Any remaining directionality notes in this skill are preserved as legacy references and should be re-verified against current server source before relying on them.

Quick Reference

Task Approach
Get zone at position zoneGen.generate(seed, x, z) returns ZoneGeneratorResult
Get zone from result zoneResult.getZone() returns Zone
Get biome in zone zone.biomePatternGenerator().generateBiomeAt(zoneResult, seed, x, z)
Get cave generator zone.caveGenerator() returns CaveGenerator (nullable)
Get cave types caveGen.getCaveTypes() returns CaveType[]
Check biome cave mask CaveBiomeMaskFlags.canGenerate(flags)
Get border distance zoneResult.getBorderDistance()
Fade near border customBiome.getFadeContainer().getMaskFactor(result)
Create zone discovery new ZoneDiscoveryConfig(...)
Create biome pattern new BiomePatternGenerator(points, tileBiomes, customBiomes)
Create cave config new CaveGenerator(caveTypes)
Create custom zone new Zone(id, name, discovery, caveGen, biomeGen, prefabs)

Overview

Hytale's world generation is organized into three interconnected systems:

World Generation
├── Zones       — Large-scale regions defining overall world structure
├── Biomes      — Terrain characteristics and environment within zones
└── Caves       — Underground structures and networks within zones

These systems are hierarchical: Zones contain Biomes, and both Zones and Biomes influence Cave generation. They work together to produce smooth transitions and coherent regional themes.


Zones

Zones are the largest-scale division in world generation. Each zone defines its own biome patterns, cave configurations, and unique structures (prefabs).

Zone Lookup and Generation

// Get zone at a world position
ZonePatternGenerator zoneGen = /* from world generator */;
ZoneGeneratorResult zoneResult = zoneGen.generate(seed, x, z);
Zone zone = zoneResult.getZone();

ZoneGeneratorResult

The result object provides:

Method Returns Description
getZone() Zone The zone at the queried position
getBorderDistance() double Distance to the nearest zone border

Zone Class

A Zone encapsulates all generation data for a region:

Property Type Description
ID int Unique numeric identifier
Name String Internal name (e.g., "new_custom_zone")
Discovery ZoneDiscoveryConfig Player notification on zone entry
Cave Generator CaveGenerator Cave configuration (nullable)
Biome Pattern BiomePatternGenerator Biome layout within the zone
Unique Prefabs Unique structures placed in the zone

Creating a Custom Zone

// 1. Configure zone discovery (player notification on entry)
ZoneDiscoveryConfig discovery = new ZoneDiscoveryConfig(
    true,                           // Show notification
    "Custom Zone",                  // Display name
    "zone.forest.discover",         // Sound event
    "icons/forest.png",             // Icon
    true,                           // Major zone
    5.0f, 2.0f, 1.5f               // Duration, fade in, fade out
);

// 2. Create biome pattern
IPointGenerator biomePoints;
IWeightedMap<TileBiome> tileBiomes;
CustomBiome[] customBiomes;

BiomePatternGenerator biomeGen = new BiomePatternGenerator(
    biomePoints,
    tileBiomes,
    customBiomes
);

// 3. Create cave configuration
CaveType[] caveTypes; // cave definitions
CaveGenerator caveGen = new CaveGenerator(caveTypes);

// 4. Assemble the zone
Zone customZone = new Zone(
    100,                    // Unique ID
    "new_custom_zone",      // Internal name
    discovery,              // Discovery config
    caveGen,                // Cave generator
    biomeGen,               // Biome pattern
    uniquePrefabs           // Unique structures
);

ZoneDiscoveryConfig

Controls what the player sees when entering a zone:

Parameter Type Description
showNotification boolean Whether to display the zone entry notification
displayName String Name shown to the player
soundEvent String Sound played on zone entry
icon String Icon path for the notification
majorZone boolean Whether this is a major zone (affects display)
duration float How long the notification is visible (seconds)
fadeIn float Fade-in duration (seconds)
fadeOut float Fade-out duration (seconds)

Biomes

Biomes define terrain characteristics, vegetation, and environmental properties within a zone. Each zone has its own BiomePatternGenerator that determines biome layout.

Biome Lookup

// Get the biome at a specific position within a zone
Zone zone = zoneResult.getZone();
BiomePatternGenerator biomeGen = zone.biomePatternGenerator();
Biome biome = biomeGen.generateBiomeAt(zoneResult, seed, x, z);

BiomePatternGenerator

Constructs the biome layout from three inputs:

Parameter Type Description
biomePoints IPointGenerator Point distribution controlling biome placement
tileBiomes IWeightedMap<TileBiome> Weighted map of tile-level biome data
customBiomes CustomBiome[] Custom biome definitions with fade/transition settings

Biome Properties

Each Biome has at minimum:

Method Returns Description
getId() int Unique biome identifier

CustomBiome Fading

Custom biomes support smooth transitions near zone borders via a fade container:

CustomBiome customBiome = /* ... */;
FadeContainer fade = customBiome.getFadeContainer();
double maskFadeSum = fade.getMaskFadeSum();
double factor = fade.getMaskFactor(zoneResult);

Caves

Caves are underground structures generated within zones. Each zone optionally has a CaveGenerator with one or more CaveType definitions.

Cave Lookup

Zone zone = /* ... */;
CaveGenerator caveGen = zone.caveGenerator();
if (caveGen != null) {
    // This zone has caves
    CaveType[] types = caveGen.getCaveTypes();
}

CaveType and Biome Masks

Cave types use biome masks to control where caves can generate:

// Cave type with biome restrictions
Int2FlagsCondition biomeMask = caveType.getBiomeMask();
int biomeId = biome.getId();
int flags = biomeMask.eval(biomeId);

// Check if cave can generate in this biome
if (CaveBiomeMaskFlags.canGenerate(flags)) {
    // Generate cave
}
Class Purpose
CaveGenerator Holds cave type definitions for a zone
CaveType Individual cave definition with shape, biome mask, etc.
Int2FlagsCondition Evaluates biome ID → flags for cave placement
CaveBiomeMaskFlags Utility to interpret biome mask flags (e.g., canGenerate)

System Integration

Zone → Biome Integration

Each zone defines its own biome pattern. The biome generator requires the zone result (for border distance and zone context):

Zone zone = zoneGen.generate(seed, x, z).getZone();
BiomePatternGenerator biomeGen = zone.biomePatternGenerator();
Biome biome = biomeGen.generateBiomeAt(zoneResult, seed, x, z);

Zone → Cave Integration

Each zone defines its own cave patterns. Not all zones have caves:

Zone zone = /* ... */;
CaveGenerator caveGen = zone.caveGenerator();
if (caveGen != null) {
    CaveType[] types = caveGen.getCaveTypes();
}

Biome → Cave Integration

Caves use biome masks to restrict generation to specific biomes:

Int2FlagsCondition biomeMask = caveType.getBiomeMask();
int biomeId = biome.getId();
int flags = biomeMask.eval(biomeId);

if (CaveBiomeMaskFlags.canGenerate(flags)) {
    // Cave can generate in this biome
}

Border Transitions

All systems respect zone boundaries. Custom biomes fade near borders for smooth transitions:

ZoneGeneratorResult result = zoneGen.generate(seed, x, z);
double borderDistance = result.getBorderDistance();

// Fade custom biomes near borders
if (borderDistance < customBiome.getFadeContainer().getMaskFadeSum()) {
    double factor = customBiome.getFadeContainer().getMaskFactor(result);
    // Apply fading based on factor (0.0 = fully faded, 1.0 = full strength)
}

Key Classes Summary

Class Package Area Purpose
ZonePatternGenerator worldgen Generates zones at world positions
ZoneGeneratorResult worldgen Result of zone lookup (zone + border distance)
Zone worldgen Zone definition (biomes, caves, prefabs, discovery)
ZoneDiscoveryConfig worldgen Player notification on zone entry
BiomePatternGenerator worldgen Biome layout within a zone
Biome worldgen Biome data (ID, properties)
CustomBiome worldgen Custom biome with fade/transition support
TileBiome worldgen Tile-level biome data
IPointGenerator worldgen Point distribution for biome placement
IWeightedMap<T> worldgen Weighted map for biome selection
CaveGenerator worldgen Cave configuration for a zone
CaveType worldgen Individual cave type definition
Int2FlagsCondition worldgen Biome mask evaluator for caves
CaveBiomeMaskFlags worldgen Flag utility for cave biome masks
FadeContainer worldgen Border fade/transition controller

Common Patterns

Full World Position → Zone + Biome + Cave Pipeline

// Complete lookup pipeline
ZonePatternGenerator zoneGen = /* from world generator */;
long seed = /* world seed */;
int x = /* world x */;
int z = /* world z */;

// 1. Determine zone
ZoneGeneratorResult zoneResult = zoneGen.generate(seed, x, z);
Zone zone = zoneResult.getZone();

// 2. Determine biome within zone
BiomePatternGenerator biomeGen = zone.biomePatternGenerator();
Biome biome = biomeGen.generateBiomeAt(zoneResult, seed, x, z);

// 3. Check for caves
CaveGenerator caveGen = zone.caveGenerator();
if (caveGen != null) {
    for (CaveType caveType : caveGen.getCaveTypes()) {
        Int2FlagsCondition biomeMask = caveType.getBiomeMask();
        int flags = biomeMask.eval(biome.getId());
        if (CaveBiomeMaskFlags.canGenerate(flags)) {
            // This cave type can generate here
        }
    }
}

// 4. Handle border transitions
double borderDistance = zoneResult.getBorderDistance();
// Use borderDistance for custom blending/fading logic

Zone Entry Notification Setup

// Minimal zone discovery config
ZoneDiscoveryConfig discovery = new ZoneDiscoveryConfig(
    true,                    // Show notification
    "Enchanted Forest",      // Display name
    "zone.forest.discover",  // Sound event
    "icons/forest.png",      // Icon
    true,                    // Major zone
    5.0f, 2.0f, 1.5f        // Duration, fade in, fade out
);


Data-Driven World Generation (Node/JSON System)

Beyond the Java plugin API, Hytale's world generation is primarily data-driven through JSON asset files and an in-game Node Editor. Biomes, terrain shapes, materials, and content placement are all defined declaratively.

Detailed references for every node type are in the references/ subdirectory of this skill.

Asset Directory Structure

Server/HytaleGenerator/
├── WorldStructure/    # Generator files defining which biomes spawn together
├── Biomes/            # Biome assets with content configurations
├── Density/           # Reusable density assets referenced by other generation assets
└── Assignments/       # Reusable prop assignment assets referenced by biomes

World Instance Configuration

Instances are separate worlds that players can join. Each instance has an Instance.bson that specifies which generator to use:

{
  "WorldGen": {
    "Type": "HytaleGenerator",
    "WorldStructure": "Basic",
    "playerSpawn": {
      "X": 123, "Y": 480, "Z": 10000,
      "Pitch": 0, "Yaw": 0, "Roll": 0
    }
  }
}

Instance configs are stored at Server/Instances/. Create custom instances by duplicating the basic config and changing WorldStructure to your asset name.

Previewing World Generation

Command Purpose
/viewport --radius 5 Live-reload area around player as you edit
/instances spawn <instance> Create a new world with latest changes
Fly south New chunks generate with latest changes

Biome Asset Structure

Every biome has 5 root components:

Component Purpose
Terrain Density function nodes defining the physical terrain shape
Material Provider Logic nodes determining which block types make up terrain
Props Object nodes placing prefabs, trees, POIs, grass, etc.
Environment Provider Logic nodes determining weather, NPC spawns, sounds per coordinate
Tint Provider Function nodes determining color codes for grasses, soils, etc.

Each biome is self-contained — it controls everything within its boundaries except Base Heights.

Node System Overview

World generation uses a node-based system of composable JSON assets. Each node type has parameters and inputs:

Node Category Purpose Key Types
Density 3D decimal value fields for terrain shape SimplexNoise2D/3D, PositionsCellNoise, Distance, Ellipsoid, Cube, Cylinder, Sum, Multiplier, Mix, CurveMapper, Scale, Rotator, Warp nodes
Curves f(x)=y mappings for value transformation Manual, DistanceExponential, DistanceS, Ceiling/Floor, SmoothClamp, Clamp, Inverter, Min/Max
Patterns Validate world positions by material/structure BlockType, BlockSet, Floor, Ceiling, Wall, Surface, Gap, Cuboid, And/Or/Not, FieldFunction
Material Providers Determine block types at positions Constant, Solidity, Queue, SimpleHorizontal, Striped, Weighted, FieldFunction, SpaceAndDepth (with Layers and Conditions)
Positions Provider Define infinite 3D position fields Mesh2D, Mesh3D, List, FieldFunction, Occurrence, BaseHeight, Cache
Scanners Scan local world areas for valid positions Origin, ColumnLinear, ColumnRandom, Area
Props Localized content placed in the world Box, Density, Prefab, Column, Cluster, Union, Weighted, Queue, PondFiller
Assignments Assign props to positions Constant, FieldFunction, Sandwich, Weighted
Legacy Directionality Older prop-facing nodes preserved as reference only Static, Random, Pattern-based
Vector Provider Define 3D vectors procedurally Constant, DensityGradient, Cache
Block Mask Control which materials can replace others DontPlace, DontReplace, Advanced rules

Core Concept: Density Fields

Terrain generation is built on density fields — maps of decimal values (typically -1 to 1) defining terrain shape:

  • Positive values → solid terrain
  • Negative values → empty space (air)
  • Density is calculated from the sum of all nodes: f(x) = z + y

Common terrain formula: Simplex 2D noise + Y-Curve (height gradient) = basic terrain shape.

Function nodes manipulate density fields: Absolute (ridged shapes), Normalization (rescaling range), Scale (stretch/contract), Rotator (orientation), Warp (distortion), and many more.

Core Concept: Props Pipeline

Props place procedural content (trees, prefabs, grass) using three connected systems:

Positions → Scanner → Pattern → Prop Placement
  1. Positions provide candidate locations (e.g., Mesh2D grid, BaseHeight offsets)
  2. Scanner searches around each position (e.g., ColumnLinear scans Y range)
  3. Pattern validates positions (e.g., Floor pattern checks for solid ground below)
  4. Prop places content at validated positions (e.g., Prefab placement; older docs also referenced Directionality for facing)

Asset Packs

Asset Packs override or add assets to the base game. Required for world gen customization:

{
  "Group": "My Group",
  "Name": "Pack Example",
  "Version": "1.0.0",
  "Description": "An Example Asset Pack",
  "Authors": [{"Name": "Me", "Email": "", "Url": ""}],
  "Dependencies": {},
  "DisabledByDefault": false,
  "IncludesAssetPack": false,
  "SubPlugins": []
}
  • Stored in C:\Users\<user>\AppData\Roaming\Hytale\UserData\Mods
  • Per-world packs stored in UserData\Saves\<world>\mods
  • Asset Packs exist entirely on the server — only the host needs them
  • Assets inside packs override base game assets

Import/Export System

Most node types support Imported and Exported nodes for reusability:

  • Exported: Makes a node tree available by name, with optional SingleInstance for shared caching
  • Imported: References an exported asset by name
  • This enables modular, reusable density fields, curves, patterns, etc.

Notes

  • The worldgen module is a built-in Hytale module. Plugins interact with it through the public API classes listed above.
  • Zone IDs must be unique across the world generation configuration.
  • CaveGenerator is nullable — not all zones have caves.
  • Biome masks use a flags-based system (Int2FlagsCondition) for efficient cave-biome filtering.
  • Border transitions use FadeContainer with getMaskFadeSum() and getMaskFactor() for smooth blending between zones.
  • The --validate-world-gen server launch flag can be used to validate world generation assets.
  • World gen examples can be found in HytaleGenerator/Biomes/Examples/.
  • The Hytale Node Editor is accessible in-game from the Content Creation menu (Tab key).

Performance Optimization

World-gen prints a performance report to server logs at configurable sample-size intervals. Open it: right-click world in world selection → open world folder → logs/latest. Use reports with Sample Count ≥ 500 for accuracy.

Key metrics to watch: Content Generation: # ms — the time you have the most control over. Each stage (BiomeStage, TerrainStage, PropStages, TintStage, EnvironmentStage) is listed separately.

Density / Terrain

Technique Detail
Use Mix to mask expensive Density Limit costly density fields to only the regions that need them. Replace areas above max terrain height with Constant(-1) and all-underground with Constant(1).
Use YSampled Reduces vertical sample count for density fields where full resolution isn't visually needed. Recommended SampleDistance: 8 for best performance, 2 for high-detail areas. Mix sampled and non-sampled versions for precision only where needed.
Cache nodes Add Cache on the right side of YOverride nodes, and at the root of ChoiceDensity/CellValue Density. SimplexNoise2d and CellNoise2d already cache automatically.
Use Mix over Sum/Min/Max Mix disables fields where they aren't needed; Sum/Min/Max always evaluate all inputs.
Avoid unnecessary Density gradients Gradients resolve the child 4x per position. Mask them out. Inside Material Providers, use the TerrainDensity node (reuses existing buffers) rather than importing the terrain root density.
2D where possible Use 3D density only when required. 3D domain warping invalidates 2D caches from all child nodes.
WorldStructure tuning Don't set DefaultTransitionDistance and MaxBiomeEdgeDistance higher than necessary — they affect BiomeStage and TerrainStage output sizes.

Materials

  • Put expensive Material Providers as far right in the tree as possible; cheap limiters go left.
  • SimpleHorizontal reduces the height range for its children.
  • SpaceAndDepth reduces the depth range for its children.
  • Use FieldFunction with a cheap density mask to limit an expensive Material Provider to a specific world region.
  • Use TerrainDensity node inside Material Providers when referencing the terrain's density for gradients.

Props

  • Keep each Runtime's horizontal size as small as possible — it's determined by the largest Prop in that Runtime.
  • Put Props with the largest horizontal size at the lowest Runtime index.
  • Pack as many Props into one Runtime as possible. Only create new Runtimes when Props need context from other Props.
  • All Biomes in a WorldStructure should use the same Runtime indices to avoid multiplying Runtimes.
  • Break large Props into smaller modular pieces assembled at the Prop Distribution level.

Quick Checklist

  1. Try 2D over 3D everywhere possible.
  2. Place Cache on the right side of all YOverride nodes.
  3. Add YSampled at the root of each Biome's Density as a first pass.
  4. Use Mix (not Sum) to cap terrain above max height and below min height.
  5. Ensure all Biomes share the same Runtime indices.
  6. Check DefaultTransitionDistance and MaxBiomeEdgeDistance in WorldStructure — keep them minimal.

Source: hytalemodding.dev — World Generation Optimization

Source: hytalemodding.dev — World Generation System Source: HytaleModding/site — Official World Generation Documentation

Install via CLI
npx skills add https://github.com/JBurlison/Hytale-Mod-Agent --skill hytale-world-gen
Repository Details
star Stars 10
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator