Seed map architecture

What runs where, what is exact, and what the WebAssembly generation engine adds.

Pipeline

  1. The page parses and validates the seed, version and dimension from the route and query string.
  2. A small pool of workers is created, each building its own generation engine for those parameters.
  3. The worker reports progress through named phases: engine, version, biomes, structures, render.
  4. The main thread requests structure data for the visible bounds, and terrain tiles when the engine supports them.
  5. The renderer draws one frame per animation frame onto a single canvas.

Threading

Nothing expensive runs on the main thread. The workers own the engine, structure scanning, slime chunk detection and terrain rasterisation; the main thread owns input, camera state and drawing. Requests carry a generation token, and a worker abandons any work whose token is stale — that is how panning quickly cancels superseded work instead of queueing it.

Terrain is the expensive part: every tile runs the real surface model over its area. Tiles are spread round-robin across a pool of up to four workers, each with its own engine instance, so no state is shared and no locking is needed. World setup, structure scans and inspection go to the first worker, which keeps those answers consistent and cheap.

Message types: START_GENERATION, GENERATE_REGION, CANCEL_GENERATION, CHANGE_VERSION, CHANGE_DIMENSION, SET_VIEWPORT, GET_STRUCTURE_DATA, FIND_NEAREST, INSPECT_POSITION.

Rendering

Terrain is rasterised in the workers from two real inputs: a biome grid and a surface height grid, both produced by the generation engine. Colour, the light model and the surface textures are presentation only — they never move a coastline or change an elevation.

  • One canvas, no per-feature DOM nodes.
  • Terrain is rasterised into 128-pixel tiles aligned to a world-space grid, so tiles survive panning.
  • Relief shading comes from the engine's surface heights, lit from the upper left.
  • Water depth is the distance below sea level, so shallows and deep ocean read differently.
  • Tiles are transferred as ImageBitmaps and blitted without touching pixel data on the main thread.
  • An LRU cache holds recent tiles and closes evicted bitmaps; capacity shrinks on low-memory devices.
  • Markers, grids, labels and overlays are drawn as vectors, with viewport culling before each draw.
  • Zoom is a power-of-two ladder so tiles align exactly and biome sampling can use integer scales.

Detail levels

Sampling cost scales with the world area on screen, so the renderer changes what it asks for as you zoom.

Rendering detail by zoom level
ZoomBiome samplingReliefSurface detail
1 block per pixel or closerscale 1FullFull texture
Up to 4 blocks per pixelscale 4FullFading
8 to 32 blocks per pixelscale 4 – 16Biome elevation class onlyNone
64 blocks per pixel and beyondscale 64 – 256Biome elevation class onlyDownsampling filter

Relief is dropped once a tile would need more than about twenty thousand height samples, which is also the point where it stops being visible. Dense structure layers wait for zoom rather than drawing thousands of overlapping markers.

The generation engine

There are two implementations behind one interface.

Structure-only engine (always present)

Pure JavaScript, bit-exact ports of the vanilla algorithms. It answers:

  • Structure region candidate positions for every grid-placed structure.
  • Slime chunks.
  • Seed parsing, including Java string hashing for text seeds.
  • Block, chunk, region and Nether coordinate conversions.

WebAssembly engine (optional)

A WebAssembly build of cubiomes, a C implementation of Minecraft world generation. It supplies:

  • biome sampling at every scale, which is what the terrain colours are drawn from;
  • surface heights, which drive relief shading and water depth;
  • biome and terrain validation of structure candidates;
  • stronghold positions and world spawn.

The artefact is not committed to the repository. Run npm run engine:build with the WASI SDK available to produce public/wasm/minecraft-generator/mineseed-gen.wasm — a single 530 KiB module with no JavaScript glue. The loader checks for it at runtime and reports the engine as unavailable when it is absent.

Candidates versus confirmed structures

Minecraft chooses a structure position on a region grid and then checks the biome and terrain there. Without the engine, only the first half can be evaluated, so markers are labelled candidates and the layer panel says so. With the engine, candidates are filtered through the real checks and reported as confirmed. The application never fabricates the second step. Background on the algorithm →

Error handling

  • Invalid or out-of-range seeds are rejected before any work starts, with a plain-language message.
  • Worker creation failure, worker crashes and message errors surface as a readable status, never a stack trace.
  • A failed engine load falls back to the structure-only engine rather than breaking the map.
  • Long operations report progress and can be cancelled.