Skip to main content

Overview

Voxy World Gen V2 provides deep integration with Tellus, a 1:1 scale Earth world generator for Minecraft. This integration enables extremely fast LOD generation for Earth terrain by directly sampling elevation and land cover data.

What is Tellus?

Tellus is a world generator that recreates the entire Earth at 1:1 scale in Minecraft, using real-world elevation data, land cover classifications, and geographic features. The integration allows Voxy World Gen V2 to generate distant terrain chunks much faster than standard world generation.

Automatic Detection

The system automatically detects Tellus worlds at runtime:
public static boolean isTellusWorld(ServerLevel level) {
    if (!initialized) initialize();
    if (!TellusSampler.isTellusPresent()) return false;
    Object generator = level.getChunkSource().getGenerator();
    return generator != null && generator.getClass().getName().contains("EarthChunkGenerator");
}
When a Tellus world is detected, Voxy World Gen V2 automatically switches to the fast generation path. No configuration required.

Integration Architecture

The Tellus integration consists of four main components:

TellusIntegration

Main coordinator that manages worker threads and chunk building

TellusSampler

Reflective access to Tellus elevation, cover, and water data

VoxyIngester

Direct voxel data injection into Voxy’s rendering system

TellusWorldFeatures

Procedural generation of vegetation and decorations

Fast Generation Path

Why It’s Fast

Traditional Minecraft world generation is slow because it:
  • Runs multiple noise samplers
  • Places features one by one
  • Performs complex biome blending
  • Executes expensive decoration passes
The Tellus integration bypasses all of this by:
  1. Direct elevation sampling from Tellus heightmaps
  2. Batch biome resolution using pre-computed climate data
  3. Direct voxel injection into Voxy without intermediate chunk objects
  4. Simplified feature placement with procedural algorithms
The Tellus integration can generate chunks 50-100x faster than traditional generation.

Minimum Generation Radius

Tellus worlds require a minimum generation radius of 128 chunks:
// In ChunkGenerationManager initialization
if (isTellusWorld) {
    config.generationRadius = Math.max(128, config.generationRadius);
}
Why this restriction?
  • Earth-scale worlds benefit most from distant LODs
  • Smaller radii don’t provide meaningful value
  • Ensures worker thread pool operates efficiently
  • Matches typical Voxy render distances
If you configure a radius less than 128, it will be automatically increased to 128 for Tellus worlds.

Sampling Workflow

Step 1: Prefetch Data

Before generation begins, the system prefetches necessary data:
public static void prefetch(ServerLevel level, ChunkPos pos) {
    if (!isTellusPresent()) return;
    try {
        Object generator = level.getChunkSource().getGenerator();
        earthChunkGeneratorClass.getMethod("prefetchForChunk", int.class, int.class)
            .invoke(generator, pos.x, pos.z);
    } catch (Throwable ignored) {}
}
This ensures elevation tiles are loaded before sampling begins.

Step 2: Sample Terrain Data

The system samples elevation, cover class, slopes, and water data for the entire 16×16 chunk:
public record TellusChunkData(
    int[] heights,          // Terrain height per column (256 values)
    byte[] coverClasses,    // ESA land cover classification (256 values)
    byte[] slopes,          // Terrain slope magnitude (256 values)
    boolean[] hasWater,     // Water presence flags (256 values)
    int[] waterSurfaces,    // Water surface heights (256 values)
    int seaLevel            // World sea level
) {}
Heights are sampled from Tellus elevation source with proper scaling:
double elevation = (double) sampleElevationMetersMethod.invoke(
    elevationSource, (double) worldX, (double) worldZ, worldScale, oceanZoom
);
double heightScale = (elevation >= 0.0) ? terrestrialHeightScale : oceanicHeightScale;
double scaled = (elevation * heightScale) / worldScale;
return ((elevation >= 0.0) ? Mth.ceil(scaled) : Mth.floor(scaled)) + heightOffset;
Land cover classes follow ESA CCI standards:
  • 10: Tree cover
  • 80: Water bodies
  • 95: Mangrove
  • 70: Snow/Ice
  • 0: No data (ocean)
Slopes are computed using 4-neighbor sampling:
int hE = samplePixelHeight(..., worldX + 4, worldZ);
int hW = samplePixelHeight(..., worldX - 4, worldZ);
int hN = samplePixelHeight(..., worldX, worldZ - 4);
int hS = samplePixelHeight(..., worldX, worldZ + 4);

int maxDiff = Math.max(
    Math.max(Math.abs(hE - terrainH), Math.abs(hW - terrainH)),
    Math.max(Math.abs(hN - terrainH), Math.abs(hS - terrainH))
);
slopes[i] = (byte) Math.min(255, maxDiff);

Step 3: Build Voxel Data

The sampled data is converted to voxel format and injected directly into Voxy:
private static void buildAndIngest(ServerLevel level, ChunkPos pos, TellusChunkData data) {
    Object voxy = VoxyIngester.getVoxyInstance();
    Object engine = VoxyIngester.getWorldEngine(voxy, level);
    Object mapper = VoxyIngester.getMapper(engine);
    
    // Build 16×16×16 sections
    for (int sy = 0; sy < sectionCount; sy++) {
        Object vs = VoxyIngester.createSection(pos.x, sY, pos.z);
        long[] dataArray = VoxyIngester.getSectionData(vs);
        
        // Fill section with terrain and water
        for (int i = 0; i < 4096; i++) {
            // Compute block based on height, water, and features
            dataArray[i] = blockId;
        }
        
        // Mip and insert into Voxy
        VoxyIngester.mipAndInsert(engine, mapper, vs);
    }
}

Surface Block Palettes

The integration applies biome-specific surface materials:
private static Palette getPalette(Holder<Biome> biome, Random random) {
    if (biome.is(BiomeTags.IS_OCEAN) || biome.is(BiomeTags.IS_RIVER)) {
        int roll = random.nextInt(100);
        if (roll < 10) return new Palette(Blocks.GRAVEL, Blocks.GRAVEL);
        if (roll < 15) return new Palette(Blocks.CLAY, Blocks.CLAY);
        return new Palette(Blocks.SAND, Blocks.SAND);
    }
    if (biome.is(Biomes.DESERT)) 
        return new Palette(Blocks.SAND, Blocks.SANDSTONE);
    if (biome.is(BiomeTags.IS_BEACH)) 
        return new Palette(Blocks.SAND, Blocks.SAND);
    if (biome.is(BiomeTags.IS_BADLANDS)) 
        return new Palette(Blocks.RED_SAND, Blocks.TERRACOTTA);
    if (biome.is(Biomes.MANGROVE_SWAMP)) 
        return new Palette(Blocks.MUD, Blocks.MUD);
    if (biome.is(Biomes.SNOWY_PLAINS) || biome.is(Biomes.SNOWY_TAIGA)) 
        return new Palette(Blocks.SNOW_BLOCK, Blocks.DIRT);
    
    return new Palette(Blocks.GRASS_BLOCK, Blocks.DIRT);
}
Steep slopes (slope ≥ 3) are rendered as stone regardless of biome, simulating rocky cliffs.

Procedural Features

The integration generates vegetation and decorations procedurally:

Tree Generation

Trees are placed based on ESA cover class:
int coverClass = TellusSampler.sampleCoverClass(level, wx, wz);
if (coverClass == 10 || coverClass == 95) {  // Tree cover or mangrove
    int surface = TellusSampler.sampleHeightOnly(level, wx, wz);
    if (surface >= localWaterY) {
        Holder<Biome> biome = biomeSource.getNoiseBiome(...);
        buildProceduralTree(wx, surface + 1, wz, biome, mapper, blocks, random, bId);
    }
}
Tree types are determined by biome:
  • Taiga/Grove/Snowy biomes: Spruce trees with conical canopy
  • Jungle biomes: Large jungle trees with multiple branch layers
  • Birch Forest: Tall birch trees with narrow ellipsoid canopy
  • Dark Forest: 2×2 dark oak trees with broad canopy
  • Default: Oak trees with spherical canopy

Vegetation

Grass and tall grass are placed on suitable terrain:
if (vegAllowed[i]) {  // Grass blocks not underwater
    if (random.nextFloat() < 0.20f) {
        if (random.nextFloat() < 0.15f) {
            // Place tall grass (2 blocks)
            blocks.put(p1, tallGrassLowerId);
            blocks.put(p2, tallGrassUpperId);
        } else {
            // Place short grass (1 block)
            blocks.put(p1, grassId);
        }
    }
}

Underwater Vegetation

Seagrass generates in water bodies:
if (hasWaters[i] && wH - h >= 2 && random.nextFloat() < 0.15f) {
    if (wH - h >= 3 && random.nextFloat() < 0.10f) {
        // Tall seagrass
        blocks.put(new BlockPos(wx, h + 1, wz), tallSeagrassLowerId);
        blocks.put(new BlockPos(wx, h + 2, wz), tallSeagrassUpperId);
    } else {
        // Regular seagrass
        blocks.put(new BlockPos(wx, h + 1, wz), seagrassId);
    }
}

Water Handling

The integration implements sophisticated water surface modeling:

Shoreline Smoothing

Water depths are adjusted near shores to create natural transitions:
// Determine distance to shore
int distToShore = 5;
for (int d = 1; d < 5; d++) {
    boolean foundLand = false;
    // Check ring at distance d
    for (int dz = -d; dz <= d; dz++) {
        for (int dx = -d; dx <= d; dx++) {
            if (!expandedWater[(iz + dz + 4) * 24 + (ix + dx + 4)]) {
                foundLand = true;
                break;
            }
        }
    }
    if (foundLand) {
        distToShore = d;
        break;
    }
}

// Make water shallow near land
int targetH = waterH - distToShore;
if (h > targetH) {
    h = targetH;
}
This prevents harsh water cliffs and creates gradual beaches.

Ocean Depth

Open ocean areas are deepened for realistic appearance:
if (isOcean && h > seaLevel - 8) {
    h = seaLevel - 8;
}

Thread Pool Architecture

Tellus generation uses a dedicated worker pool:
int threadCount = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);
workerPool = new ThreadPoolExecutor(
    threadCount,
    threadCount,
    0L,
    TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<>(10000),
    r -> {
        Thread t = new Thread(r, "tellus-voxy-worker-" + threadCounter.getAndIncrement());
        t.setDaemon(true);
        t.setPriority(Thread.NORM_PRIORITY - 1);
        return t;
    },
    new ThreadPoolExecutor.CallerRunsPolicy()
);
Uses half of available CPU cores to avoid overloading the system while maintaining high throughput.
The 10,000 task queue ensures smooth generation even during rapid player movement.
CallerRunsPolicy prevents task rejection by executing on the calling thread if the queue is full.

Performance Characteristics

Generation Speed

50-100ms per chunk on modern hardwareTraditional generation: 500-2000ms

Memory Usage

~2KB per chunk for intermediate dataTraditional: 50-200KB per chunk

CPU Utilization

Multi-threaded with 50% core allocationScales efficiently to 16+ cores

I/O Impact

Minimal disk access for elevation tilesCached after first access

Configuration

The integration respects all standard Voxy World Gen V2 settings:
{
  "generationRadius": 128,  // Minimum for Tellus worlds
  "maxActiveTasks": 20,     // Concurrent generation tasks
  "maxQueueSize": 20000     // Generation queue size
}
See Configuration for details.

Troubleshooting

Symptoms: Chunks generate slowly despite Tellus integrationPossible causes:
  • Elevation data not prefetched (network latency)
  • Insufficient worker threads
  • CPU thermal throttling
Solutions:
  • Ensure stable internet connection for tile downloads
  • Increase maxActiveTasks if you have many CPU cores
  • Improve system cooling
Symptoms: Terrain generates but lacks trees or vegetationCauses:
  • Cover class data not available
  • Biome sampling issues
Solutions:
  • Check Tellus configuration and data packs
  • Verify biome source is functioning
  • Look for errors in logs
Symptoms: Water appears at wrong heights or missingCauses:
  • Water resolver not initialized
  • Chunk boundary issues
Solutions:
  • Ensure Tellus is up to date
  • Check for mod conflicts
  • Report with chunk coordinates and screenshots

Source Code References

The Tellus integration spans multiple files:
  • TellusIntegration.java (330 lines): Main coordinator and chunk builder
    • Lines 62-67: World detection
    • Lines 69-86: Chunk generation queue
    • Lines 113-328: Voxel building and ingestion
  • TellusSampler.java (261 lines): Reflective data access
    • Lines 60-118: Initialization and method binding
    • Lines 142-211: Terrain data sampling
  • VoxyIngester.java (187 lines): Direct Voxy integration
    • Lines 49-92: Voxy API discovery
    • Lines 145-153: Voxel ID composition
    • Lines 178-185: Section mipmapping and insertion
  • TellusWorldFeatures.java (268 lines): Procedural features
    • Lines 21-55: Vegetation placement
    • Lines 92-149: Tree generation by biome
    • Lines 159-235: Specific tree types

Voxy Integration

Understand the underlying Voxy ingestion system

Performance Tuning

Optimize for maximum generation speed

LOD System

Learn how LOD chunks differ from regular chunks

Architecture

See how Tellus fits into the overall system

Build docs developers (and LLMs) love