-
-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
WorldgenLibMod is a server-only ModSystem with an execution order of -1000. Its lifecycle is:
-
AssetsFinalizeapplies the narrow runtime seams and creates the initial terrain state. -
StartServerSidecreates the map and BlockLayers hosts, registers WorldgenLib callbacks, and starts the post-process host. - Consumer mods run their own
StartServerSidemethods and register hooks. - The
InitWorldGencallback runs after the vanilla world-generation state is available. - WorldgenLib detects blocking takeovers. On a clean path it binds landforms, initializes the map and terrain hosts, freezes every hook list, and initializes sampling.
- Generation callbacks invoke the hosts. A blocking conflict leaves the native or foreign generation callbacks in control.
-
Disposeunpatches WorldgenLib's Harmony IDs and restores captured vanilla state.
WorldgenLib does not blindly suppress every vanilla callback. It patches only the boundaries needed to avoid duplicate generation:
-
GenMapsduplicate region generation and force forwarding -
GenTerraduplicate terrain generation -
GenTerraPostProcessduplicate cleanup generation -
GenBlockLayersfinal raise/filter injection and terminal pass entry
Vanilla initialization still runs when the clean path needs it. In particular, native GenMaps initialization can populate required-land state before the ocean map layer is constructed. WorldgenLib forwards force requests and preserves that state rather than replacing it with a disconnected copy.
ConflictDetector runs before the WorldgenLib hosts take ownership of generation. It examines the known full-replacement mechanisms, including removed world-generation delegates and Harmony patches. A finding is either advisory or blocking.
When a blocking conflict is present:
- WorldgenLib's own map and terrain callbacks become no-ops.
- Vanilla or the foreign generator remains enabled.
- WorldgenLib prints a startup report instead of creating a second canonical pass.
When the detector cannot inspect a required owner or delegate layout, it fails closed for the affected mechanism. A missing inspection capability is not treated as proof that the pipeline is safe.
The BlockLayers inline seam depends on a structural IL pattern. WorldgenLib checks that pattern before allowing raise or sea-level filter registrations. If the pattern is unavailable, inline registration fails clearly. A complete BlockLayers consumer can still use the terminal adapter if its migration does not depend on the scalar inline seam.
The same principle applies to the other required seams: if the library cannot install the callbacks needed for a safe pass, it disables itself rather than producing partial terrain.
GenTerra processes columns in a parallel loop. Request-local scratch arrays are owned by the terrain request, while each column receives stack-scoped context values. Do not put mutable per-world or per-request data in static fields. ChunkContext.CustomData is synchronized during initialization, but the value stored there remains the consumer's responsibility to partition or synchronize.
GenMaps and post-process state are region or column scoped. Persistent region maps use per-region synchronization and bounded serialization.
WorldgenLib captures and restores the vanilla latitude callback and the GenMaps.upheavelCommonness global it changes. Landforms are rebound when vanilla reloads its landform property before the freeze. A disposed post-process callback checks its registration state, so a stale event delegate becomes a no-op during a hot reload instead of mutating a later world.