Interface RecipeService
This service allows addon developers to create, register, and manage custom crafting recipes that integrate with the Zentrix game system.
Features
- Register shaped and shapeless recipes
- Set craft limits (GLOBAL per world/game, not per player!)
- Query existing recipes
- Remove recipes programmatically
- Check global craft availability
- Batch operations for multiple recipes
IMPORTANT: Craft Limits are GLOBAL per World!
Craft limits restrict how many TOTAL times a recipe can be crafted in a world/game, not per player:
- One-time (
oneTime()): Only 1 player total can craft it per world - Craft limit (
craftLimit(9)): Only 9 total crafts per world (any players) - Unlimited: Any number of players can craft unlimited times
Creating and Registering a Recipe
RecipeService recipeService = api.getRecipeService();
// Create a shaped recipe
RecipeBuilder builder = new RecipeBuilder()
.id("super-pickaxe")
.shaped()
.result(new ItemStack(Material.DIAMOND_PICKAXE))
.pattern("DDD", " S ", " S ")
.ingredient('D', new ItemStack(Material.DIAMOND))
.ingredient('S', new ItemStack(Material.STICK))
.craftLimit(1);
// Register it
boolean success = recipeService.registerRecipe(builder);
Querying Recipes
// Get all recipes
Collection<ZentrixRecipe> recipes = recipeService.getAllRecipes();
// Find a specific recipe
Optional<ZentrixRecipe> recipe = recipeService.getRecipe("super-pickaxe");
// Check if recipe exists
boolean exists = recipeService.recipeExists("super-pickaxe");
- Since:
- 1.0.1
- See Also:
-
Method Summary
Modifier and TypeMethodDescriptionbooleancanCraftInWorld(@NotNull String worldName, @NotNull String recipeId) Checks if a recipe can still be crafted in a specific world.booleancanPlayerCraft(@NotNull UUID playerId, @NotNull String recipeId) Checks if a recipe can still be crafted in the player's current world.booleancanPlayerCraft(@NotNull org.bukkit.entity.Player player, @NotNull String recipeId) Checks if a recipe can still be crafted in the player's current world.voidcleanupPlayer(@NotNull UUID playerId) Cleans up craft tracking data for a specific player.voidcleanupWorld(@NotNull String worldName) Cleans up craft tracking data for a specific world.default @NotNull RecipeBuilderCreates a new RecipeBuilder instance.default @NotNull RecipeBuildercreateBuilder(@NotNull String id) Creates a new RecipeBuilder with the specified ID.@NotNull Collection<ZentrixRecipe> findRecipesByCreator(@NotNull String creatorName) Finds recipes created by a specific player.@NotNull Collection<ZentrixRecipe> findRecipesByResult(@NotNull org.bukkit.inventory.ItemStack result) Finds recipes by their result item type.@NotNull Collection<ZentrixRecipe> Gets all registered recipes.intgetGlobalCraftCount(@NotNull String worldName, @NotNull String recipeId) Gets the GLOBAL craft count for a recipe in a specific world.@NotNull Collection<ZentrixRecipe> Gets all recipes with craft limits.@NotNull Collection<ZentrixRecipe> Gets all one-time recipes.intgetPlayerCraftCount(@NotNull UUID playerId, @NotNull String recipeId) Gets how many times a specific player has crafted a recipe in the current game.intgetPlayerCraftCount(@NotNull org.bukkit.entity.Player player, @NotNull String recipeId) Gets how many times a specific player has crafted a recipe in the current game.@NotNull Optional<ZentrixRecipe> Gets a recipe by its ID.intGets the total number of registered recipes.@NotNull Collection<String> Gets the IDs of all registered recipes.@NotNull Collection<ZentrixRecipe> getRecipesByAddon(@NotNull String addonId) Gets recipes added by a specific addon.intgetRemainingCrafts(@NotNull UUID playerId, @NotNull String recipeId) Gets the remaining GLOBAL crafts for a recipe in the player's world.intgetRemainingCrafts(@NotNull org.bukkit.entity.Player player, @NotNull String recipeId) Gets the remaining GLOBAL crafts for a recipe in the player's world.intgetRemainingCraftsInWorld(@NotNull String worldName, @NotNull String recipeId) Gets the remaining GLOBAL crafts for a recipe in a specific world.default booleanhasPlayerCraftedOneTime(@NotNull UUID playerId, @NotNull String recipeId) Deprecated, for removal: This API element is subject to removal in a future version.booleanhasPlayerEverCrafted(@NotNull UUID playerId, @NotNull String recipeId) Checks if a player has ever crafted a specific recipe (for first-time bonus).booleanChecks if the recipe system is available and ready.booleanisRecipePersisted(@NotNull String recipeId) Checks if a recipe is persisted to disk.booleanrecipeExists(@NotNull String recipeId) Checks if a recipe with the given ID exists.booleanregisterRecipe(@NotNull RecipeBuilder builder) Registers a new recipe from a builder.@NotNull CompletableFuture<Boolean> registerRecipeAsync(@NotNull RecipeBuilder builder) Registers a new recipe and saves it to file asynchronously.intregisterRecipes(@NotNull Collection<RecipeBuilder> builders) Registers multiple recipes at once.@NotNull CompletableFuture<Integer> registerRecipesAsync(@NotNull Collection<RecipeBuilder> builders) Registers multiple recipes and saves them to file asynchronously.voidReloads all recipes from disk.@NotNull CompletableFuture<Boolean> saveRecipe(@NotNull String recipeId) Saves an existing recipe to disk.booleanunregisterRecipe(@NotNull String recipeId) Unregisters a recipe by its ID.@NotNull CompletableFuture<Boolean> unregisterRecipeAndDelete(@NotNull String recipeId) Unregisters a recipe and deletes it from disk.intunregisterRecipes(@NotNull Collection<String> recipeIds) Unregisters multiple recipes by their IDs.@NotNull CompletableFuture<Integer> unregisterRecipesAndDelete(@NotNull Collection<String> recipeIds) Unregisters multiple recipes and deletes them from disk.booleanupdateRecipe(@NotNull RecipeBuilder builder) Updates an existing recipe with new settings.@NotNull CompletableFuture<Boolean> updateRecipeAsync(@NotNull RecipeBuilder builder) Updates an existing recipe and saves changes to file asynchronously.
-
Method Details
-
registerRecipe
Registers a new recipe from a builder.The builder must have all required fields set (ID, result, and ingredients). If a recipe with the same ID already exists, registration will fail.
- Parameters:
builder- The recipe builder with configuration- Returns:
- true if registered successfully, false if failed (e.g., duplicate ID)
- Throws:
IllegalArgumentException- if the builder is invalid
-
registerRecipeAsync
@NotNull @NotNull CompletableFuture<Boolean> registerRecipeAsync(@NotNull @NotNull RecipeBuilder builder) Registers a new recipe and saves it to file asynchronously.This method performs the same registration as
registerRecipe(RecipeBuilder)but also persists the recipe to disk so it survives server restarts.The returned CompletableFuture completes only after both registration AND file saving have completed (or failed).
- Parameters:
builder- The recipe builder with configuration- Returns:
- CompletableFuture that completes with true if successful
- Throws:
IllegalArgumentException- if the builder is invalid
-
registerRecipes
Registers multiple recipes at once.This is more efficient than calling
registerRecipe(RecipeBuilder)multiple times, especially for addons with many recipes.- Parameters:
builders- The recipe builders to register- Returns:
- Number of recipes successfully registered
- Throws:
IllegalArgumentException- if any builder is invalid
-
registerRecipesAsync
@NotNull @NotNull CompletableFuture<Integer> registerRecipesAsync(@NotNull @NotNull Collection<RecipeBuilder> builders) Registers multiple recipes and saves them to file asynchronously.- Parameters:
builders- The recipe builders to register- Returns:
- CompletableFuture that completes with the number of successful registrations
-
unregisterRecipe
Unregisters a recipe by its ID.This removes the recipe from the server but does NOT delete the file. Use
unregisterRecipeAndDelete(String)to also remove from disk.- Parameters:
recipeId- The recipe ID to unregister- Returns:
- true if the recipe was found and unregistered
-
unregisterRecipeAndDelete
@NotNull @NotNull CompletableFuture<Boolean> unregisterRecipeAndDelete(@NotNull @NotNull String recipeId) Unregisters a recipe and deletes it from disk.This completely removes the recipe, including the saved file. The returned CompletableFuture completes only after both unregistration AND file deletion have completed (or failed).
- Parameters:
recipeId- The recipe ID to unregister and delete- Returns:
- CompletableFuture that completes with true if successful
-
unregisterRecipes
Unregisters multiple recipes by their IDs.- Parameters:
recipeIds- The recipe IDs to unregister- Returns:
- Number of recipes successfully unregistered
-
unregisterRecipesAndDelete
@NotNull @NotNull CompletableFuture<Integer> unregisterRecipesAndDelete(@NotNull @NotNull Collection<String> recipeIds) Unregisters multiple recipes and deletes them from disk.- Parameters:
recipeIds- The recipe IDs to unregister and delete- Returns:
- CompletableFuture that completes with the number of successful deletions
-
updateRecipe
Updates an existing recipe with new settings.This replaces the existing recipe while preserving craft tracking data. The builder's ID must match an existing recipe.
- Parameters:
builder- The recipe builder with updated configuration- Returns:
- true if the recipe was updated successfully
- Throws:
IllegalArgumentException- if the builder is invalid or recipe doesn't exist
-
updateRecipeAsync
@NotNull @NotNull CompletableFuture<Boolean> updateRecipeAsync(@NotNull @NotNull RecipeBuilder builder) Updates an existing recipe and saves changes to file asynchronously.- Parameters:
builder- The recipe builder with updated configuration- Returns:
- CompletableFuture that completes with true if successful
- Throws:
IllegalArgumentException- if the builder is invalid
-
getRecipe
Gets a recipe by its ID.- Parameters:
recipeId- The recipe ID- Returns:
- Optional containing the recipe, or empty if not found
-
getAllRecipes
Gets all registered recipes.The returned collection is a snapshot and modifications won't affect the actual recipe registry.
- Returns:
- Collection of all registered recipes
-
recipeExists
Checks if a recipe with the given ID exists.- Parameters:
recipeId- The recipe ID to check- Returns:
- true if a recipe with this ID exists
-
getRecipeCount
int getRecipeCount()Gets the total number of registered recipes.- Returns:
- The recipe count
-
findRecipesByResult
@NotNull @NotNull Collection<ZentrixRecipe> findRecipesByResult(@NotNull @NotNull org.bukkit.inventory.ItemStack result) Finds recipes by their result item type.Returns all recipes that produce an item of the specified type.
- Parameters:
result- The result item to search for (type is compared)- Returns:
- Collection of matching recipes
-
findRecipesByCreator
@NotNull @NotNull Collection<ZentrixRecipe> findRecipesByCreator(@NotNull @NotNull String creatorName) Finds recipes created by a specific player.- Parameters:
creatorName- The creator's name- Returns:
- Collection of recipes created by this player
-
getOneTimeRecipes
Gets all one-time recipes.- Returns:
- Collection of one-time recipes
-
getLimitedRecipes
Gets all recipes with craft limits.- Returns:
- Collection of recipes that have craft limits
-
canPlayerCraft
boolean canPlayerCraft(@NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull String recipeId) Checks if a recipe can still be crafted in the player's current world.IMPORTANT: Craft limits are GLOBAL per world, not per player!
- One-time recipes: Only 1 player total can craft per world
- Limited recipes: Only N total crafts allowed per world
- Parameters:
player- The player (used to determine world)recipeId- The recipe ID- Returns:
- true if the GLOBAL limit hasn't been reached
-
canPlayerCraft
Checks if a recipe can still be crafted in the player's current world.IMPORTANT: Craft limits are GLOBAL per world, not per player!
Note: If the player is offline (not found by UUID), this method returns false because the world cannot be determined. This does NOT mean the recipe cannot be crafted - use
canCraftInWorld(String, String)if you know the world name.- Parameters:
playerId- The player's UUID (used to determine world)recipeId- The recipe ID- Returns:
- true if the GLOBAL limit hasn't been reached, false if limit reached OR player offline
-
canCraftInWorld
Checks if a recipe can still be crafted in a specific world.IMPORTANT: Craft limits are GLOBAL per world, not per player!
- Parameters:
worldName- The world name to checkrecipeId- The recipe ID- Returns:
- true if the GLOBAL limit hasn't been reached
-
getPlayerCraftCount
int getPlayerCraftCount(@NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull String recipeId) Gets how many times a specific player has crafted a recipe in the current game.Note: This is for statistics only! Craft limits are checked globally, not per player. Use
getRemainingCrafts(Player, String)to check if the recipe can still be crafted.- Parameters:
player- The playerrecipeId- The recipe ID- Returns:
- The number of times THIS player crafted it (for stats)
-
getPlayerCraftCount
Gets how many times a specific player has crafted a recipe in the current game.Note: This is for statistics only! Craft limits are checked globally. Returns 0 if the player is offline.
- Parameters:
playerId- The player's UUIDrecipeId- The recipe ID- Returns:
- The number of times THIS player crafted it (for stats), 0 if player offline
-
getGlobalCraftCount
Gets the GLOBAL craft count for a recipe in a specific world.This returns the TOTAL number of times ANY player has crafted this recipe in the specified world.
- Parameters:
worldName- The world namerecipeId- The recipe ID- Returns:
- Total crafts in this world by all players
-
getRemainingCrafts
int getRemainingCrafts(@NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull String recipeId) Gets the remaining GLOBAL crafts for a recipe in the player's world.IMPORTANT: This returns the GLOBAL remaining count, not per-player!
- One-time: Returns 1 if not crafted, 0 if someone crafted it
- Limited (e.g., 9): Returns 9 minus total crafts by ALL players
- Unlimited: Returns -1
- Parameters:
player- The player (used to determine world)recipeId- The recipe ID- Returns:
- GLOBAL remaining crafts, -1 if unlimited, 0 if limit reached
-
getRemainingCrafts
Gets the remaining GLOBAL crafts for a recipe in the player's world.IMPORTANT: This returns the GLOBAL remaining count, not per-player!
Note: If the player is offline, returns -1 (treated as unlimited/unknown). Use
getRemainingCraftsInWorld(String, String)if you know the world name.- Parameters:
playerId- The player's UUID (used to determine world)recipeId- The recipe ID- Returns:
- GLOBAL remaining crafts, -1 if unlimited or player offline
-
getRemainingCraftsInWorld
int getRemainingCraftsInWorld(@NotNull @NotNull String worldName, @NotNull @NotNull String recipeId) Gets the remaining GLOBAL crafts for a recipe in a specific world.- Parameters:
worldName- The world namerecipeId- The recipe ID- Returns:
- GLOBAL remaining crafts, -1 if unlimited
-
hasPlayerEverCrafted
Checks if a player has ever crafted a specific recipe (for first-time bonus).Note: This is for the first-time crafting bonus tracking, not for one-time recipe limits. One-time limits are checked globally.
- Parameters:
playerId- The player's UUIDrecipeId- The recipe ID- Returns:
- true if this player has crafted this recipe at least once
-
hasPlayerCraftedOneTime
@Deprecated(since="1.0.2", forRemoval=true) default boolean hasPlayerCraftedOneTime(@NotNull @NotNull UUID playerId, @NotNull @NotNull String recipeId) Deprecated, for removal: This API element is subject to removal in a future version.UsehasPlayerEverCrafted(UUID, String)instead. The old name was misleading as it suggested relation to one-time recipes. -
getRecipeIds
Gets the IDs of all registered recipes.- Returns:
- Collection of recipe IDs
-
getRecipesByAddon
Gets recipes added by a specific addon.Recipes track their source addon via a custom field.
- Parameters:
addonId- The addon ID- Returns:
- Collection of recipes from this addon
-
isRecipePersisted
Checks if a recipe is persisted to disk.- Parameters:
recipeId- The recipe ID- Returns:
- true if the recipe file exists on disk
-
saveRecipe
Saves an existing recipe to disk.Use this to persist a recipe that was registered without saving, or to update the saved version after modifications.
- Parameters:
recipeId- The recipe ID to save- Returns:
- CompletableFuture that completes with true if saved successfully
-
reloadRecipes
void reloadRecipes()Reloads all recipes from disk.This clears the recipe registry and reloads from files.
-
isAvailable
boolean isAvailable()Checks if the recipe system is available and ready.- Returns:
- true if recipes can be registered and queried
-
createBuilder
Creates a new RecipeBuilder instance.Convenience method for creating builders.
- Returns:
- A new RecipeBuilder
-
createBuilder
Creates a new RecipeBuilder with the specified ID.- Parameters:
id- The recipe ID- Returns:
- A new RecipeBuilder with the ID set
-
cleanupWorld
Cleans up craft tracking data for a specific world.This should be called when a game world is deleted to prevent memory leaks.
- Parameters:
worldName- The world name to cleanup
-
cleanupPlayer
Cleans up craft tracking data for a specific player.This can be called when a player leaves the server permanently to free memory.
- Parameters:
playerId- The player's UUID to cleanup
-
hasPlayerEverCrafted(UUID, String)instead.