Skip to content

World generation: seed plus edits ​

You'll learn: how a lobby's terrain is made, and why lobbies are cheap. You'll need this when: your game has generated terrain, or players dig and build.

Status: the recipe, per-lobby seeds, regenerateTerrain and mods' world-gen features (ore, tree, scatter, structure) are Built, with four simple generators; onlookers' pages generate the same blocks from the recipe and the seed. biome and loot features are registered but not used by generation yet. The engine's own generators in place of the simple ones are Planned.

A lobby is seed plus edits ​

Your plot's terrain is built in layers:

  lobby's edit layer     what players changed in this lobby (a sparse diff)
          over
  the shared base        what you placed by hand and published (structures, the lobby area)
          over
  generated terrain      generate(recipe, this lobby's seed), inside your bounds

Each lobby has its own seed, so two lobbies can be two different worlds from the same recipe. Onlookers don't download your terrain: they get the recipe and the seed, generate it themselves, then apply the edits. That's why lobbies are cheap.

One hills recipe, three lobbies with three seeds; the third has its own edits

Rendered with the runtime's headless renderer from makeGenerator (source: img/src/render-worldgen.mjs).

The recipe ​

A runtime declares it in plot.json:

json
{ "kind": "runtime", "worldgen": { "generator": "hills", "seed": 7, "features": ["ores:copper"] } }
GeneratorMakes
"flat"grass over dirt over stone (or your own layers)
"hills"gentle value-noise hills
"void"air: sky islands are yours to place
"world" (or none)the world's own terrain under your plot

Seeds and regenerating ​

ts
const id = lobbies.create({ seed: 1234 });   // runtime, plot level; default: derived from the plot and lobby ids
lobbies.regenerateTerrain(id, 5678);         // drop this lobby's edits and generate again (refused unless empty)

Want 20 different maps? Create 20 lobbies with 20 seeds.

Features from mods ​

A mod can add to every lobby's generation:

ts
import { worldgen } from "@inventery/minecraft";
worldgen.feature("copper", "ore", { block: "ores:copper_ore", veinsPerChunk: 6, maxY: 40 });

The runtime names the features its recipe uses in worldgen.features, in order; each is applied over the generated terrain, deterministically from the lobby's seed, per 16×16 column. data per kind (defaults in brackets):

Kinddata
oreblock, replaces (["stone"]), veinsPerChunk (4), size (4), minY, maxY
treetrunk ("oak_log"), leaves ("oak_leaves"), perChunk (2), height ([4, 6]), on (["grass"])
scatterblock, perChunk (8), on (["grass"])
structureblocks ([[dx, dy, dz, block], ...]), chance (0.1), on
biome, lootregistered only, for now

A feature naming an unknown block or feature id is skipped.

Hand-placed content on top ​

Anything you write at plot level goes into the shared base, which every lobby sees and none can change:

ts
export function init() {
  if (!storage.getPlot("built")) {
    world.fillBox({ min: [0, 18, 4], max: [8, 19, 12] }, world.blockId("stone"));   // an island, in every lobby
    storage.setPlot("built", true);
  }
}

In a lobby hook, the same world.fillBox writes that lobby's edit layer instead. Coordinates in host calls are world coordinates (world.bounds().min is the plot's corner).

Next ​

The scene and visibility sets.