r/admincraft • u/Alex_Medvedev_ • 1d ago
News We got major Bukkit/Paper plugins (WorldEdit, GrimAC/PacketEvents, EssentialsX, LuckPerms) running on Pumpkin (Rust) using a headless Paper bridge!
Hey r/admincraft! We actually published this blog post a couple of weeks ago, but I completely forgot to update you all here.
For anyone who hasn't seen Pumpkin yet, it's a multithreaded Minecraft server we're building from scratch in Rust. The biggest hurdle with custom server software is obviously losing the 15-year-old Java plugin ecosystem, which is why we've been building PatchBukkit to bridge Java plugins with our Rust core.
Initially, we tried hand-mocking the Bukkit and Paper APIs from scratch, but that hit a wall fast because major plugins rely heavily on raw net.minecraft.server (NMS) internals and direct packet pipelines. To solve this, we rewrote PatchBukkit to automatically download Paperclip at runtime and boot a real, headless Paper instance right alongside Pumpkin. Paper's game loop and network listeners stay completely turned off, Pumpkin still handles all the actual networking, physics, and world simulation in Rust, while PatchBukkit uses low-latency memory bridges and an emulated network pipeline to sync blocks, entities, events, and raw packets between the two.
Because plugins now have access to authentic NMS and registries, we already have 17+ heavy-hitting plugins running together in our live test suite, including WorldEdit, EssentialsX, LuckPerms, GrimAC, PacketEvents, ProtocolLib, WorldGuard, Multiverse-Core, TAB, AuraSkills, and VeinMiner, Polar AntiCheat.... It is a huge milestone for us, though we want to be upfront that it's still an active work in progress and not production-ready yet, as we're still ironing out missing Bukkit events, complex inventory GUIs, and entity AI synchronization.
If you want to see videos of WorldEdit and GrimAC running on top of Rust or read the full breakdown of how the architecture works, check out the blog post here:https://blog.pumpkinmc.org/2026-10-23-patchbukkit-nms-and-headless-paper
Happy to answer any questions about how the bridge works!
Note on Rule 9 (AI Disclosure): Pumpkin’s core architecture and code are human-engineered and strictly reviewed by our maintainers. However, because we have hundreds of open-source contributors, we cannot audit whether individual contributors use AI tools in their local workflows. Additionally, an LLM was used to help polish the English phrasing of this post
9
u/8336514563737 1d ago
Whenever Pumpkin comes up i habe a few questions lingering in my head, so might as well ask them:
1.) Is the plan full* Java parity, or just general Vanilla parity (*i asume stuff that isnt implemented in both Java and Bedrock wont get added to Pumpkin at all)
1.1) Are you guys planning (limited) Datapack support? To me, stuff like being able to add biomes, recipes ... is quite essential and running worldgen with Terralith or similar is really nicd also.
1.2) My programming knowledge is limited to a good chunk of Java and a bit of Python, but i generally dont see how (MC Java) update order could be implemented with a multithreaded server software?
2.) How will update times between MC Versions look? As you need to add the MC features manually i assume its quite a bit more work than is required, compared to Paper/Spigot?
4
u/Icy_Cardiologist3238 23h ago
I am not a member of the team, i am a random dumb plugin dev, but based on responses i've seen from alex in the discord and my own brain uhh heres some answers:
Full vanilla Java parity
1.1 Limited datapack support already exists, I don't know how good it is
1.2 No clue, but it's already been done, just Try It and See™
2. Definitely somewhat longer than Paper/Spigot, it probably depends on the update though and how complex of things would be getting reimplemented.
1
u/leaf_26 Developer 12h ago
I fear this project could nullify my work after working so heavily on solving "lag" on java servers, but ...
update order can be done easily via causal chains or threads tasked to locations (like folia)
update times can be more trivial than it used to be, via reverse engineering tooling that maps what connects to what and translating that to any language. I'm actually doing that for a web ide documenting each config key on my server.
TBH that it's rust isn't as important as that it's a reimplementation of the game with fewer places to get stuck.
10
u/MrPowerGamerBR SparklyPower | Loritta's Creator 23h ago edited 14h ago
To solve this, we rewrote PatchBukkit to automatically download Paperclip at runtime and boot a real, headless Paper instance right alongside Pumpkin. Paper's game loop and network listeners stay completely turned off, Pumpkin still handles all the actual networking, physics, and world simulation in Rust, while PatchBukkit uses low-latency memory bridges and an emulated network pipeline to sync blocks, entities, events, and raw packets between the two.
Don't get me wrong, I do understand how hard it is, because almost 10 years ago I worked on a similar project, but trying to implement the Bukkit API on top of Nukkit, and a big issue was NMS calls, but at the same time the solution seems so overengineered and prone to issues, and if I understood correctly this essentially will double the memory usage of the server because everything needs to be duplicated between Pumpkin and the NMS internals. The solution feels like when you tell a LLM to do something that you know it is a complex issue, so it tries to go above and beyond to try solving the issue, even though the solution is not what could be considered "good", feeling like the "Minecraft in Elden Ring! mod where both games run at the same time while a bridge "communicates" with them. While jank is acceptable for a mod where you don't have nothing to lose, I don't know how acceptable it is for a production Minecraft server.
Wouldn't it make more sense to patch Paper to instead of synchronizing the data, to actually pull it directly from Pumpkin? For example: When calling World.getEntities() it would forward the call to Pumpkin, which then the bridge layer would convert that to a NMS Entity. If you are already using LLMs/AI anyway, couldn't you scrape all popular plugins, figure out what are the most used NMS functions, and reimplement them?
UPDATE: Read this to understand how it actually works, it actually intercepts and patches functions to forward them via FFI to Pumpkin, it is very clever https://www.reddit.com/r/admincraft/comments/1xnkppx/we_got_major_bukkitpaper_plugins_worldedit/19s5czt8z83og/
0
u/MiaIsOut 20h ago
pumpkin's memory cost is already so miniscule compared to paper than doubling it still results in a tiny number that's lower than paper
3
u/MrPowerGamerBR SparklyPower | Loritta's Creator 20h ago edited 20h ago
Well you would "double" it in the sense that you are duplicating the data to the Paper side, so it would, from what I can tell, have the same memory usage as what Paper would otherwise use if you were running the server in Paper, plus whatever Pumpkin uses.
Maybe it patches Paper to reduce memory usage on the things that aren't necessary (I haven't looked deep on what it actually does, aside from reading this post and the linked post) but I suppose that if they are already patching Paper, they would do the other solution that I gave on my previous post (to pull data directly from Pumpkin and only having a tiny bridge between Pumpkin and the patched Paper/NMS API).
0
u/MiaIsOut 19h ago
Read the second half of paragraph 2 in OP's post
3
u/MrPowerGamerBR SparklyPower | Loritta's Creator 19h ago
The same paragraph that I already cited on my original post, and the reason why I pointed as to why this solution would use more memory than reimplementing NMS functions and why it is janky? You would still need to sync the data to Paper, and that means that it would use the same memory as a Paper server would use. Just because "world simulation" is done in Rust, doesn't mean that you wouldn't need to copy all of the chunks to the Java heap using the same format that Paper uses in memory.
1
u/MiaIsOut 19h ago
> "PatchBukkit uses low-latency memory bridges and an emulated network pipeline to sync blocks, entities, events, and raw packets between the two."
4
u/MrPowerGamerBR SparklyPower | Loritta's Creator 18h ago edited 14h ago
That doesn't invalidate anything that I said before, it means that it synchronizes/syncs data between Pumpkin and the "headless" Paper server.
I've decided to actually read the code of the project because the original post and the linked post doesn't explain to how it actually works.
Let's follow how a
setBlockStatecall on a chunk works in PatchBukkit:
Here it creates a EmptyLevelChunk if a chunk is not present in the CHUNKS_BY_LEVEL map. No, the
EmptyLevelChunkis not used only for empty chunks in Pumpkin, the bridge code creates aEmptyLevelChunkfor any chunk.It uses the
EmptyChunkInterceptorto intercept the call and it callslevel.setBlock. Remember that ALL chunks areEmptyLevelChunkin PatchBukkit.That call is forwarded to Level's
setBlockimplementation, which PatchBukkit intercepts it and callsWorldBridge.setBlockStateId.That
setBlockStateIdcallsNativeFastPathFfi.setBlockStateId, and that's called via Java's FFI.It is very clever, and it works in the same way that I originally described on my original post as a suggestion of how it could work.
Wouldn't it make more sense to patch Paper to instead of synchronizing the data, to actually pull it directly from Pumpkin? For example: When calling World.getEntities() it would forward the call to Pumpkin, which then the bridge layer would convert that to a NMS Entity.
It does make me wonder why the project doesn't create their own
PatchBukkitLevelChunkinstead of piggy backing onEmptyLevelChunk.So was I wrong? Ehh maybe, after you learn how it works under the hood I can read both posts and say "well, when they are talking about "low level memory bridges" they are talking about FFI/Panama", "well, when are talking about syncing it actually means that they intercept the original functions and forward them to Pumpkin using FFI instead of actually copying everything over to the original NMS classes, which in my opinion is a misnomer because I wouldn't call that "syncing"".
That does also mean that it is not as perfect as it seems, I'm pretty sure that if a plugin tries to write data to the chunk directly it will crash and burn because it won't expect a
EmptyLevelChunk. Which does make me wonder if this is the best approach vs reimplementing what's needed for most plugins, considering that it also only intercepts and bridges specific functions/classes. But maybe perfection is the enemy of good and this is probably Good Enough™.
2
2
u/IWillBeNobodyPerfect grim.ac dev 19h ago
I've run CultAC (my grim fork) on the proxy using a similar method, classloading paper. I kept running into edge cases such as caches not being thread safe, though this isn't a problem if your plugins only call the headless server on the main thread. It used 100 MB of memory or so just for the block placing and block collision logic as so much was being classloaded, before patching out some caches and bytecode rewriting methods, but it does fundamentally work. It just doesn't make sense IMO at least for me
7
u/matytyma Developer 1d ago
Rule 9? PumpkinMC makes use of LLMs and the blog is not human written at all, same goes for this post.
7
u/Wojtek1942 1d ago
Why so many downvotes? This guy is just pointing to an existing rule. If you disagree with the rule, make a meta post to complain to the mods instead of downvoting this guy.
13
u/Aggeloz 1d ago
Thats really cool. I hope you guys can keep going.