Skip to content

Otaku17/Crafting_psdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Crafting System (Advanced Recipes & Unlock Logic)

Modern crafting system for Ruby / Pokémon SDK projects
Fully configurable JSON recipes + advanced unlock logic + UI integration


Installation / Update

  1. Download Crafting.psdkplug

  2. Place the plugin in your project/scripts:

    Crafting.psdkplug
    
  3. Run this command at the root of your project:

    .\psdk --util=plugin load
  4. Configure crafting settings:

    Data/configs/crafting_config.json
    

Open Crafting UI

# Show all categories (with :all tab)
GamePlay.open_craft_system_ui

# Show only specific categories (with :all tab)
GamePlay.open_craft_system_ui([:ball, :medical])

# Show a single category (no :all tab)
GamePlay.open_craft_system_ui([:tm])

The "All" tab appears automatically when 2 or more categories are passed.
Passing a single category hides the "All" tab — no extra configuration needed.

You can call this from:

  • Events
  • NPC interactions
  • Menus
  • Scripts

CONFIGURATION

All crafting data is defined in:

Data/configs/crafting_config.json

Categories

You can define custom recipe categories:

"categories": [
  { "all": 3 },
  { "ball": 4 },
  { "medical": 5 },
  { "tm": 6 }
]
Field Required Description
category_name Internal symbol used by recipes
index_csv CSV/UI index reference

You can add unlimited categories.

Example:

{ "legendary": 7 }

Then assign it inside a recipe:

"category": "legendary"

RECIPE STRUCTURE

"poke_ball": {
  "ingredients": {
    "red_apricorn": 2
  },
  "result": "poke_ball",
  "quantity": 1,
  "category": "ball",
  "unlock_condition": {
    "type": "manual",
    "value": true
  }
}

Recipe Fields

Field Required Type Description
ingredients Object Required items
result String Crafted item
quantity Integer Amount produced
category String Recipe category
unlock_condition Object Unlock logic

Every recipe must have an unlock condition defined.


UNLOCK CONDITIONS

Switch

{
  "type": "switch",
  "id": 12
}
Field Required Type Description
type String Condition type
id Integer Switch ID

Variable

{
  "type": "variable",
  "id": 5,
  "value": 10
}
Field Required Type Description
type String Condition type
id Integer Variable ID
value Integer Required value

Quest

{
  "type": "quest",
  "id": 3
}
Field Required Type Description
type String Condition type
id Integer Quest ID

Recipe Dependency

{
  "type": "recipe",
  "key": "poke_ball_basic"
}
Field Required Type Description
type String Condition type
key String Recipe key

Item Requirement

{
  "type": "item",
  "item": "hammer_tool",
  "quantity": 1
}
Field Required Type Description
type String Condition type
item String Item db_symbol
quantity Integer Required quantity

Manual Unlock

{
  "type": "manual",
  "value": true
}
Field Required Type Description
type String Condition type
value Boolean Initial unlock state

Usage:

  • "value": true → Recipe is unlocked by default
  • "value": false → Recipe is locked by default

Controlled dynamically with:

CraftSystem.unlock(:recipe_key)
CraftSystem.lock(:recipe_key)

Use manual unlock for recipes that should be available from the start or controlled via scripts/events.


Pokémon Condition

Unlocks a recipe when the player owns a Pokémon matching all specified attributes.
Searches both the party and the PC storage.
All fields are optional — only those present are checked.

{
  "type": "pokemon",
  "db_symbol": "absol",
  "min_loyalty": 200,
  "min_level": 30,
  "move": "night_slash",
  "ability": "super_luck",
  "holding_item": "dusk_stone",
  "gender": 1,
  "form": 0,
  "shiny": false
}
Field Required Type Description
type String "pokemon"
db_symbol String Species db_symbol (e.g. "absol")
min_loyalty Integer Minimum loyalty/happiness (0–255)
min_level Integer Minimum level
move String db_symbol of a move the Pokémon must know
ability String db_symbol of the ability the Pokémon must have
holding_item String db_symbol of the item the Pokémon must hold
gender Integer 0 = genderless, 1 = male, 2 = female
form Integer Form index (0 = default, 29 = Mega, etc.)
shiny Boolean true = must be shiny, false = must not be shiny

Simple example — Absolite:

"absolite": {
  "ingredients": {
    "dusk_stone": 1,
    "dark_gem": 3
  },
  "result": "absolite",
  "quantity": 1,
  "category": "tm",
  "unlock_condition": {
    "type": "pokemon",
    "db_symbol": "absol",
    "min_loyalty": 200
  }
}

This unlocks as soon as the player owns an Absol with at least 200 loyalty, anywhere in their party or PC.

Pokémon conditions can be freely combined with and / or / not operators like any other condition type.


LOGICAL OPERATORS

AND / ALL

{
  "operator": "and",
  "conditions": []
}

All conditions must be met.

OR / ANY

{
  "operator": "or",
  "conditions": []
}

At least one condition must be met.

NOT / NONE

{
  "operator": "not",
  "conditions": []
}

Inverts the condition result.

Field Required Type Description
operator String Logic type (and / or / not)
conditions Array Array of conditions

Nested operators are fully supported.


Complex Example

"great_ball": {
  "ingredients": {
    "poke_ball": 1,
    "blue_apricorn": 1
  },
  "result": "great_ball",
  "quantity": 1,
  "category": "ball",
  "unlock_condition": {
    "operator": "and",
    "conditions": [
      { "type": "switch", "id": 500 },
      { "type": "variable", "id": 988, "value": 3 },
      { "type": "recipe", "key": "poke_ball" }
    ]
  }
}

This unlocks when:

  • Switch 500 is ON AND
  • Variable 988 equals 3 AND
  • Recipe poke_ball is unlocked

CRAFT SYSTEM API

Returns all recipes.

CraftSystem.all_recipes

Check if recipe is unlocked.

CraftSystem.unlocked?(:recipe_key)

Manually unlock/lock a recipe.

CraftSystem.unlock(:recipe_key)
CraftSystem.lock(:recipe_key)

Check if player can craft.

CraftSystem.can_craft?(:recipe_key, amount)

Craft a specific amount.

CraftSystem.craft(:recipe_key, amount)

Craft maximum possible amount.

CraftSystem.craft_all(:recipe_key)

Get maximum craftable amount.

CraftSystem.max_craft(:recipe_key)

Get recipe data.

CraftSystem.data_craft(:recipe_key)

UI API

Open with all categories

GamePlay.open_craft_system_ui

Open with a category filter

Pass an array of category symbols — only those categories will appear in the UI.
The :all tab is added automatically when 2 or more categories are passed.

# Two categories → :all tab shown automatically
GamePlay.open_craft_system_ui([:ball, :medical])

# Single category → no :all tab
GamePlay.open_craft_system_ui([:tm])

Useful for NPC shops, event-specific crafting tables, or locked progression menus.


AUTOMATIC STATE MANAGEMENT

The system automatically:

  • Synchronizes crafting state
  • Updates dependent recipes
  • Removes invalid states
  • Re-evaluates unlock conditions dynamically
  • Prevents circular dependency issues

BEST PRACTICES

  • Always define unlock_condition: Every recipe must have an unlock condition, use {"type": "manual", "value": true} for default availability
  • Avoid circular dependencies: Don't make Recipe A depend on Recipe B while Recipe B depends on Recipe A
  • Use manual unlocks for tutorials: Control progression with manual unlock/lock
  • Keep categories consistent: Use the same category names across recipes
  • Use nested operators for advanced progression: Combine AND/OR/NOT for complex unlock logic
  • Pokémon conditions search party + PC: No need for the player to carry the Pokémon on them

Configuration Reference

{
  "categories": [
    { "all": 3 },
    { "ball": 4 },
    { "medical": 5 },
    { "tm": 6 }
  ],
  "data": {
    "poke_ball": {
      "ingredients": { "red_apricorn": 2 },
      "result": "poke_ball",
      "quantity": 1,
      "category": "ball",
      "unlock_condition": { "type": "manual", "value": true }
    },
    "great_ball": {
      "ingredients": { "poke_ball": 1, "blue_apricorn": 1 },
      "result": "great_ball",
      "quantity": 1,
      "category": "ball",
      "unlock_condition": {
        "operator": "and",
        "conditions": [
          { "type": "switch", "id": 500 },
          { "type": "variable", "id": 988, "value": 3 },
          { "type": "recipe", "key": "poke_ball" }
        ]
      }
    },
    "potion": {
      "ingredients": { "tiny_mushroom": 2 },
      "result": "potion",
      "quantity": 1,
      "category": "medical",
      "unlock_condition": { "type": "manual", "value": false }
    },
    "super_potion": {
      "ingredients": { "big_mushroom": 1, "potion": 1 },
      "result": "super_potion",
      "quantity": 1,
      "category": "medical",
      "unlock_condition": { "type": "recipe", "key": "potion" }
    },
    "absolite": {
      "ingredients": { "dusk_stone": 1, "dark_gem": 3 },
      "result": "absolite",
      "quantity": 1,
      "category": "tm",
      "unlock_condition": {
        "type": "pokemon",
        "db_symbol": "absol",
        "min_loyalty": 200
      }
    }
  }
}

License

Free to use, modify and distribute.


Credits

Made with ❤️ for Pokémon SDK & Ruby projects.

About

PSDK plugin adding a modern crafting system inspired by Pokémon Legends: Arceus and Pokémon Scarlet / Pokémon Violet.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages