-
-
Notifications
You must be signed in to change notification settings - Fork 0
Map Hooks
GenMapsHost generates one map region through the nine vanilla map stages. Each stage has a region hook, and the factory chain has a separate wrapper hook for consumers that need to wrap or replace a map generator before regions are generated.
| Stage | Registration | Output |
|---|---|---|
| 1 | RegisterMapsGeoprovince |
Geologic province map |
| 2 | RegisterMapsClimate |
Climate map |
| 3 | RegisterMapsForest |
Forest map |
| 4 | RegisterMapsUpheavel |
Upheaval map |
| 5 | RegisterMapsOcean |
Ocean map |
| 6 | RegisterMapsBeach |
Beach map |
| 7 | RegisterMapsShrub |
Shrub map |
| 8 | RegisterMapsBiome |
Biome map |
| 9 | RegisterMapsLandform |
Landform map |
Each stage receives a RegionContext. CurrentMap points at the map produced by that stage. A hook may edit the map in place or replace CurrentMap with another compatible IntDataMap2D. After the hook chain finishes, the host assigns the current map back to the corresponding region property.
private static void SmoothOcean(RegionContext context)
{
IntDataMap2D map = context.CurrentMap
?? throw new InvalidOperationException("Ocean map is unavailable.");
// Edit map.Data or replace context.CurrentMap with a compatible map.
SmoothInPlace(map);
}
WorldgenLibAPI.RegisterMapsOcean(
"my-mod",
OrderBands.BeforeVanillaMax,
SmoothOcean);The stage hooks run after the host invokes the assembled map generator for that stage. Use a generator wrapper when the transformation must happen around the map layer itself.
The context exposes:
-
RegionX,RegionZ, andMapRegion ServerApi-
ChunkGenParams, when provided by the world-generation request CurrentMap- the eight map noise sizes used by the active world configuration
-
GetMap(RegionMapSlot)for a persistent custom map -
GetMapGenerator(MapGeneratorStep)after initialization -
ForceLandformAt,ForceClimateAt, andRequireLandAt
Map hooks are region scoped. They must not assume that a different region is being generated at the same time or that a particular order of region requests exists.
RegisterMapGenerator wraps one of the nine MapGeneratorStep factory results:
WorldgenLibAPI.RegisterMapGenerator(
MapGeneratorStep.Ocean,
"my-mod",
OrderBands.BeforeVanillaMax,
(context, current) => new MyOceanLayer(current));MapGeneratorContext contains the stage, seed, server API, map scale, landcover, ocean scale, landform scale, spawn-offset requirement, required-land coordinates, and climate noise when one is available.
The wrapper must return a non-null MapLayerBase. If it returns null or throws, WorldgenLib disables that registration and leaves the current generator chain intact.
RegisterMapPadding replaces a local padding value for a map stage without requiring a transpiler:
WorldgenLibAPI.RegisterMapPadding(
"my-mod",
OrderBands.BeforeVanillaMax,
(step, vanillaPadding) =>
step == MapGeneratorStep.Upheavel ? 5 : vanillaPadding);The returned padding must be non-negative. A negative value or an exception disables the registration.
RegisterMapsRegionFinalize runs after all nine maps have been generated and their map hooks have completed, before the map region is marked dirty for saving. Use it to derive custom region data from the finalized vanilla maps or to update a RegionMapSlot.
WorldgenLibAPI.RegisterMapsRegionFinalize(
"my-mod",
OrderBands.AfterVanillaMin + 20,
context =>
{
RegionMapSlot slot = RegionMapRegistry.GetSlot("my-mod:streammap")
?? throw new InvalidOperationException("Slot was not registered.");
IntDataMap2D streamMap = context.GetMap(slot);
BuildStreamMap(context, streamMap);
});WorldgenLib flushes registered real region maps through their persistent moddata format when the region pass completes.
The public force methods mirror the mechanisms used by vanilla map generation:
WorldgenLibAPI.ForceLandformAt(forceLandform);
WorldgenLibAPI.ForceClimateAt(forceClimate);
WorldgenLibAPI.RequireLandAt(mapX, mapZ);
WorldgenLibAPI.ForceRandomLandArea(positionX, positionZ, radius);Calls made before the map host has initialized its map scales are queued and replayed at the safe point. This includes required-land data needed by the ocean generator constructor. The force objects use Vintage Story's own types and landform codes.
WorldgenLibAPI.RegisterFullMapRegionGeneration(
"my-mod",
OrderBands.FinalOverrideMin,
context =>
{
GenerateCompleteRegion(context);
return true;
});Return true only when the consumer generated the complete region. Return false to allow another terminal adapter and then the normal nine-stage pass. A full-region adapter is appropriate for a genuinely non-decomposable algorithm, such as an incremental migration bridge.