Skip to content

Custom Registry API #12383

@akarahdev

Description

@akarahdev

Is your feature request related to a problem?

A Custom Registry API would allow plugins to share custom data through the use of Custom Registries. Developers would be able to create custom registries via a new RegistryKey.custom method, use it in a RegistryEvent through a RegistryEvents.custom(RegistryKey) method, and access it through RegistryAccess.

While niche, this could help plugins depending on eachother share data between them.

Describe the solution you'd like.

I'm not sure on what the exact semantics should be, what I have here is just a concept, but I would like to propose a new RegistryEvents.custom(RegistryKey) and RegistryKey.custom(NamespacedKey). This would allow you to modify a custom registry introduced by a plugin. If a registry of the name does not already exist, a new one should be transparently created behind the scenes. The custom registries behind the scenes could just be simple HashMap<NamespacedKey, T> where T is the value type of the custom registry.

For an example, let's say a plugin wanted people to allow registering custom items to a Registry<T>. These custom items have a type dedicated to them:

record CustomItem(String name, Material type) {}

A plugin creator could then create a registry for these:

RegistryKey rgk = RegistryKey.custom("plugin:custom_items");
BootstrapContext bctx = /* placeholder */ 0;
bctx.getLifecycleManager().registerEventHandler(RegistryEvents.custom(rgk), ctx -> {
  ctx.registry().register(
    TypedKey.create(rgk, Key.key("plugin:cool_sword")), 
    new CustomItem("cool sword", Material.STONE_SWORD)
  );
});

Then, another plugin could use the same registry later and register something else into the same custom registry.

bctx.getLifecycleManager().registerEventHandler(RegistryEvents.custom(rgk), ctx -> {
  ctx.registry().register(
    TypedKey.create(rgk, Key.key("other_plugin:coolest_sword")), 
    new CustomItem("coolest sword", Material.NETHERITE_SWORD)
  );
});

After that, RegistryAccess could be used to access an entry from the new custom registry:

Registry<CustomItem> registry = RegistryAccess.registryAccess().getRegistry(rgk);
// do stuff with registry...

Describe alternatives you've considered.

An alternative is each plugin that wants this kind of interop can offer their own static Map somewhere that maybe even implements the Registry<T> interface. However, this honestly seems sketchy in my opinion since this means each plugin will have their own way of handling this and there is a lack of standardization.

A plugin could also implement the Registry<T> interface themselves, but now no one can access it using RegistryAccess.

Other

I think something to note is that this feature would likely require a dependency on being a Paper Plugin & Paper Plugins interacting with eachother. I'm not sure how big of a problem this is though.

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions