Compatibility
Minecraft: Java Edition
Platforms
Tags
Creators
Details
ForgeEngine
Overview
Platform: Spigot / Paper (Bukkit API)
ForgeEngine is a fully configurable crafting station plugin. Server owners can define stations and recipes entirely in YAML, with no code required, while developers can extend the plugin through a clean Java API.
It follows the popular "one YAML file per station" convention, while adding features such as:
- Weighted multi-outputs
- Rich condition and trigger system
- Non-consumed "tool" ingredients
- Persistent asynchronous crafting queue
- Multiple economy backends
- Public developer API
- MMOCore integration
- PlaceholderAPI integration
- MythicMobs / Oraxen / Nexo / ItemsAdder support
Core Concepts
| Concept | Class | Description |
|---|---|---|
| Station | CraftingStation |
A crafting menu with its own layout, recipes, permission, sounds and decorative items. |
| Recipe | Recipe |
One craftable entry inside a station: ingredients, outputs, conditions, triggers and timing. |
| Ingredient | RecipeIngredient |
An item required by a recipe, optionally non-consumed ("tool"). |
| Output | RecipeOutput |
An item produced by a recipe, with an optional drop chance. |
| Condition | RecipeCondition |
A requirement checked before a craft succeeds and optionally consumed. |
| Trigger | Trigger |
A side effect fired after a successful craft. |
| Queue Entry | QueueEntry |
A timed craft in progress, tracked per player/station and persisted to the database. |
Stations
Every file inside the stations/ folder becomes one CraftingStation.
Subfolders are allowed and are used purely for organisation.
The file name without .yml becomes the station's internal ID.
This follows the same general convention used by MMOItems item-type files.
Loading
StationManager recursively loads every .yml file under stations/ on startup.
If the folder is empty, an example example_forge.yml is copied automatically.
If a station fails to parse, it is logged and skipped without bringing down the rest of the server.
Keys
| Key | Type | Default | Description |
|---|---|---|---|
name |
string | file name | Display name. Supports #page# / #max# pagination placeholders. |
layout |
string | default |
ID of a registered StationLayout. |
preview-layout |
string | default |
ID of the PreviewLayout used for recipe previews. |
permission.enabled |
boolean | false |
Whether a permission is required to open the station. |
permission.node |
string | forgeengine.station.<id> |
Permission node checked when opening the station. |
sound |
string | config.yml | Bukkit Sound enum played when opening the station. |
max-queue-size |
int | config.yml | Maximum concurrent queued crafts per player for this station. |
fill |
item block | black glass pane | Decorative filler item for empty slots. |
no-recipe |
item block | gray glass pane | Shown in an empty recipe slot. |
locked-recipe |
item block | barrier | Shown instead of a locked recipe's real icon. |
empty-queue-slot |
item block | light gray glass pane | Shown in empty queue slots. |
command.enabled |
boolean | false |
Registers a dedicated /<name> command. |
command.name |
string | — | Command name. |
command.description |
string | — | Command description. |
command.permission |
string | — | Command permission. |
command.aliases |
list | — | Command aliases. |
recipes |
section | — | Map of recipeId -> recipe definition. |
Decorative GUI items such as fill, no-recipe, locked-recipe and empty-queue-slot belong to the station itself, not the layout.
This allows the same slot layout to be reused with different visual themes.
Recipes
Recipes are declared under a station's recipes: section.
Each recipe must have a unique recipe ID.
recipes:
iron_sword:
output: 'vanilla{type=IRON_SWORD,amount=1}'
ingredients:
- 'vanilla{type=IRON_INGOT,amount=2}'
- 'vanilla{type=STICK,amount=1}'
conditions:
- 'level{level=5}'
- 'money{amount=50}'
triggers:
- 'sound{sound=ENTITY_PLAYER_LEVELUP}'
- 'message{format="&aYou forged an iron sword!"}'
crafting-time: 10
cooldown: 5
options:
glow: true
Keys
| Key | Type | Default | Description |
|---|---|---|---|
output |
string / map / list | — | One or more possible outputs. |
ingredients |
string list | [] |
Required items. Append !nc for non-consumed items. |
conditions |
string list | [] |
Non-item requirements. |
triggers |
string list | [] |
Effects fired after a successful craft. |
crafting-time |
int | 0 |
Crafting time in seconds. 0 = instant craft. |
cooldown |
int | 0 |
Per-recipe cooldown in seconds. |
slot |
int | -1 |
Fixed GUI slot. -1 = automatic placement. |
icon |
string / map | first output | Overrides the recipe icon. |
options.output-item |
boolean | true |
Whether the output item is actually given. |
options.silent-craft |
boolean | false |
Suppresses default craft feedback. |
options.hide-when-locked |
boolean | false |
Completely hides the recipe while locked. |
options.hide-when-no-ingredients |
boolean | false |
Hides the recipe if ingredients are missing. |
options.blocked-icon |
boolean | true |
Uses the station's locked recipe icon while locked. |
options.glow |
boolean | false |
Adds an enchantment glint while unlocked. |
options.close-on-craft |
boolean | false |
Closes the GUI after a successful craft. |
Items
Both ingredients and outputs use the same ItemReference syntax:
provider{key=value,key2=value2}
Built-in providers include:
vanilla- MythicMobs
- Oraxen
- Nexo
- ItemsAdder
Additional providers can be registered through the Developer API.
Ingredients
ingredients:
- 'vanilla{type=IRON_INGOT,amount=2}'
- 'vanilla{type=DIAMOND_PICKAXE,amount=1}!nc'
!nc means "no consume".
The item must exist in the player's inventory but is not removed when crafting.
Outputs
Compact
output: 'vanilla{type=IRON_PICKAXE,amount=1}'
Expanded
output:
type: VANILLA
id: IRON_PICKAXE
amount: 1
name: '&fIron Pickaxe'
lore:
- '&7A sturdy tool.'
Weighted
output:
- item: 'vanilla{type=IRON_INGOT,amount=2}'
chance: 100
- item:
type: VANILLA
id: DIAMOND
amount: 1
chance: 12.5
Each output rolls independently.
This allows recipes to produce guaranteed base items alongside bonus drops.
Conditions
Conditions determine whether a recipe can be crafted.
Important: every condition is checked first. Only when all conditions pass are ingredients or other resources consumed.
This prevents partial charges, such as taking money before discovering that another requirement failed.
Syntax:
type{key=value;key2=value2}
Common optional arguments:
display="..."— custom tooltip linehide=true— hides the requirement from the tooltip
| Condition | Syntax | Behaviour |
|---|---|---|
| Level | level{level=<n>,consume=<bool>} |
Requires a minimum level. Uses MMOCore, then PlaceholderAPI, then vanilla XP level. |
| Class | class{list=<Class1>,<Class2>,...} |
Requires one of the listed RPG classes. |
| Permission | permission{list="perm1,perm2"} |
Requires every listed Bukkit permission. |
| Placeholder | placeholder{placeholder="<Placeholder>~<Comparator>~<Value>"} |
Arbitrary PlaceholderAPI comparison. |
| Food | food{amount=<n>} |
Requires and consumes food level. |
| Mana | mana{amount=<n>,format="0.#"} |
Requires and consumes MMOCore mana. |
| Stamina | stamina{amount=<n>,format="0.#"} |
Requires and consumes MMOCore stamina. |
| Money | money{amount=<n>,provider=vault|gemseconomy|coinsengine,currency=<name>} |
Requires and withdraws money through the selected economy backend. |
Non-hidden conditions are automatically displayed in the recipe tooltip.
Triggers
Triggers execute after a craft has completely succeeded.
Multiple triggers of the same type can be used.
| Trigger | Syntax | Effect |
|---|---|---|
| Message | message{format="..."} |
Sends a chat message to the crafter. |
| Action Bar | actionbar{format="..."} |
Sends an action-bar message. |
| Broadcast | broadcast{format="..."} |
Broadcasts a message server-wide. |
| Title | title{title="...",subtitle="...",fade-in=10,stay=40,fade-out=10} |
Displays a title and subtitle. |
| Command | command{format="...",sender=CONSOLE|PLAYER} |
Runs a command as console or player. |
| Sound | sound{sound=<Sound>,volume=1,pitch=1} |
Plays a sound to the crafter. |
| Particle | particle{particle=<Particle>,amount=20} |
Spawns particles at the player. |
| Exp | exp{amount=<n>} |
Gives vanilla XP. |
| Money | money{amount=<n>,provider=vault,currency=<name>} |
Pays money through the selected economy backend. |
| MythicMobs Skill | mmskill{id=<skill>} |
Casts a MythicMobs skill. |
| MythicMobs Spawn | mmspawnmob{id=<mob>,amount=1,level=1} |
Spawns a MythicMobs mob. |
| MythicMobs Signal | mmsignal{signal=<id>} |
Sends a MythicMobs signal. |
| Bonus Item | vanilla{type=...} |
Any registered item provider can be used as a bonus item trigger. |
Unknown trigger types are logged as warnings and ignored. The recipe itself still loads.
Queue
Recipes with crafting-time > 0 are handled by QueueService.
The queue is maintained per player and per station and persisted to the database.
Lifecycle
- Queue: ingredients are taken immediately and outputs are pre-rolled once.
- Progress:
getProgress()andgetSecondsRemaining()drive the GUI progress bar. - Collection: completed items can be collected manually or automatically.
- Expiry: completed but uncollected items can expire after a configurable number of days.
- Cancellation: incomplete crafts can be cancelled and their consumed ingredients refunded.
- Persistence: queue entries survive server restarts.
Progress
The GUI displays a 10-segment progress bar while a craft is running.
Once complete, the queue icon changes to a ready state.
Auto-Collection
When:
auto-collect-on-complete: true
is enabled, completed items are automatically collected while the player is online.
Expiry
Default:
queue:
ready-item-expiry:
enabled: true
after-days: 7
Persistence
Every queue entry is persisted.
A server restart therefore does not lose:
- Crafting progress
- Consumed ingredients
- Pending outputs
If a station or recipe referenced by a stored entry no longer exists, the entry is discarded and a warning is logged.
Economy
EconomyManager supports multiple pluggable economy backends.
- Vault —
vault - GemsEconomy —
gemseconomy - CoinsEngine —
coinsengine
Recipes can select the backend using:
money{amount=50,provider=vault}
Multi-currency providers can additionally specify:
currency=<name>
Money is only withdrawn after every other condition has passed.
EconomyBridge
It supports:
haswithdrawdeposit
It activates only when:
economy.enabled: true
and Vault is present.
MMOCore
ForgeEngine integrates with MMOCore through reflection.
Supported features:
- Level
- Level consumption
- Class
- Mana
- Stamina
Fallbacks
If MMOCore is not installed:
Level
%player_level% through PlaceholderAPI is checked first, followed by vanilla XP level.
Class
%mmocore_class% is used through PlaceholderAPI, then none.
Mana / Stamina
These have no vanilla equivalent and therefore always fail if MMOCore is unavailable.
A one-time warning is logged.
PlaceholderAPI
PlaceholderBridge connects to PlaceholderAPI when:
placeholderapi.enabled: true
and PlaceholderAPI is installed.
This is used by:
placeholder{}conditions- Level fallback
- Class fallback
- Other placeholder-based data
Database
Database persists three major categories of data using HikariCP connection pooling.
Craft Log
Recorded actions include:
| Action | Description |
|---|---|
QUEUE_START |
A timed recipe was queued. |
COLLECT |
A completed queued craft was collected. |
CANCEL |
A queued craft was cancelled and refunded. |
INSTANT |
An instant recipe was completed. |
EXPIRED |
A completed item expired before collection. |
Cooldowns
Active per-recipe cooldowns are also persisted.
SQLite
SQLite uses a single connection in the pool to avoid database locking issues.
MySQL
Configured through:
hostportdatabaseusernamepassworduseSSLpool-size
Purge
Optional configuration:
database:
purge:
enabled: false
after-days: 30
GUI
Recipes using:
hide-when-locked
or
hide-when-no-ingredients
can be hidden depending on their state.
Lore
Recipe icons automatically display:
- Required ingredients
- Green / red ingredient status
- Non-hidden conditions
- Crafting time
- Locked / unlocked state
glow: true adds an enchantment glint while unlocked.
Locked Icon
When blocked-icon is enabled and the recipe is locked, the station's locked-recipe item replaces the real icon.
The same behaviour is used in both the station list and recipe preview.
Preview
Right-clicking a recipe opens the preview.
The preview displays:
- Full output icon
- Every ingredient
- Owned / required status
- Confirm button
- Required conditions
Both the station GUI and preview automatically refresh while open.
Configuration
debug: false
queue-tick-rate: 10
default-max-queue-size: 9
background-queue-processing: true
auto-collect-on-complete: false
queue:
ready-item-expiry:
enabled: true
after-days: 7
database:
purge:
enabled: false
after-days: 30
economy:
enabled: false
placeholderapi:
enabled: false
providers:
<providerId>: true
default-open-sound: BLOCK_CHEST_OPEN
default-craft-sound: ENTITY_PLAYER_LEVELUP
Developer API
ForgeEngine provides a public API for other plugins that want to integrate with crafting stations, register custom item providers, or open stations programmatically.
API Class:
com.mastercraft.forgeengine.api.ForgeEngineAPI
Availability
Before using the API, always check whether ForgeEngine is available:
if (!ForgeEngineAPI.isAvailable()) return;
Providers
The API allows other plugins to register their own item providers.
This makes custom items available inside station YAML files as ingredients, outputs, and other item-based features.
ForgeEngineAPI.registerItemProvider(
"myitems",
"My Items",
myPlugin,
(args, amount) -> buildMyItem(args, amount),
(stack, args) -> matchesMyItem(stack, args)
);
Once registered, the provider can be used directly in station YAML:
output: 'myitems{id=example,amount=1}'
ingredients:
- 'myitems{id=material,amount=2}'
Opening Stations
Other plugins can open a ForgeEngine station directly for a player.
The normal station permission check and StationOpenEvent are still applied.
boolean opened =
ForgeEngineAPI.openStation(player, "iron_forge");
Integration
To integrate ForgeEngine into another plugin:
- Add ForgeEngine as a compile-only / provided dependency.
- Do not shade ForgeEngine into your plugin.
- Add ForgeEngine to your
dependorsoftdependlist. - Register custom item providers from your plugin's
onEnable().
Advanced Providers
For advanced integrations, such as custom item matching or NBT-based identification, implement ItemProvider directly and register it through the API.
ForgeEngineAPI.registerItemProvider(ItemProvider)
Note: The Developer API is intended for plugin developers who want to extend ForgeEngine or integrate it with their own systems. Server owners do not need to use the API to configure stations and recipes.
Cheat Sheet
Example
recipes:
example_recipe:
output:
- item: 'vanilla{type=NETHERITE_INGOT,amount=1}'
chance: 100
- item: 'vanilla{type=DIAMOND,amount=1}'
chance: 15
ingredients:
- 'vanilla{type=IRON_INGOT,amount=4}'
- 'vanilla{type=BLAZE_ROD,amount=2}'
- 'vanilla{type=SMITHING_TABLE,amount=1}!nc'
conditions:
- 'level{level=25,consume=false}'
- 'class{list=Blacksmith,Artisan}'
- 'permission{list="forge.advanced"}'
- 'placeholder{placeholder="%player_level%~>=~25"}'
- 'food{amount=6}'
- 'money{amount=250,provider=vault}'
- 'mana{amount=30,format="0.#"}'
- 'stamina{amount=20,format="0.#"}'
triggers:
- 'message{format="&aYou forged a Netherite Ingot!"}'
- 'actionbar{format="&6Crafting complete"}'
- 'broadcast{format="&e%player% just forged something legendary!"}'
- 'title{title="&6Forged!",subtitle="&7A legendary item",fade-in=10,stay=40,fade-out=10}'
- 'sound{sound=ENTITY_PLAYER_LEVELUP,volume=1,pitch=1}'
- 'particle{particle=HAPPY_VILLAGER,amount=20}'
- 'exp{amount=50}'
- 'money{amount=10,provider=vault}'
- 'vanilla{type=EMERALD,amount=1}'
crafting-time: 30
cooldown: 60
options:
glow: true
blocked-icon: true
close-on-craft: false
ForgeEngine
Fully configurable crafting stations for Spigot / Paper
YAML-driven • Async Queue • Multi-Economy • Conditions • Triggers • Developer API

