Skip to content

Instantly share code, notes, and snippets.

@Floweynt
Created July 13, 2024 05:16
Show Gist options
  • Save Floweynt/8facf927205910271679df641e2a86a7 to your computer and use it in GitHub Desktop.
Save Floweynt/8facf927205910271679df641e2a86a7 to your computer and use it in GitHub Desktop.
Monumenta Mixin/Paper Patches RFC

Monumenta Mixin/Paper Patches RFC

revision changes
1.0 initial specification

The Monumenta paper patches implementation will expose interfaces to plugins that enable the use of features and programming techniques that would otherwise be difficult or ugly with vanilla paper. The API is designed with abstracting away from Minecraft in mind, so version adapters should not be required to use it. The most notable exception is the PlayerData event interface(s) for legacy reasons.

A integrated NBTAPI implementation will be provided, which may or may not provide better performance by avoiding reflection calls. Current implementation simply bundles NBTAPI from upstream, along with some bootstrap code.

Main API

Monumenta paper patches exposes a large part of its API in one interface:

interface MonumentaMixinAPI {
    public static MonumentaMixinAPI getInstance() { /* implementation-defined */ }
    public int getFlyingTickTime();
    public void setFlyingTickTime(int flyingTickTime);

    public int getServerShutdownTime();
    public void setServerShutdownTime(int flyingTickTime);

    public String getIdentifier();

    // Other methods described in different sections
}

Player Data Events

As described previously, this is not properly integrated with NBTAPI, and thus requires version adapters. They are defined in the com.floweytf.monumentapaper.api.event package, and has the same API signature as in the legacy monumenta-paperfork patches.

Enhanced Metadata/Persistent data interface

Plugins often need to associate data with an entity to manage plugin state. This is often achieved with Map<UUID, ?>, which may cause memory leakage if not carefully managed, as well as introducing extra hashmap lookup overhead. In order to support binding arbitrary data (that may or may not persist), entities will have an additional associated object, implemented via injecting a field into various types of entity classes.

Because this code hooks into Minecraft's very cleanly, persistent data (typically done via NBTAPI calls) should be significantly more performance, as it no longer requires serializing and deserializing the entity instance. Instead, data will be saved when the rest of the entity is saved.

This may be extended to more than just Entity, such as various subclasses (notably, Player). Thus, Type is used as placeholder in the following code block.

interface IPluginData<T> {
    public void save(T self, ReadWriteNBT nbt);
    public void load(T self, ReadableNBT nbt);
}

// ...
// In main API interface
public void bindTypePluginDataSupplier(Supplier<IPluginData<Type>> supplier);
public void bindTypePluginData(Type instance, IPluginData<Type> instance);
public IPluginData<Type> getTypePluginData(Type instance);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment