ForgeEngine — Plugin Wiki
Configurable Crafting Stations for Spigot / Paper
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
1. 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. |
2. Crafting Stations (YAML)
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.
Station 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.
Station-level 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.
3. Recipes
Recipes are declared under a station's recipes: section.
Each recipe must have a unique recipe ID.
Code (YAML):
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
| 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. |
4. Ingredients & Outputs
Both ingredients and outputs use the same ItemReference syntax:
Code (Text):
provider{key=value,key2=value2}
- vanilla
- MythicMobs
- Oraxen
- Nexo
- ItemsAdder
Additional providers can be registered through the Developer API.
Ingredients
Code (YAML):
ingredients :
- 'vanilla {type=IRON_INGOT,amount=2 }'
- 'vanilla {type=DIAMOND_PICKAXE,amount=1 }!nc'
The item must exist in the player's inventory but is not removed when crafting.
Outputs — Three Formats
1. Compact string
Code (YAML):
output : 'vanilla {type=IRON_PICKAXE,amount=1 }'
Code (YAML):
output:
type : VANILLA
id : IRON_PICKAXE
amount : 1
name : '&fIron Pickaxe'
lore :
- '&7A sturdy tool.'
Code (YAML):
output:
- item : 'vanilla {type=IRON_INGOT,amount=2 }'
chance : 100
- item:
type : VANILLA
id : DIAMOND
amount : 1
chance : 12.5
This allows recipes to produce guaranteed base items alongside bonus drops.
5. 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:
Code (Text):
type{key=value;key2=value2}
- display="..." — custom tooltip line
- hide=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.
6. 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.
7. The Crafting Queue
Recipes with crafting-time > 0 are handled by QueueService.
The queue is maintained per player and per station and persisted to the database.
Queue lifecycle
- Queue: ingredients are taken immediately and outputs are pre-rolled once.
- Progress: getProgress() and getSecondsRemaining() 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.
Queue 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:
Code (Text):
auto-collect-on-complete: true
Expiry
Default:
Code (YAML):
queue:
ready-item-expiry:
enabled : true
after-days : 7
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.
8. Economy Integration
EconomyManager supports multiple pluggable economy backends.
- Vault — vault
- GemsEconomy — gemseconomy
- CoinsEngine — coinsengine
Recipes can select the backend using:
Code (Text):
money{amount=50,provider=vault}
Code (Text):
currency=<name>
EconomyBridge
It supports:
- has
- withdraw
- deposit
It activates only when:
Code (Text):
economy.enabled: true
9. RPG Integration (MMOCore)
ForgeEngine integrates with MMOCore through reflection.
Supported features:
- Level
- Level consumption
- Class
- Mana
- Stamina
Fallback behaviour
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.
10. PlaceholderAPI Integration
PlaceholderBridge connects to PlaceholderAPI when:
Code (Text):
placeholderapi.enabled: true
This is used by:
- placeholder{} conditions
- Level fallback
- Class fallback
- Other placeholder-based data
11. Database & Persistence
Database persists three major categories of data using HikariCP connection pooling.
1. 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. |
Table:
2. 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:
- host
- port
- database
- username
- password
- useSSL
- pool-size
History purge
Optional configuration:
Code (YAML):
database:
purge:
enabled : false
after-days : 30
12. GUI Behaviour
Recipes using:
hide-when-locked
or
hide-when-no-ingredients
Recipe 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 Recipe 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.
Recipe Preview GUI
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.
13. Configuration (config.yml)
Code (YAML):
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
14. 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:
Code (Text):
com.mastercraft.forgeengine.api.ForgeEngineAPI
Before using the API, always check whether ForgeEngine is available:
Code (Java):
if ( !ForgeEngineAPI. isAvailable ( ) ) return ;
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.
Code (Java):
ForgeEngineAPI. registerItemProvider (
"myitems",
"My Items",
myPlugin,
(args, amount ) -> buildMyItem (args, amount ),
(stack, args ) -> matchesMyItem (stack, args )
) ;
Code (YAML):
output : 'myitems {id=example,amount=1 }'
ingredients :
- 'myitems {id=material,amount=2 }'
Other plugins can open a ForgeEngine station directly for a player.
The normal station permission check and StationOpenEvent
are still applied.
Code (Java):
boolean opened =
ForgeEngineAPI. openStation (player, "iron_forge" ) ;
Advanced Item Providers
For advanced integrations, such as custom item matching or NBT-based
identification, implement ItemProvider directly and register
it through the API.
Code (Java):
ForgeEngineAPI. registerItemProvider (ItemProvider )
Appendix — Full Cheat Sheet
Example Recipe
Code (YAML):
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
ForgeEngine is a free Minecraft Java mod. Compatible with Minecraft 1.20.6, 1.21. Downloaded 7 times (via Spigot). Download it and open it directly in the game.