Hi, I’m writing a worldgen mod that places a lot of schematics (shafts/caves/etc.) per chunk. I’ve run into a hard performance/architecture limit and I’m not sure what’s the “canonical” way to solve it.
Current setup (simplified):
I generate data for columns asynchronously in a separate service (via gRPC).
On the server side I queue results and apply them either:
during OnChunkColumnGen (for fresh chunks), or
in OnServerTick (for late/retry cases).
For placement I’m using BlockSchematicStructure.Place with a BulkBlockAccessor and committing once per tick for a batch of chunks.
The issue:
When I try to place many schematics (multiple layers per chunk, many chunks in a radius), the server essentially hits a single-thread bottleneck.
Even with BulkBlockAccessor and batching, mass placement of complex schematics (many blocks, some with BlockEntities/liquids) causes long stalls and very slow “catching up” of world changes.
Functionally everything works (given enough time, all schematics appear and states are correct), but the rate of applying them is too low for a smooth experience.
What I’m looking for:
Recommended pattern or API usage to perform large-scale, non-blocking schematic placement:
Is there an official/idiomatic way to schedule bulk Place operations over multiple ticks so they don’t stall the main thread?
Should I split schematics into “lightweight” (structure) and “heavy” (BlockEntity/liquid) parts and place them in different passes?
Is there a better way to use BulkBlockAccessor / caching accessors for this scenario?
Are there engine hooks or patterns to offload part of the work (lighting/liquid updates) without manually throttling everything myself?
I’m not asking for full code, just guidance on the best practice inside Vintage Story’s engine constraints: how would you implement high-volume, background-ish schematic insertion so that it:
doesn’t block chunk generation,
doesn’t freeze the server,
but eventually applies all structures reliably?
Any pointers to existing mods, docs, or patterns that solve this would be very helpful.
Hi, I’m writing a worldgen mod that places a lot of schematics (shafts/caves/etc.) per chunk. I’ve run into a hard performance/architecture limit and I’m not sure what’s the “canonical” way to solve it.
Current setup (simplified):
I generate data for columns asynchronously in a separate service (via gRPC).
On the server side I queue results and apply them either:
during OnChunkColumnGen (for fresh chunks), or
in OnServerTick (for late/retry cases).
For placement I’m using BlockSchematicStructure.Place with a BulkBlockAccessor and committing once per tick for a batch of chunks.
The issue:
When I try to place many schematics (multiple layers per chunk, many chunks in a radius), the server essentially hits a single-thread bottleneck.
Even with BulkBlockAccessor and batching, mass placement of complex schematics (many blocks, some with BlockEntities/liquids) causes long stalls and very slow “catching up” of world changes.
Functionally everything works (given enough time, all schematics appear and states are correct), but the rate of applying them is too low for a smooth experience.
What I’m looking for:
Recommended pattern or API usage to perform large-scale, non-blocking schematic placement:
Is there an official/idiomatic way to schedule bulk Place operations over multiple ticks so they don’t stall the main thread?
Should I split schematics into “lightweight” (structure) and “heavy” (BlockEntity/liquid) parts and place them in different passes?
Is there a better way to use BulkBlockAccessor / caching accessors for this scenario?
Are there engine hooks or patterns to offload part of the work (lighting/liquid updates) without manually throttling everything myself?
I’m not asking for full code, just guidance on the best practice inside Vintage Story’s engine constraints: how would you implement high-volume, background-ish schematic insertion so that it:
doesn’t block chunk generation,
doesn’t freeze the server,
but eventually applies all structures reliably?
Any pointers to existing mods, docs, or patterns that solve this would be very helpful.