# Master Developer AI Prompt: Custom Recipe Plugin (Enhanced v3 - Complete)

You are a **master Minecraft plugin developer** specializing in creating polished, production-ready Spigot/Paper plugins. You excel at elegant GUI design, robust data management, version compatibility, and **deep ItemStack/NBT manipulation**.

---

## 🎯 Project: EasyCrafts - Advanced Custom Recipe Manager

Create a comprehensive Minecraft plugin that allows server administrators to create fully custom crafting recipes through an intuitive drag-and-drop GUI interface with **intelligent item data handling** and **advanced recipe management**.

---

## 📋 Core Requirements

### **Recipe System with Smart Metadata Handling**

**INPUT INGREDIENTS (Crafting Grid):**
- ✅ Can be **ANY item** with **ANY name, lore, enchants, etc.**
- ✅ Recipe matching is **FLEXIBLE** - only checks **material type** by default
- ❌ Does **NOT** require exact metadata match (unless explicitly configured)
- **Example**: If you place a diamond sword named "Excalibur" in the recipe, players can use ANY diamond sword (named or not) to craft

**OUTPUT RESULT (Red Glass Slot):**
- ✅ **ALWAYS preserves ALL metadata** exactly as saved
- ✅ Enchantments, custom names, lore, durability, CustomModelData, ALL NBT data preserved
- ✅ Players receive the **EXACT item** that was placed in the result slot
- **Example**: If result slot has a diamond sword named "Legendary Blade" with Sharpness X, players ALWAYS get that exact item

**SPECIAL CASE - Input Metadata Matching:**
- ⚙️ **OPTIONAL feature**: If input ingredient has metadata (enchants, name, lore), admin can toggle "strict matching"
- When strict matching enabled: Recipe requires EXACT item match including all metadata
- **Example with strict mode**: Recipe needs "Excalibur" diamond sword → only swords named "Excalibur" work
- Default behavior: Strict matching **OFF** (only material type matters for inputs)

---

## 🎨 GUI Design Specifications

### **Main Menu: "EasyCrafts"**
```
┌─────────────────────────────────┐
│      ✦ EasyCrafts ✦             │  ← Title with shadow effect
├─────────────────────────────────┤
│ 🟨🟨🟨🟨🟨🟨🟨🟨🟨 │  ← Row 1: Yellow stained glass (no name)
│ 🟨 [ADD] 🟨🟨 [REMOVE] 🟨 │  ← Row 2: Yellow glass + options
│ 🟨🟨🟨🟨🟨🟨🟨🟨🟨 │  ← Row 3: Yellow stained glass (no name)
└─────────────────────────────────┘
```

**Visual Style:**
- Background: Yellow stained glass panes (no item names displayed)
- Title: "✦ EasyCrafts ✦" in **gold/yellow** with shadow effect (`&6&l✦ &e&lEasyCrafts &6&l✦`)
- Theme: Elegant, luxurious gold aesthetic

**Interactive Buttons:**

**📦 ADD RECIPES** (Crafting Table icon)
- Item: Crafting Table
- Name: `&6&l⚒ &e&lAdd Recipe`
- Lore:
  ```
  &7Create a new custom recipe
  &7using the drag-and-drop builder

  &8Input: Any item type accepted
  &8Output: Exact item with all data saved

  &e▸ Click to open builder
  ```

**🗑️ REMOVE RECIPES** (Smithing Table icon)
- Item: Smithing Table
- Name: `&6&l✖ &e&lManage Recipes`
- Lore:
  ```
  &7View, edit, or delete
  &7existing custom recipes

  &e▸ Click to open manager
  ```

---

## 🛠️ Recipe Builder GUI (Add New Recipe)

### **Layout**
```
┌─────────────────────────────────────────────┐
│         ✦ Recipe Builder ✦                  │
├─────────────────────────────────────────────┤
│ ⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ │  ← Black stained glass panes
│ ⬛ [1][2][3] ⬛⬛ [RESULT] ⬛ │  ← 3x3 crafting grid + result
│ ⬛ [4][5][6] ⬛⬛  (red)  ⬛ │
│ ⬛ [7][8][9] ⬛⬛⬛⬛⬛⬛ │
│ ⬛⬛⬛⬛⬛ [MODE] [SAVE] [CANCEL] │  ← Mode toggle + actions
└─────────────────────────────────────────────┘
```

**Crafting Grid (Input Slots):**
- **9 slots** (3x3): Glass blocks (NOT glass panes) - transparent and interactive
- Players **drag and drop** items from inventory
- **Items can have any properties** (names, lore, enchants visible in GUI)
- **BY DEFAULT**: Only material type matters for matching
  - Place diamond sword with any name → accepts ANY diamond sword
  - Place enchanted pickaxe → accepts ANY pickaxe (enchanted or not)

**Result Slot (Output):**
- **Red stained glass pane** on the right side
- Players drag the **desired output item** here
- **CRITICAL**: This item's metadata is **ALWAYS preserved 100%**
- Whatever you place here is **EXACTLY** what players receive
- Instruction tooltip:
  ```
  &cDrag output item here
  &aAll properties will be saved:
  &8• Custom names & lore
  &8• Enchantments (all levels)
  &8• Durability & damage values
  &8• Custom model data
  &8• ALL NBT data preserved
  ```

**Mode Toggle Button:**
- **Item**: Comparator
- **Name**: `&e&lMatching Mode: &7Flexible` (or `&e&lMatching Mode: &7Strict`)
- **Lore**:
  ```
  &7Current: &fMaterial type only

  &7Flexible Mode:
  &8• Accepts any item of same type
  &8• Ignores names, lore, enchants

  &7Strict Mode:
  &8• Requires EXACT item match
  &8• Must have same metadata

  &e▸ Click to toggle
  ```

**Action Buttons:**

**💾 SAVE** (Green wool/concrete)
- Name: `&a&l✔ Save Recipe`
- Lore:
  ```
  &7Saves this recipe

  &aInput: Material-based matching
  &aOutput: Full metadata preserved

  &eClick to confirm
  ```

**❌ CANCEL** (Red wool/concrete)
- Name: `&c&l✖ Cancel`
- Returns to main menu without saving

---

## 🗂️ Recipe Manager GUI (Remove/Edit Recipes)

### **Layout**
```
┌─────────────────────────────────────────────┐
│      ✦ Recipe Manager ✦                     │
├─────────────────────────────────────────────┤
│ ⬛⬛⬛⬛⬛⬛⬛⬛⬛ │  ← Row 0: Black border (top)
│ ⬛🟨🟨🟨🟨🟨🟨🟨⬛ │  ← Row 1: Black border + yellow center
│ ⬛🟨[R1][R2][R3][R4][R5]🟨⬛ │  ← Rows 2-4: Recipe outputs displayed
│ ⬛🟨[R6][R7][R8][R9][R10]🟨⬛ │     (replaces yellow panes only)
│ ⬛🟨[R11][R12][R13][R14][R15]🟨⬛ │
│ ⬛🟨🟨🟨🟨🟨🟨🟨⬛ │  ← Row 5: Black border + yellow
│ ⬛⬛⬛⬛⬛⬛⬛⬛⬛ │  ← Row 6: Black border (bottom)
│ ⬛⬛⬛ [◀] [▶] ⬛⬛⬛ │  ← Navigation buttons
└─────────────────────────────────────────────┘
```

**Design Specifications:**

**Border Structure:**
- **Outer frame**: Black stained glass panes (all edges - 1 block thick)
- **Inner area**: Yellow stained glass panes (fills inside border)
- **Recipe slots**: Replace yellow panes ONLY (not black border)
- Total display area: **5 columns × 3 rows = 15 recipe slots** per page

**Recipe Display Items:**
- Each slot shows the **OUTPUT ITEM** of a saved recipe
- Items appear **exactly as they will be crafted** (with all metadata visible)
- Displays: Custom names, lore, enchantments, glowing effects, etc.
- Item tooltip shows additional info:
  ```
  &e[Recipe Name/ID]
  &7Output: &f[Item Display Name]

  &7Ingredients: &f[count] items
  &7Mode: &f[Flexible/Strict]

  &e▸ Click to edit
  &c▸ Shift+Click to delete
  ```

**Layout Pattern:**
```
Slot positions (9x6 inventory):
Row 0: [0][1][2][3][4][5][6][7][8]  ← All black panes
Row 1: [9]⬛[10]🟨[11]🟨[12]🟨[13]🟨[14]🟨[15]🟨[16]🟨[17]⬛
Row 2: [18]⬛[19]🟨→R1[20]→R2[21]→R3[22]→R4[23]→R5[24]🟨[25]🟨[26]⬛
Row 3: [27]⬛[28]🟨→R6[29]→R7[30]→R8[31]→R9[32]→R10[33]🟨[34]⬛
Row 4: [36]⬛[37]🟨→R11[38]→R12[39]→R13[40]→R14[41]→R15[42]🟨[43]⬛
Row 5: [45]⬛[46]🟨[47]🟨[48]🟨[49]🟨[50]🟨[51]🟨[52]🟨[53]⬛
Row 6: [54][55][56][57][58][59][60][61][62]  ← All black panes

Recipe slots replace yellow panes at positions:
R1=20, R2=21, R3=22, R4=23, R5=24
R6=29, R7=30, R8=31, R9=32, R10=33
R11=38, R12=39, R13=40, R14=41, R15=42
```

**Navigation Buttons:**
- **◀ Previous Page** (Arrow or similar)
  - Position: Slot 57 (bottom row, left of center)
  - Name: `&e&l◀ Previous`
  - Shows current page: `&7Page [X] of [Y]`

- **▶ Next Page** (Arrow or similar)
  - Position: Slot 59 (bottom row, right of center)
  - Name: `&e&l▶ Next`
  - Only visible if more recipes exist

**Interaction Behavior:**

**Left Click on Recipe:**
- Opens **Recipe Editor GUI** (identical to builder GUI)
- Pre-fills all ingredient slots with saved items
- Pre-fills result slot with saved output item
- Shows current matching mode
- Allows moving items around, adding/removing items
- **SAVE** button updates existing recipe
- **DELETE** button (new) removes recipe entirely

**Shift + Left Click on Recipe:**
- Shows confirmation dialog:
  ```
  &c&lDelete Recipe?

  &7This will permanently remove:
  &e[Recipe Output Name]

  &a[CONFIRM] &7| &c[CANCEL]
  ```

**Empty Yellow Slots:**
- Remain as yellow panes (no action)
- Tooltip: `&7No recipe here`

---

## 🔧 Recipe Editor GUI (Edit Existing Recipe)

### **Layout** (Same as Builder)
```
┌─────────────────────────────────────────────┐
│         ✦ Recipe Editor ✦                   │
├─────────────────────────────────────────────┤
│ ⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ │
│ ⬛ [1][2][3] ⬛⬛ [RESULT] ⬛ │  ← Pre-filled with saved items
│ ⬛ [4][5][6] ⬛⬛  (red)  ⬛ │
│ ⬛ [7][8][9] ⬛⬛⬛⬛⬛⬛ │
│ ⬛⬛⬛ [MODE] [SAVE] [DELETE] [BACK] │
└─────────────────────────────────────────────┘
```

**Key Differences from Builder:**

1. **Pre-Filled Slots:**
   - All ingredient slots (1-9) contain saved recipe items
   - Result slot contains saved output item
   - Items can be **moved, removed, or replaced**
   - Can drag new items from inventory to add/replace

2. **Additional DELETE Button:**
   - **Item**: Red concrete/wool with barrier icon
   - **Name**: `&c&l✖ Delete Recipe`
   - **Lore**:
     ```
     &7Permanently remove this recipe
     &7from the server

     &c▸ Click to delete
     ```
   - Shows confirmation before deletion

3. **BACK Button** (replaces CANCEL):
   - **Name**: `&e&l← Back to Manager`
   - Returns to recipe manager GUI without changes

4. **Modified SAVE Button:**
   - **Lore**:
     ```
     &7Save changes to this recipe

     &aUpdates existing recipe

     &eClick to confirm
     ```

**Editor Capabilities:**
- ✅ Move items between slots (drag-and-drop)
- ✅ Remove items (drag out of GUI or shift+click)
- ✅ Add new items (drag from inventory)
- ✅ Change result item (replace red glass pane item)
- ✅ Toggle matching mode
- ✅ Save updates to existing recipe
- ✅ Delete entire recipe

---

## 🔧 Technical Requirements

### **Recipe Storage System**

```java
/**
 * Recipe data structure
 */
public class CustomRecipe {
    private String recipeId;  // Unique identifier (UUID)
    private RecipeType type;  // SHAPED or SHAPELESS
    private boolean strictMatching;  // Default: false

    // Input ingredients (slots 0-8)
    private Map<Integer, ItemStack> ingredients;

    // Output result (always full metadata)
    private ItemStack result;

    // Shaped recipe pattern
    private String[] pattern;  // e.g., ["AAA", " B ", "CCC"]

    // Metadata
    private long createdDate;
    private String creatorUuid;
}
```

### **Data Persistence**

```yaml
# plugins/EasyCrafts/recipes.yml
recipes:
  "550e8400-e29b-41d4-a716-446655440000":
    type: shaped
    strict_matching: false
    created: 1234567890
    creator: "player-uuid-here"

    # Ingredients stored as material type (flexible mode) OR full serialization (strict mode)
    ingredients:
      0:
        material: DIAMOND
      1:
        material: DIAMOND
      4:
        material: STICK

    # Result ALWAYS stores full serialization
    result:
      serialized: "rO0ABXNyABpvcmcuYnVra2l0LnV0aWwuaW8uV3JhcHBlcvJQR+zxEm8FAgABTAADbWFwdAAP..."
      # Full metadata preserved

    pattern:
      - "AA "
      - " B "
      - "   "

  "661f9511-f30c-52e5-b827-557766551111":
    type: shaped
    strict_matching: true

    ingredients:
      0:
        # Strict mode: full item serialization
        serialized: "rO0ABXNyABpvcmcuYnVra2l0LnV0aWwuaW8uV3JhcHBlcvJQR+zxEm8FAgABTAADbWFwdAAP..."
        # Requires exact item match

    result:
      serialized: "rO0ABXNyABpvcmcuYnVra2l0LnV0aWwuaW8uV3JhcHBlcvJQR+zxEm8FAgABTAADbWFwdAAP..."
```

### **Recipe Manager Backend**

```java
public class RecipeManager {
    private Map<String, CustomRecipe> recipes = new HashMap<>();

    /**
     * Load all recipes from storage
     */
    public void loadRecipes() {
        // Load from YAML/JSON
        // Deserialize result items (always full metadata)
        // Deserialize ingredients (material type OR full metadata based on strict mode)
    }

    /**
     * Save recipe to storage
     */
    public void saveRecipe(CustomRecipe recipe) {
        // Generate UUID if new
        // Serialize result item (always full)
        // Serialize ingredients (material only unless strict mode)
        // Write to YAML/JSON
    }

    /**
     * Update existing recipe
     */
    public void updateRecipe(String recipeId, CustomRecipe newRecipe) {
        // Keep same UUID
        // Update all fields
        // Re-serialize items
        // Save to storage
    }

    /**
     * Delete recipe
     */
    public void deleteRecipe(String recipeId) {
        recipes.remove(recipeId);
        // Remove from YAML/JSON
        // Unregister from Bukkit recipe system
    }

    /**
     * Get paginated recipe list for GUI
     */
    public List<CustomRecipe> getRecipesForPage(int page, int itemsPerPage) {
        // Return 15 recipes per page
        // Sorted by creation date or name
    }
}
```

### **GUI Navigation System**

```java
public class RecipeManagerGUI {
    private static final int ITEMS_PER_PAGE = 15;
    private static final int[] RECIPE_SLOTS = {
        20, 21, 22, 23, 24,  // Row 2
        29, 30, 31, 32, 33,  // Row 3
        38, 39, 40, 41, 42   // Row 4
    };
    private static final int[] BORDER_SLOTS = {
        // Top row
        0, 1, 2, 3, 4, 5, 6, 7, 8,
        // Sides
        9, 17, 18, 26, 27, 35, 36, 44, 45, 53,
        // Bottom row
        54, 55, 56, 57, 58, 59, 60, 61, 62
    };
    private static final int[] YELLOW_SLOTS = {
        10, 11, 12, 13, 14, 15, 16,  // Row 1 inner
        19, 24, 25,  // Row 2 sides
        28, 34,  // Row 3 sides
        37, 43,  // Row 4 sides
        46, 47, 48, 49, 50, 51, 52  // Row 5 inner
    };

    public void openManagerGUI(Player player, int page) {
        Inventory inv = Bukkit.createInventory(null, 54, "✦ Recipe Manager ✦");

        // Fill black border
        ItemStack blackPane = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
        ItemMeta blackMeta = blackPane.getItemMeta();
        blackMeta.setDisplayName(" ");
        blackPane.setItemMeta(blackMeta);
        for (int slot : BORDER_SLOTS) {
            inv.setItem(slot, blackPane);
        }

        // Fill yellow inner area
        ItemStack yellowPane = new ItemStack(Material.YELLOW_STAINED_GLASS_PANE);
        ItemMeta yellowMeta = yellowPane.getItemMeta();
        yellowMeta.setDisplayName(" ");
        yellowPane.setItemMeta(yellowMeta);
        for (int slot : YELLOW_SLOTS) {
            inv.setItem(slot, yellowPane);
        }

        // Load recipes for this page
        List<CustomRecipe> recipes = recipeManager.getRecipesForPage(page, ITEMS_PER_PAGE);

        // Place recipe output items in slots (replacing yellow panes)
        for (int i = 0; i < recipes.size() && i < RECIPE_SLOTS.length; i++) {
            CustomRecipe recipe = recipes.get(i);
            ItemStack displayItem = recipe.getResult().clone();

            // Add tooltip lore
            ItemMeta meta = displayItem.getItemMeta();
            List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
            lore.add("");
            lore.add("§7Ingredients: §f" + recipe.getIngredients().size() + " items");
            lore.add("§7Mode: §f" + (recipe.isStrictMatching() ? "Strict" : "Flexible"));
            lore.add("");
            lore.add("§e▸ Click to edit");
            lore.add("§c▸ Shift+Click to delete");
            meta.setLore(lore);
            displayItem.setItemMeta(meta);

            inv.setItem(RECIPE_SLOTS[i], displayItem);
        }

        // Add navigation buttons
        // ... previous/next page buttons ...

        player.openInventory(inv);
    }
}
```

### **Input Ingredient Matching**

```java
/**
 * Check if item matches recipe ingredient
 * DEFAULT: Only material type matters
 * STRICT MODE: Full metadata comparison required
 */
public boolean ingredientMatches(ItemStack playerItem, ItemStack recipeIngredient, boolean strictMode) {
    if (playerItem == null || recipeIngredient == null) return false;

    // Always check material type first
    if (playerItem.getType() != recipeIngredient.getType()) return false;

    // If strict mode is disabled (default), material match is enough
    if (!strictMode) {
        return true; // Player can use ANY item of this material type
    }

    // STRICT MODE: Full metadata comparison
    return itemsExactlyMatch(playerItem, recipeIngredient);
}
```

### **Output Result Preservation**

```java
/**
 * Serialize output ItemStack with ALL metadata preserved
 * This ALWAYS preserves: enchantments, lore, names, durability,
 * CustomModelData, and ALL NBT data
 */
public String serializeResultItem(ItemStack item) {
    try {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
        dataOutput.writeObject(item);
        dataOutput.close();
        return Base64.getEncoder().encodeToString(outputStream.toByteArray());
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}
```

### **Version Compatibility**
```java
// Detect Minecraft version and adapt features
if (version >= 1.20) {
    // Enable autocrafter support
    registerAutocrafterRecipes();
} else {
    // Use legacy crafting mechanics
    registerLegacyCraftingRecipes();
}
```

---

## 🎭 Polish & Details

### **GUI Enhancements**
- Use **Unicode symbols** sparingly (✦, ⚒, ▸, ✔, ✖, ◀, ▶)
- **Avoid excessive bold text**
- Shadow effects on titles: `&6&l✦ &e&lEasyCrafts &6&l✦`
- Consistent color scheme across all GUIs

### **User Experience**
- Sound effects:
  - `BLOCK_NOTE_BLOCK_PLING` on successful save
  - `ENTITY_ITEM_PICKUP` on item drag
  - `UI_BUTTON_CLICK` on GUI navigation
  - `BLOCK_ANVIL_LAND` on recipe deletion
- Visual feedback when items placed/removed
- Smooth transitions between GUIs
- Clear tooltips on all interactive elements

### **Performance**
- Cache recipe lookups
- Lazy-load recipes (don't load all at once)
- Efficient pagination system
- Async file I/O for save operations

---

## 🔍 Testing Checklist

✅ **Recipe Builder**:
- Can create new recipes with drag-and-drop
- Mode toggle works correctly
- Save creates new recipe file
- Cancel returns without saving

✅ **Recipe Manager**:
- Displays output items correctly with all metadata visible
- Pagination works (15 items per page)
- Black border maintains structure
- Only yellow panes get replaced with recipe items
- Empty slots remain yellow panes

✅ **Recipe Editor**:
- Opens with pre-filled recipe data
- Can move items around
- Can add/remove items
- Can change result item
- Save updates existing recipe
- Delete removes recipe entirely
- Back button returns to manager

✅ **Matching Logic**:
- Flexible mode accepts any material type
- Strict mode requires exact match
- Output always preserves metadata

✅ **Persistence**:
- Recipes save to file correctly
- Recipes load on server restart
- Recipe edits persist
- Recipe deletions persist

---

## 📦 Deliverables

1. **Plugin JAR** compatible with Spigot/Paper 1.13+
2. **Source code** with comprehensive documentation
3. **config.yml** with GUI customization options
4. **README.md** with:
   - Setup guide
   - Recipe creation tutorial
   - Recipe management guide
   - Troubleshooting section
5. **Permissions setup** guide:
   - `easycrafts.admin` - Create/edit/delete recipes
   - `easycrafts.use` - Craft custom recipes

---

## ⚠️ CRITICAL REMINDERS

1. **Recipe Manager GUI**: Black border, yellow interior, recipes replace yellow panes ONLY
2. **Slot positions**: Follow exact layout (15 recipe slots in 5×3 grid)
3. **Recipe display**: Show OUTPUT item with all metadata visible
4. **Editor functionality**: Pre-fill all slots, allow full editing
5. **Delete confirmation**: Always confirm before deletion
6. **Navigation**: Support pagination for many recipes
7. **Metadata preservation**: Output ALWAYS preserves everything
8. **Flexible matching**: Input defaults to material-type only

---

**Begin development with the recipe storage and manager system. Build the GUI navigation system next, ensuring the black/yellow border layout is pixel-perfect. Then implement the editor functionality with pre-filling and editing capabilities. Test thoroughly with multiple recipes to ensure pagination and editing work seamlessly.**