-
-
Notifications
You must be signed in to change notification settings - Fork 0
Diagnostics and Troubleshooting
WorldgenLib reports the assembled hooks and step list so a server owner can check the active pipeline before generating a large world.
After the server has initialized WorldgenLib, print the hook report from a consumer or a diagnostic command:
foreach (var entry in WorldgenLibAPI.GetHookReport())
{
api.Logger.Notification(
"WorldgenLib hook {0} at {1} owned by {2}",
entry.Step,
entry.Order,
entry.ModId);
}
api.Logger.Notification(
WorldgenLibAPI.GetStepRegistry().GetVersionReport());The report is useful for checking that a consumer registered before the freeze, that its order is the intended value, and that a terminal adapter is not registered alongside an equivalent atomic effect.
| Symptom | Likely cause | Action |
|---|---|---|
IsLoaded is false
|
WorldgenLib is missing, client-side, or not initialized | Declare the server dependency and register from StartServerSide
|
WorldgenLib is not initialized |
Registration or sampling happened too early | Wait for StartServerSide or worldgen initialization as documented |
Cannot register ... after initWorldGen |
A hook, landform, or map slot was registered late | Move registration to startup |
| BlockLayers inline seam unavailable | The Vintage Story IL shape is unsupported | Use the terminal adapter if appropriate, or wait for a compatible build |
GetIndex returns -1
|
The code is absent or not yet imported | Check the canonical code and registration timing |
| Duplicate landform or map code | Two consumers claimed the same identifier | Namespace the code or coordinate ownership |
| Region map budget exceeded | Declared storage exceeds the 4 MiB per-region budget | Reduce dimensions, padding, or the number of slots |
| Hook disappears after an exception | WorldgenLib disabled that mod ID in the affected list | Fix the exception or non-finite result and restart the worldgen session |
| WorldgenLib hooks are present but inactive | A blocking foreign takeover was detected | Read the conflict entry and remove the duplicate owner or choose a policy |
| Sampler throws before worldgen |
TerrainSampler is not initialized yet |
Query only after the worldgen host has initialized |
SetFluid writes at the wrong height |
Local Y was used instead of global Y | Pass global Y and let ColumnCarvingContext choose the vertical chunk |
| Saved custom map is empty | The coordinate-only compatibility overload was used | Use GetMap(IMapRegion, ...) and SetMap(IMapRegion, ...)
|
Numeric hooks must return finite values. A non-finite raise or threshold result disables the owning mod's registrations in that list. A thrown exception has the same isolation boundary. The remaining hooks continue, but the server log is the evidence that the consumer is no longer active.
Do not catch and hide exceptions inside a consumer hook. Log the input coordinates, step, and consumer state, then allow WorldgenLib to apply its isolation policy.
Check the pipeline in this order:
- Confirm the server loaded exactly one canonical terrain and map owner.
- Print
GetHookReport()and compare every step and order with the consumer's intended policy. - Check for disabled registrations and the first warning in the server log.
- Verify map mutations occur at the correct map stage and call
TerrainSampler.InvalidateRegionafter changing sampled landform data. - Verify per-column hooks do not share mutable state without synchronization.
- Reproduce with a fixed seed and a no-consumer world.
- Test negative coordinates and terrain that crosses multiple vertical chunks.
If the output depends on which chunk generated first, the consumer probably relies on callback arrival order or writes shared state from a parallel column hook. Move that work to a region or finalization boundary.