Evolution of Bukkit/PaperAPI - A wish list

Hey guys,

you might have noticed, that there is a dream, an idea, emerging in the developer community: Splitting up from upstream, a hard fork.

The could simplify the whole workflow, removing patches in some places, moving to nicer mappings, etc. But thats not what I want to talk about today.

Today I want to talk about things in the bukkit/paper api, that didn’t age well and that need refactoring. We can’t expect such refactorings from upstream and we can’t do such refactorings ourselfs without breaking compat with upstream, so the only way we sanely can get such refactorings in, is when we broke away from upstream.

This means, anything posted here isn’t more than a wish or dream. We have no clue if paper can actually break up from upstream or if we can get such refactorings in. Nevertheless I want to start a collections of apis that could use a good ol refactor, so if we see ourself in a situation to attempt that, we have a list of ideas.

Please refrain from posting dum comments like “everything!!!11”. Its a non goal to completely abolish the bukkit api. The goal is to find inconsistencies and address them, and to find areas where bukkit didn’t move with the time (both related to java 8 (hopefully 11 soon?) and the vanilla apis). Its also not a goal to break plugins, just for the heck of it.
Keep it reasonable.



Short version (and elaborated below)

  • Most of the enums - could deprecated the enums and temporarily keep them depending on relevant discussions. Unfortunately changing anything with that requires breaking lots of tools/methods through the whole project… This is a hard topic.
  • Providing early notification of api breakage and documenting how to recode things appropriately. Ideally at the Mojang snapshot stage instead of release stage.
  • Abstracting various event to be less implementation specific.
  • Inventory events. Client actions vs. Server actions. And altering the results of these separate but intertwined things.
  • Looking to fill API holes currently accomplished with nms but hard to add API while we have an upstream.

The most common complaint about the Bukkit API I notice is the enums in the API, specifically the Material api - but it applies elsewhere. I don’t want to speculate on what the proper replacement would look like. But I would want that replacement to make it really easy to make the transition so it isn’t a discouragement to do the upgrade (just look at the people that chose not to go past 1.12 because of the work required; disregarding the performance issues). By easy, I mean that you can use find/replace tools to do most of the work with minor human review to go from current API to the refactored.

A large issue I see on that subject… Is that vanilla is moving towards supporting custom data pack and resource packa into vanilla Minecraft (custom blocks/items/entities/etc). The Bukkit project has always been intentional about not providing special support to the modding community. But with certain aspects of modding coming to vanilla, I don’t see the current API adapting. It is my opinion, that if it can be done with the vanilla client, it should be supported by this project.

Additionally, policy-wise. Would want to have a Deprecation policy with the API, not to encourage us to constantly refactor things - like Sponge tends to do (significantly harder to maintain). But develop a consistent place to communicate what will be changing ahead of time, so that things like CraftEvil don’t have to exist. When there is an API break, make it easy for people to update their code even if they miss out on the new mechanics.
To further clarify. It is less about the ability to deprecate and remove things. Spigot already has that ability. The bigger picture is communicating how to transition X API to Y API in a timely fashion. Not at the time of Mojang’s final release. This cross-version documentation would make it more clear how to implement multi-version plugins since not every individual is doing the research.

The spark for this forum thread was that paper has been adding multiple PrepareFooEvent events and that could all be extended from a common event. This could probably be applied to other events as well. I personally do not tend to think about the flaws since my mindset is just working within the box.

In terms of forward-compatibility and events. I think it would be good to consider any event which has a specific entity’s name in it - to be abstract. Even if Mojang’s code doesn’t abstract it yet.
Example. For 1.15 I wrote a BeeAngerEvent for our fork. 1.16 has caused me to abstract that to an EntityAngerEvent because mojang internally abstracted it to include piglins, wolves, etc and it was easier for me to implement. For things like that, it would have been possible to deprecate the BeeAngerEvent and extend it from the EntityAngerEvent. But could have been avoided from the start if I had considered the abstract case.
Long story short. Individual entity names in events could lead to abstraction issues later on. Would be an easy API improvement even if there is only a single use of it now.

Another common api complaint is the inventory events (with regards to interaction and api accessibility). I don’t know the solution to that. As technically the current api allows most things to be possible in a horribly awkward way. In my words. It is just a wrapper for clients action. An entire thread could probably be dedicated to handling that topic alone. An extra event which fired to describe the resulting inventory action is what would be nice. The problem being the plugins are sorta designed around that not happening and makes assumptions about how to hack in what they want.

Finally. I think possibly the best thing API goals could be to look at the various plugins and look what people are reflecting into nms for. Where is the need in terms of API expansion? (somewhat off-topic to API refactoring)

  1. Location should be immutable and should not include a reference to “World”, just a simple tuple of doubles (x,y,z).
  2. Use a separate BlockPos type for when Location must be integers
  3. Cleaner ItemMeta API, including a clear distinction mutable views , unmodifiable views and immutable snapshots (think kotlin ‘List’ vs ‘MutableList’ interfaces in kotlin) with Immutable list copies
  4. Allow taking immutable snapshots of entity state, in addition to the existing mutable views
  5. BlockState API to complement ItemMeta API - Transparently handle the
  6. Deprecate/remove Material enum - Replace with new ItemMeta and BlockState APIs
  7. Clearer story on concurrency - Try and support it where possible and throw a hard error everywhere else
  8. Include Aikar’s command dispatch framework as the default

In general I would say that Java needs better support for serialization. Rust has elegant, zero-cost serialization via https://serde.rs/ The entire ecosystem supports it Transparently and it’s agnostic of the underlying serialization format. I’d like something like that for Java (which we would then use in Bukkit).


In addition to the blockstate and itemmeta API I would like to see a walk away from the inheritance. Instead define typed keys. HasCompomponent Directional. blockstate.set(Component.DIRECTIONAL, Direction.WEST);
So a little bit going into the direction of sponge but with a more stable API.

A large amount of inspiration could be drawn from Sponge.

Wait can I not say that?
Never mind…

Wish there was more client-server trading, since there are many ways to do that which could completely remove blacklisted mods from specific servers running this server jar. But that would be incredibly hard, as most servers with rules against modifications know that those modifications try and stay hiddin.

We can only modify the server, not the client

Cool would be something like that but that needs either work on Mojangs side or a client mod written/maintained for Forge/Fabric.

What I meant was more client-server trading, showing the server your mods. And if mods were blacklisted, you wouldn’t be able to join with them.

Does the client send its modlist to the server?

As I know only forge. Every hack client does send nothing.

Sadly true, I meant something like an item scroller or an inventory tweaker.

I would love to see teams api being separated from the scoreboard api since in vanilla those were separated a long time ago (I think in 1.13?) and I want to send tablist prefixes and suffixes to clients whithout having to allocate a scoreboard for every player.

Introduce the new brigadier system (1.13+) and so rewrite the Command API.

My primary wishlist item for WorldEdit would be the introduction of key-based properties for block states.

Eg, being able to look up what properties can be applied to a block. When you’ve got a property, being able to get the property key, and allowed values. And then being able to set properties with values etc.

For my CraftBook wishlist (that’ll grow tremendously when I get a chance)

Consistency amongst events. Some events, such as the Dispenser event, now fire after the item has been removed from the dispenser. Realistically this should happen beforehand, or at least provide a snapshot of the state beforehand and allow cancelling to cancel the item being removed.