Skip to content

Support //regen on Folia - #3032

Open
strobil wants to merge 2 commits into
EngineHub:masterfrom
Vanilla-Game:codex/folia-regen-master
Open

strobil wants to merge 2 commits into
EngineHub:masterfrom
Vanilla-Game:codex/folia-regen-master

Conversation

@strobil

@strobil strobil commented Oct 10, 2026 •

Copy link
Copy Markdown

Adds //regen on Folia, including -b, -c, block entities, masks, limits and undo. Plugins can use the new World#regenerateAsync.

The adapter generates the terrain into a snapshot in a temporary world, as the synchronous path does, but waits on chunk futures instead of managedBlock. The selection's chunks are loaded with World#getChunkAtAsync and held with plugin tickets, the snapshot is applied on the region thread owning them, and the command completes on the player's scheduler. Temporary worlds live on the global region thread, one at a time.

Limitations:

  • The selection must end up in one Folia region when the result is applied.
  • One generation at a time; a concurrent //regen is refused with a message.
  • Inventory mode is not supported.
  • Seed overrides are not supported on 26.1 and 26.2, as on Paper.
  • No timeout: a generation that never completes keeps the lock until restart.

Also fixes //regen -b sampling biomes at block instead of quart coordinates on all platforms (separate commit).

Risks:

  • Folia does not support creating or unloading worlds, so the temporary world relies on the same ServerLevel constructor trick as the synchronous path. Its registration in the server's world map is brief but visible to plugins iterating Bukkit.getWorlds() from other threads.
  • Creating and closing the temporary world stalls the global region thread for about a second each; on Paper the synchronous path stalls the main thread for the whole regeneration instead.
  • Freshly loaded chunks are given up to two seconds to merge into one region; a selection spanning regions that merge slower is refused after the terrain was already generated.
  • A generation that never completes leaks the temporary world and blocks further regenerations until restart.
  • Runtime testing covered console-driven regeneration of a small selection on 26.2; player-driven regeneration, large selections and the 1.21.x adapters are compile-verified only.

Tested on Folia 26.2 and Paper 26.2: regen of unloaded chunks far from spawn, undo, redo, -b, -c, two concurrent requests; block counts verified afterwards.

@strobil
strobil requested a review from a team as a code owner October 10, 2026 21:45
@strobil strobil changed the title feat: support //regen within the current Folia region feat: support //regen within the Folia region of pos1 Oct 10, 2026
@strobil
strobil marked this pull request as draft October 10, 2026 23:32
@strobil strobil changed the title feat: support //regen within the Folia region of pos1 Support //regen on Folia Oct 11, 2026
@strobil
strobil marked this pull request as ready for review October 11, 2026 01:00
ChunkAccess#getNoiseBiome takes biome (quart) coordinates, as the
adapter's own getBiome already does. The previous call passed block
coordinates, so biome regeneration read from the wrong place.
Folia cannot wait for chunk generation on a region thread, so the Bukkit
adapter generates the terrain into a detached snapshot in a temporary
world, as the synchronous path does, but waits on chunk futures instead
of managedBlock. The selection's chunks are then loaded with
World#getChunkAtAsync and held with plugin tickets, the snapshot is
applied on the region thread owning them, and the command completes on
the player's scheduler.

Core gains a single World#regenerateAsync default method that falls back
to the synchronous regenerate(); //regen creates its own edit session so
both paths share one completion handler. The adapters implement
regenerateAsync from the existing temporary world setup and copy loop,
driven by a small AsyncRegeneration helper, and load the temporary world
through the Bukkit API rather than chunk system internals. Temporary
worlds live on the global region thread, one at a time.

Limitations: the selection must end up in one region when the result is
applied, concurrent regenerations are refused with a message, inventory
mode is not supported, seed overrides remain unsupported on 26.x, and
there is no timeout.
@strobil
strobil force-pushed the codex/folia-regen-master branch from ea7a529 to 6c53204 Compare October 11, 2026 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant