Serverside component for Axiom, with Folia support.
This is a maintained fork of Moulberry/AxiomPaperPlugin built on top of Paper's modern scheduler API. The result runs on both Paper and Folia from the same jar.
- Default branch:
folia(Folia-supported build) master: unmodified upstream mirror, kept purely as the rebase base- Upstream changelog: https://github.com/Moulberry/AxiomPaperPlugin
On Folia there is no "main thread": every region (and the world's global region)
ticks on its own thread, and the classic Bukkit scheduler (BukkitRunnable,
scheduleSyncRepeatingTask, server.execute(...)) does not exist / throws.
The fork replaces all of that with the Paper Scheduler API
(GlobalRegionScheduler / RegionScheduler / EntityScheduler), which behaves
identically on Paper and Folia:
- The plugin tick now runs on the
GlobalRegionSchedulerfixed-rate task. - World work (chunk resend/relight, block buffers, biome writes, marker sync) is scheduled per region, so a task only ever touches chunks it owns.
- Entity operations (spawn / manipulate / delete / request data / marker NBT) hop to the entity's own region.
- Blueprint uploads write files on the async scheduler and update the registry on the global region thread.
- Many permission checks moved to UUID-based lookups so they work without a Bukkit entity reference on another region's thread.
Scheduling helpers live in com.moulberry.axiom.Environment
(runGlobal, runGlobalFixedRate, runOnRegion, runOnEntityRegion).
Folia is detected at runtime via io.papermc.paper.threadedregions.RegionizedData.
tick_blocksand direct reads of far, already-loaded chunks outside the player's region can still cross regions and be rejected by Folia (rare).- Marker gizmo sync (
send-markers) reads marker data per-entity; seeWorldExtension.scheduleMarkerTick.
Release builds (default branch): Releases tab on the right, or the link below.
The released jar is a fully shaded (shadow) jar — just drop it into plugins/.
https://github.com/LapisWorks/AxiomPaperPlugin-Folia/releases
Requires a JDK 25 toolchain and Gradle 9.x (wrapper included).
./gradlew shadowJar
# jar output: build/libs/AxiomPaper-all.jarLocal-only machine paths (e.g. org.gradle.java.home=...) belong in a
gitignored gradle.properties — do not commit them.
This fork uses a rebase-based workflow so it can track upstream with minimal conflict surface. Every Folia change is split into small, focused commits (patches); upstream updates are replayed underneath them.
upstream/master (Moulberry) ← pure upstream, fetch-only
└─ folia (default) ← = upstream + Folia patches
Never merge upstream into folia — always rebase.
git fetch upstream # get the latest Moulberry commits
git checkout folia
git rebase upstream/master # replay every Folia commit on top of the new codeIf a commit fails to apply, git stops on it:
# fix conflicts in the reported files
git add <files>
git rebase --continueThen push the rewritten branch (rebase rewrites commit hashes):
git push --force-with-lease origin folia--force-with-lease refuses the push if somebody else updated origin/folia,
protecting you from overwriting others' work.
- Keep
masterclean — never commit fork-specific changes to it. - Keep Folia changes in small, logical commits so future rebases stay one-file, one-commit conflicts.
- Prefer the
Environmenthelpers over raw scheduler calls so changes stay in one compatibility layer and are easy to rebase.
Axiom works in singleplayer but not when I connect to a multiplayer server running the Axiom Paper Plugin. What gives?
First, the player must be an op on the server. If the player does not have op
permissions, run /op <playername>. This player must then disconnect from the
server and reconnect.
If you're using an alternative solution for permission management, you must give
players the axiom.default permission.
If players continue to have issues, they can run the /whynoaxiom command for
more information.
All credit for Axiom and the paper plugin goes to Moulberry. See the upstream repository for the original documentation and config reference.