
An advanced PaperMC crafting engine for building complex recipes with NBT-supported custom items.
Unlock then full potential of crafting on your PaperMC server.
Custom Crafter API is a powerful crafting engine and developer library tailored for modern PaperMC servers. Unlike standard plugins that only support vanilla item substitutions, Custom Crafter empowers you to create complex recipes using Custom Items (with NBT, Lore, and Model Data) as both ingredients and results.
Whether you are running an RPG server requiring a deep progression system or a Survival server needing unique mechanics, Custom Crafter provides the infrastructure to make it happen.
(Japanese Document (日本語ドキュメント))
Advanced Ingredient Support: Use fully customized items (NBT, Enchantments, CustomModelData) as recipe ingredients. Build a true "tier-based" crafting
Limitless Recipe Design: Create recipes with unique shapes, multiple result counts, and complex requirements that vanilla crafting cannot handle.
Non-Intrusive Mechanics: Operates via a dedicated "Custom Crafting Station" system (Gold Block base), ensuring zero conflict with vanilla
Developer-First API: A robust Kotlin-based API allows other plugins to register and manage recipes programmatically.
Paper Native: Built exclusively for PaperMC to leverage asynchronous optimizations and modern API features.
(Compatibility): Vanilla crafting remains fully functional.
CustomCrafter is written in Kotlin and requires a prerequisite library to run.
plugins directory.GOLD_BLOCK.New Release! The CustomCrafter-API Demo Plugin is now available!!!
-> custom-crafter-api-demo (on Paper-Hangar)
GOLD_BLOCK).infinityIronBlockCore (Code).infinityIronBlock (Code).infinityIronBlock)infinityIronBlock)infinityIronBlockExtract (Code).After cloning this repository locally, you can build a demo plugin that provides the recipe included in this video, as well as several other recipes, by running the following commands.
mvn -pl demo package
The jar file, which can be placed in the server's plugins directory, will be created in the demo/target directory.
| Custom_Crafter Version | Paper Version |
|---|---|
| 5.0.13 ~ 5.0.19 (Latest) | 1.21.4 ~ 1.21.11 |
| 5.0.0 ~ 5.0.11 | 1.21.3 |
| 4.3 (Legacy) | 1.21.3 |
| 4.2 (Legacy) | 1.20.1 ~ 1.20.4 |
⚠️ Essential Warning:
custom crafter does not support running on Spigot/Bukkit servers. Please ensure you run it on PaperMC or a PaperMC-fork.
Since version 5.0.0, custom crafter is designed not only as a plugin but also as an API for defining and registering custom recipes.
You can freely create custom recipes from your plugin and register them into the CustomCrafter system.
For more detailed information and a complete list of classes and methods, please refer to:
or Build:
mvn -pl api dokka:dokkamvn -pl api dokka:javadocPlugins that depend on CustomCrafterAPI must add Custom_Crafter to the depend section of their plugin.yml.
depend:
- "Custom_Crafter"
Latest Version: Versions
When using the API, you must assume the CustomCrafter plugin will be present at runtime. Therefore, set the scope to compile-time only.
Also, if you are creating plugins in Kotlin, please set the Kotlin-stdlib dependency to "compile-time only".
"compile-time" scope names in:
providedcompileOnlyFrom Maven Central
<!-- CustomCrafterAPI Dependency -->
<dependency>
<groupId>io.github.sakaki-aruka</groupId>
<artifactId>custom-crafter-api</artifactId>
<version>5.0.19</version>
<scope>provided</scope>
</dependency>
<!-- kotlin-stdlib Dependency -->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
Gradle (Groovy) Configuration Example
dependencies {
// CustomCrafterAPI Dependency
compileOnly 'io.github.sakaki-aruka:custom-crafter-api:5.0.19'
// kotlin-stdlib Dependency (If you needed)
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:2.3.0'
}
Gradle (Kotlin DSL) Configuration Example
dependencies {
// CustomCrafterAPI Dependency
compileOnly("io.github.sakaki-aruka:custom-crafter-api:5.0.19")
// kotlin-stdlib Dependency (If you needed)
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.3.0")
}
Here is a basic guide on defining custom recipes in your plugin using the CustomCrafterAPI.
Example code to check if the CustomCrafterAPI version your plugin depends on is fully compatible with the version deployed on the server.
/*
* This code is intended to strictly check compatibility with the API installed on the server,
* and it's not necessarily required for the plugin to function.
*/
class YourPlugin: JavaPlugin() {
// Define the dependent API version as a constant
const val DEPEND_API_VERSION = "5.0.19"
@Override
fun onEnable() {
// Disable the plugin if there is no compatibility to prevent errors
if (!CustomCrafterAPI.hasFullCompatibility(DEPEND_API_VERSION)) {
Bukkit.pluginManager.disablePlugin(this)
return
}
}
}
A custom recipe is mainly composed of three elements:
CMatter): Defines the conditions for the "materials" required for crafting.ResultSupplier): Defines what is generated as the "result" upon successful crafting.CRecipe): Groups the materials, results, and crafting shape (shaped/shapeless) for registration.Define the items (CMatter) that serve as materials for the recipe. CMatter determines which item, how many, and where it needs to be placed to allow crafting.
CMatterImpl or an implementation class of the CMatter interface.Example: Use 1 Stone OR 1 Cobblestone as a material
// In Kotlin
val matter: CMatter = CMatterImpl(
name = "test-matter",
candidate = setOf(Material.STONE, Material.COBBLESTONE), // Stone or Cobblestone can be used
amount = 1, // Required amount
mass = false, // true: consider stacking (usually false)
predicates = null // Additional NBT or other conditions (usually null)
)
Using the Shorthand (of)
In simple cases where multiple Material types are accepted for the candidate, the following shorthand is convenient:
// In Kotlin
val matter: CMatter = CMatterImpl.of(Material.STONE, Material.COBBLESTONE)
This example creates a flexible material that functions as a material if either Stone or Cobblestone is present.
Define the items given to the player or the process executed when the recipe is completed.
A ResultSupplier is a function (supplier) that receives various crafting conditions (Config) and determines the final output items (List<ItemStack>).
Example: Returning a result based on complex conditions
// In Kotlin
val supplier = ResultSupplier { config ->
// 'config' includes information about the crafting environment (player, workbench, etc.)
// Write the process to create and return a list of ItemStacks here.
emptyList<ItemStack>() // Example: returns nothing
}
Utilizing Simplified Helper Methods
If complex processing is not required, the helper methods provided by CustomCrafter are useful.
// In Kotlin
// Always returns the specified ItemStack (e.g., 1 Stone)
val supplier = ResultSupplier.single(ItemStack.of(Material.STONE))
// Returns the ItemStack multiplied by the number of times the player shift-clicked to craft multiple items (smart behavior)
val supplier2 = ResultSupplier.timesSingle(ItemStack.of(Material.STONE))
ResultSupplier#timesSingle is very convenient as it automatically manages the behavior when a player crafts a large amount at once. 😊
This is the core component that combines the custom materials and crafting results to register the recipe within the CustomCrafter system.
CRecipeImpl, is typically used.Example: Defining a Simple Shaped Recipe
// In Kotlin
val recipe: CRecipe = CRecipeImpl(
name = "test-recipe",
items = mapOf(CoordinateComponent(0, 0) to matter), // 'matter' is the CMatter created in step 1.
containers = null, // Additional conditions (permissions, etc.). null if not needed.
results = setOf(ResultSupplier.timesSingle(Material.STONE)), // A Set of ResultSuppliers created in step 2.
type = CRecipe.Type.SHAPED // Shaped Recipe
)
items: A map of coordinates (CoordinateComponent(x, y)) and the required material (CMatter) in the crafting grid.type: Specifies the recipe shape.CRecipe.Type.SHAPED: Shaped Recipe. The coordinates in items are crucial.CRecipe.Type.SHAPELESS: Shapeless Recipe. The CoordinateComponent values in items can be arbitrary. 😊MIT License
Copyright (c) 2023 - 2026 Sakaki-Aruka
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This product includes software developed by the IMT Atlantique.