-
Notifications
You must be signed in to change notification settings - Fork 0
Implementation Guide
DarkBladeDev edited this page Dec 27, 2025
·
1 revision
- Create a Java project (Gradle recommended).
- Copy the
MultiBlockEngineJAR into your addon project (for examplelibs/MultiBlockEngine.jar). - Compile with Java 21.
Minimal build.gradle example:
plugins {
id 'java'
}
repositories {
mavenCentral()
maven { url = 'https://repo.papermc.io/repository/maven-public/' }
}
dependencies {
compileOnly "io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT"
compileOnly files('libs/MultiBlockEngine.jar')
}
java {
toolchain { languageVersion = JavaLanguageVersion.of(21) }
}It must be located at src/main/resources/addon.properties and packaged inside the JAR:
id=energy
version=1.0.0
main=com.tuorg.energy.EnergyAddon
api=1
depends=-
id: unique ID. -
main: class implementingMultiblockAddon. -
api: must matchMultiBlockEngine.getApiVersion(). -
depends: optional, comma/space-separated list (machines,networks).
Contract: MultiblockAddon.java
Example (with commented code):
package com.tuorg.energy;
import com.darkbladedev.engine.api.addon.AddonContext;
import com.darkbladedev.engine.api.addon.AddonException;
import com.darkbladedev.engine.api.addon.MultiblockAddon;
public final class EnergyAddon implements MultiblockAddon {
private AddonContext context;
@Override
public String getId() {
return "energy";
}
@Override
public String getVersion() {
return "1.0.0";
}
@Override
public void onLoad(AddonContext ctx) throws AddonException {
// Called during the engine LOAD phase.
// Ideal for registering actions/conditions/matchers and preparing code-defined multiblocks.
this.context = ctx;
if (ctx.getApiVersion() != 1) {
throw new AddonException(getId(), "Incompatible API", true, AddonException.Phase.LOAD, "apiVersion");
}
// Register a namespaced action
ctx.registerAction("energy:energy_transfer", map -> new EnergyTransferAction(map));
// Register a namespaced condition
ctx.registerCondition("energy:energy_greater_than", map -> new EnergyGreaterThanCondition(map));
// Matchers: prefix must be EXACTLY the addonId
ctx.registerMatcher("energy", token -> new EnergyWireMatcher(token));
}
@Override
public void onEnable() throws AddonException {
// Called after the engine loaded YAML and restored instances.
// Recommended: register listeners and/or define multiblocks by code.
context.registerListener(new EnergyListener());
// Create and register a code-defined multiblock
var type = context
.createMultiblock("cell") // creates energy:cell
.version("1.0")
.controller(new EnergyControllerMatcher())
.pattern(new org.bukkit.util.Vector(0, 1, 0), new EnergyCasingMatcher())
.variable("energy", 0)
.build();
context.registerMultiblock(type);
}
@Override
public void onDisable() {
// Addon cleanup.
// If you started your own async tasks, cancel them here.
}
}The addon should only use AddonContext:
- actions/conditions/matchers registration
- multiblock creation and registration
- controlled scheduler (
runTask,runTaskAsync) - prefixed logger
Do not access engine internals directly.
addon.properties supports depends.
- If an addon depends on another one, the engine will try to enable it afterward.
- If a dependency is missing or failed, your addon will be marked as FAILED and will not be enabled.