Skip to content

BlockLayers and PostProcess

Zaldaryon edited this page Aug 28, 2026 · 1 revision

BlockLayers and post-process

WorldgenLib treats the later world-generation passes as separate hosts. They have different execution order and different data contracts, so terrain hooks should not be used as a substitute for them.

BlockLayers

GenBlockLayersHost exposes two inline hooks around the final vanilla terrain raise:

WorldgenLibAPI.RegisterBlockLayersRaiseModifier(
    "my-mod",
    OrderBands.AfterVanillaMin + 50,
    (localX, localZ, currentRaise, mapChunk) =>
        currentRaise * RiverPower(localX, localZ));

WorldgenLibAPI.RegisterBlockLayersSeaLevelFilter(
    "my-mod",
    OrderBands.AfterVanillaMin + 60,
    (localX, localZ, mapChunk) =>
        ShouldKeepSeaLevelRise(localX, localZ));

Raise modifiers receive local X/Z, the current finite raise value, and the map chunk. Their returned value becomes the input to the next modifier. A non-finite return disables that mod's registrations for the rest of the session.

Sea-level filters return true to keep the raise. The first false result zeroes it. Exceptions disable the failing registration and leave the current decision unchanged.

The inline seam is installed with structural IL validation. If the target Vintage Story build does not contain the expected final-raise pattern, inline registration throws a clear InvalidOperationException. WorldgenLib does not silently attach a hook to an unknown instruction sequence.

Complete BlockLayers adapter

WorldgenLibAPI.RegisterFullBlockLayersGeneration(
    "my-mod",
    OrderBands.FinalOverrideMin,
    request =>
    {
        GenerateCompleteBlockLayers(request);
        return true;
    });

The first full-pass hook returning true owns the request. Returning false lets the next hook or the native pass continue. Use this for a full stream-aware layer algorithm that cannot be represented as a scalar raise or filter.

Floating-node post-process

GenTerraPostProcessHost mirrors the decoration pass that removes floating solid nodes. It is active only when the world's decoration pass is enabled. The host floods connected solid blocks and deletes a floating component of 40 blocks or fewer when no hook vetoes it.

Opt out a chunk

WorldgenLibAPI.RegisterPostProcessOptOut(
    "my-mod",
    OrderBands.BeforeVanillaMax,
    (chunkX, chunkZ) => IsProtectedChunk(chunkX, chunkZ));

Return true to skip post-processing for that chunk. Return false to continue through the registered opt-out hooks and the normal cleanup pass.

Keep a specific floating node

WorldgenLibAPI.RegisterCleanupRule(
    "my-mod",
    OrderBands.BeforeVanillaMax,
    (worldX, worldY, worldZ, nodeSize) =>
        !IsProtectedNode(worldX, worldY, worldZ, nodeSize));

The cleanup rule returns true to allow deletion and false to retain the node. Rules run in order. The first false vetoes deletion. A rule that throws is disabled.

The post-process callback checks its registration state on every invocation. After unload or hot reload, a stale event reference becomes a no-op.

Clone this wiki locally