Skip to content

Conversation

@manab-pr
Copy link
Contributor

@manab-pr manab-pr commented Nov 9, 2025

Summary

Adds support for dynamic recipes - recipes where the output depends on the specific items used in crafting, not just their types. Implements decorated pot crafting as the first dynamic recipe.

Changes

New DynamicRecipe interface (recipe/dynamic.go)

  • Introduces DynamicRecipe interface with Match(input []Item) (output []item.Stack, ok bool) method
  • Allows recipes to examine the actual crafting grid and produce custom outputs
  • Implements DecoratedPotRecipe that creates pots with pottery sherd/brick patterns

Decorated pot crafting logic

  • Validates diamond/plus pattern (slots 1, 3, 5, 7 in 3x3 grid)
  • Accepts any items implementing PotDecoration() (sherds or bricks)
  • Encodes decorations into pot NBT in correct order: [back, left, front, right]
  • Each crafted pot preserves the unique pattern of sherds used

Handler integration (session/handler_crafting.go)

  • Added tryDynamicCraft() fallback when static recipes don't match
  • Validates ingredient counts to prevent item duplication
  • Caps timesCrafted to minimum available stack count across slots
  • Supports both CraftRecipe and AutoCraftRecipe actions

Recipe registration

  • Added DynamicRecipes() registry function
  • Registered decorated pot recipe in vanilla recipes
  • Dynamic recipes checked after static recipes in crafting flow

Implementation details

Dynamic recipe matching:

  1. Collect all items from crafting grid (including empty slots)
  2. Try matching against each registered dynamic recipe
  3. Validate that sufficient ingredients exist for requested craft count
  4. Consume ingredients and generate outputs

Security considerations:

  • Validates minimum stack counts before consumption
  • Prevents clients from crafting more items than ingredients allow
  • Mirrors validation logic from static recipe path

Future dynamic recipes

This system enables implementation of other dynamic recipes:

  • Banner copying
  • Banner patterns
  • Firework rockets/stars
  • Book/map cloning
  • Shulker box coloring
  • Item repairing

Test plan

  • Craft decorated pot with 4 pottery sherds
  • Verify pot displays correct sherd pattern when placed
  • Mix sherds and bricks in recipe
  • Craft with invalid patterns (should fail)
  • Craft multiple pots at once
  • Test autocrafting decorated pots

Closes #592


IssueHunt Summary

Referenced issues

This pull request has been submitted to:


Copy link
Member

@TwistedAsylumMC TwistedAsylumMC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me apart from 2 minor things. Are we supposed to be sending the dynamic recipe UUIDs to the client (maybe we already do?), or does this work without them if we're not already sending them

@manab-pr
Copy link
Contributor Author

manab-pr commented Nov 15, 2025

@TwistedAsylumMC
The server doesn't need to send Dynamicrecipes (like for decorated pots ) to the client at all , as those are handled entirely server-side.
For the static recipes that are sent to the client , we are already generating a new , random UUID for each one every time they're sent . so yes we're sending dynamically generated UUIDs for static recipes ,No it won't work without them.

@TwistedAsylumMC
Copy link
Member

Alright that sounds good to me. Does the client just magically know these recipes exist?

@manab-pr
Copy link
Contributor Author

manab-pr commented Nov 15, 2025

Alright that sounds good to me. Does the client just magically know these recipes exist?

The client doesn't need to know these dynamic recipes exist in the traditional sense. That's the whole point of dynamic recipes.

For static recipes, yes - the client receives them via CraftingData packet and can show them in the recipe book.

For dynamic recipes (decorated pots, banner copying, etc.), the client has no prior knowledge of them. The player just places items in the crafting grid,
the client sends the CraftInput to the server, and the server checks:

  1. Does this match any static recipe? If yes, craft it.
  2. If not, does this match any dynamic recipe? If yes, craft it.
  3. If neither, reject the craft.

So dynamic recipes work precisely because the client doesn't know about them - they're only validated server-side when the player attempts to craft.
The UUIDs I mentioned earlier are only for the static recipes in the CraftingData packet. Dynamic recipes don't use UUIDs at all since they're never sent
to the client.

@TwistedAsylumMC TwistedAsylumMC merged commit cd2c623 into df-mc:master Nov 15, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for dynamic crafting recipes

2 participants