Skip to content

Developer API and Bukkit Events

CraftingEngine provides a clean, modular public API module (craftingengine-api) enabling third-party plugins to initiate processes, register custom action/condition providers, listen to crafting lifecycle events, and query active workstations.


1. Maven and Gradle Coordinates

Add the CraftingEngine API dependency to your project:

Gradle (Kotlin DSL - build.gradle.kts)

repositories {
maven("https://repo.codemc.io/repository/maven-releases/")
}
dependencies {
compileOnly("dev.darkblade.craftingengine:craftingengine-api:2.9.0")
}

Maven (pom.xml)

<dependency>
<groupId>dev.darkblade.craftingengine</groupId>
<artifactId>craftingengine-api</artifactId>
<version>2.9.0</version>
<scope>provided</scope>
</dependency>

2. Accessing the Service API

Obtain the singleton CraftingEngineAPI instance via Bukkit’s ServicesManager or direct entry point:

import dev.darkblade.craftingengine.api.CraftingEngineAPI;
import org.bukkit.Bukkit;
public class MyPluginIntegration {
private CraftingEngineAPI api;
public void onEnable() {
this.api = Bukkit.getServicesManager().load(CraftingEngineAPI.class);
if (this.api == null) {
// Fallback or handle missing plugin
}
}
}

3. Bukkit Lifecycle Events

CraftingEngine dispatches asynchronous and synchronous Bukkit events throughout the crafting lifecycle:

Event ClassCancellableTiming / Trigger
ProcessPreStartEventYesDispatched before materials are consumed. Allows cancelling crafts.
ProcessStartedEventNoDispatched immediately after materials are consumed and stages begin.
StageTransitionEventNoDispatched when a process moves from one stage to another.
ProcessCompletedEventNoDispatched when all stages succeed and outputs are generated.
ProcessFailedEventNoDispatched when a process fails, aborts, or is abandoned.

Example: Event Listener

import dev.darkblade.craftingengine.api.event.ProcessPreStartEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class CraftingListener implements Listener {
@EventHandler
public void onProcessPreStart(ProcessPreStartEvent event) {
if (event.getRecipeId().equals("infernal_blade") && !event.getPlayer().hasPermission("myplugin.master")) {
event.setCancelled(true);
event.setCancelReason("You have not mastered Infernal Forging!");
}
}
}

4. Key Domain Contracts & Models (craftingengine-api)

The craftingengine-api module is decoupled from Bukkit and provides pure Java models:

Transactional Input Reservation (v2.8.0)

  • InputMode.RESERVE: Resource requirements configured with InputMode.RESERVE trigger ResourceReservedEffect on start and ResourceReleasedEffect on cancellation/failure.
  • ProcessEvent: Sealed interface includes domain events ResourceReservedEvent and ResourceReleasedEvent.

Capability Drain Policies (v2.7.0)

  • CapabilityDrainPolicy: Record defining variable name, drainPerTick, drainPerUse, and minimumThreshold.
  • StationCapability: Includes Optional<CapabilityDrainPolicy> drainPolicy() and isAvailable(StationState) check.

Ingredient Property Inheritance (v2.9.0)

  • InheritanceMode: Enum with COPY, MULTIPLY, and EXPRESSION.
  • PropertyInheritanceRule: Declarative rule record specifying source/target keys, modes, and expressions.
  • ResourceProducedEffect: Carries Map<String, StateValue> inheritedProperties injected into output PDC tags.

Sealed State Storage (StateValue)

  • dev.darkblade.craftingengine.api.state.StateValue permits 6 immutable record types:
    • StateValue.IntVal(int value)
    • StateValue.DoubleVal(double value)
    • StateValue.LongVal(long value)
    • StateValue.BoolVal(boolean value)
    • StateValue.StringVal(String value)
    • StateValue.ResourceRefVal(String resourceId)

5. Registering Custom Actions and Conditions

You can extend blueprint functionality by registering custom Java condition or action handlers with the RegistryManager:

api.getRegistryManager().registerAction("custom_teleport", (context, args) -> {
Player player = context.getPlayer();
Location target = parseLocation(args);
player.teleport(target);
});

Next Steps