Skip to main content

Creating a v7 registry pack

This example targets NotQuests 7.0.0, Minecraft 26.3, Java 25, and Paper. The objective and variable themselves use the portable API and can also live in a shared module for NeoForge.

Start with the dependency and plugin.yml setup from API usage.

1. Create the registry pack​

A pack keeps all of your registrations in one obvious place:

package com.example.notquestsaddon;

import com.notquests.core.platform.NotQuestsAdapter;
import com.notquests.core.registry.NotQuestsRegistry.Pack;
import com.notquests.paper.NotQuests;

public final class MyRegistryPack implements Pack<NotQuests> {
@Override
public void register(final NotQuests notQuests) {
final NotQuestsAdapter adapter = notQuests.getRegistryAdapter();
CustomJumpObjective.register(adapter);
CustomFoodLevelVariable.register(adapter);
}
}

Register it from your add-on's onLoad():

package com.example.notquestsaddon;

import com.notquests.Main;
import org.bukkit.plugin.java.JavaPlugin;

public final class MyAddon extends JavaPlugin {
@Override
public void onLoad() {
Main.getInstance().getNotQuests().addRegistryPack(new MyRegistryPack());
}
}

2. Add an objective​

This objective exposes one amount argument. Every registered field becomes part of command parsing, suggestions, YAML loading, and generated command documentation.

package com.example.notquestsaddon;

import com.notquests.core.platform.NotQuestsAdapter;

public final class CustomJumpObjective {
private CustomJumpObjective() {}

public static void register(final NotQuestsAdapter adapter) {
adapter.objectives().objective("CustomJump")
.displayName("Custom Jump")
.description("Counts player jumps for this add-on.")
.field(
"amount",
adapter.fields().numberExpression().progressNeeded(),
"Number of jumps required.")
.taskDescription((objective, player, activeObjective) ->
"Jump " + (activeObjective != null
? activeObjective.progressNeeded()
: objective.text("amount")) + " times.")
.onPlayerJump(activeObjective -> activeObjective.addProgress(1))
.register();
}
}

After startup, create it like every built-in objective:

/qa edit ExampleQuest objectives add CustomJump 20

There is no Paper event listener in this class. NotQuests translates the platform jump event and calls the portable onPlayerJump callback.

3. Add a number variable​

Variables can provide a value for conditions and, when a setter is registered, generate matching actions that change the value.

package com.example.notquestsaddon;

import com.notquests.core.platform.NotQuestsAdapter;

public final class CustomFoodLevelVariable {
private CustomFoodLevelVariable() {}

public static void register(final NotQuestsAdapter adapter) {
adapter.variables().numberVariable("AddonFoodLevel")
.displayName("Add-on Food Level")
.description("Reads or changes a player's hunger value from 0 to 20.")
.singular("Food level")
.plural("Food levels")
.get((player, objects) -> player == null ? 0 : player.foodLevel())
.set((newValue, player, objects) -> player != null
&& player.setFoodLevel(Math.max(0, Math.min(20, newValue.intValue()))))
.register();
}
}

The generated condition can read the value, and the generated action can set, add, remove, multiply, or divide it using NotQuests' normal variable commands.

4. Test the registration​

Start the server and check the console for registry errors. Then use tab completion under:

/qa edit ExampleQuest objectives add CustomJump
/qa variables check AddonFoodLevel

Use a unique identifier for every registered type. Registering a duplicate identifier replaces the existing type, which is useful for deliberate overrides but surprising when accidental.

For more examples, see the built-in registrations in the NotQuests source under src/builtin/src/main/java/com/notquests/builtin/.