ITEM CRAFTING

RPG Maker VX Ace

Craft items/weapons/armor from other items

Overview
This script adds an item crafting system to the game.
Crafting recipes are set using note tags.

For example, if you wanted to be able to distil 5 potions to make a Hi-Potion, you would add this tag to the Hi-Potion item's Note:
<craft item:1:5>

And to allow a hi potion to be diluted to make 4 potions from it using the breakdown system, you would add this tag:
<craft break item:1:4>

That makes it possible to create hi-potions through the crafting menu if you have 5 potions in your inventory.

And break hi-potions into potions through the breakdown menu:

Features
  • Craft item/weapon/armour from other items/weapons/armour
  • Restrict individual recipes to require a tool
  • Hide individual recipes until the player acquires a specific item
  • Restrict the crafting system to a specific actor or class
  • Control access to the crafting system with a game switch
  • Launch the crafting system from an event instead of the menu
  • Breakdown items into components (new in 0.9.2)
  • Crafting shops - gold price for recipes (new in 0.9.4)
  • Crafting shops - use a game switch to control recipe visibility (new in 0.9.4)


Usage
To install the script, open the script editor in RPG Maker VX Ace.
Scroll to the bottom, and select a blank row between Materials and Main Process.
copy/paste the script code into the right hand editing pane.

For any item you want to be craftable, you need to add at least one craft tag to its note.
Each craft tag specified one ingredient of the recipe to create the item.
The tags are as follows:
TagMeaning
<craft item:id>Consume 1 item with the specified id
<craft weapon:id>Consume 1 weapon with the specified id
<craft armor:id>Consume 1 armor with the specified id
<craft item:id:number>Consume a number of items
<craft weapon:id:number>Consume a number of weapons
<craft armor:id:number>Consume a number of armors


With these tags, you have the basic crafting system.
If the player has the ingredients you specified, they can craft the item.

But maybe you want the player to find recipe books or need specific tools to craft items.
This is also possible with two more note tags:
TagMeaning
<craft tool:id>The tool must be in inventory to craft, but is not consumed
<craft recipe:id>The recipe item must be in inventory, or this item will be hidden from the crafting menu


These are pretty similar in function, which one to use depends if you want the player to be able to see the recipe or not.

If you want to use item breakdown as well as crafting, the tags are similar:
TagMeaning
<craft break item:id>Give 1 item with the specified id
<craft break weapon:id>Give 1 weapon with the specified id
<craft break armor:id>Give 1 armor with the specified id
<craft break item:id:number>Give a number of items
<craft break weapon:id:number>Give a number of weapons
<craft break armor:id:number>Give a number of armors
<craft break tool:id>The tool must be in inventory to breakdown this item
<craft break recipe:id>The recipe item must be in inventory, or this item will be hidden from the breakdown menu


Finally, do you want the crafting menu to be available all the time?
If not, there are restrictions you can set by editing the configuration variables at the top of the script.
You should use the IDs from your game database.
VariableEffectDefault
MENU_COMMANDAddto the game menutrue
MENU_COMMAND_TEXTName of the menu commandCrafting
MENU_COMMAND_ENABLEAlways enable the menu commandtrue
MENU_COMMAND_SWITCHEnable the menu, if a switch is on0 (disabled)
MENU_COMMAND_ACTOREnable the menu if a specific actor in the party0 (disabled)
TEXT_INGREDIENTS_TITLEHeading for the ingredients windowIngredients:
TEXT_INGREDIENTS_TOOLSHeading for tools in the ingredients windowTools:
TEXT_INGREDIENTS_PRICEHeading for price in the ingredients windowTools:


Configuration for the breakdown system follows the same pattern, in the "module CRAFT_BREAK" section.
It is therefore possible to enable only one system, or have different conditions to enable each one.

Crafting shops

Perhaps you want to have crafting performed at a shop?
Perhaps you want different shops to be able to craft different things?

Both of these are now possible.
First, we need to add note tags to the items:
TagMeaning
<craft gold:amount>Price to craft this item
<craft break gold:amount>Price to break down this item
<craft switch:id>Show this recipe only if the game switch is ON
<craft break switch:id>Show this recipe only if the game switch is ON


If you want the same items to be craftable at every shop, you can ignore the switch.
However the switch lets you make a blacksmith, alchemist, etc, each of which can craft different items.
Switches can also be used to enable new items as the player progresses through the game. If you specify multiple switches in a recipe, all of them must be on.
(note that <craft switch> and <craft recipe> perform the same function, so you could use switches exclusively if you don't like using key items)

To launch the crafting from a shop event, you will need to use a script call:
SceneManager.call(Scene_Crafting)
Fiber.yield


And the equivalent for calling breakdown from an event:
SceneManager.call(Scene_Craft_Breakdown)
Fiber.yield


Here is an example of a blacksmith's shop event:


I have given the halberd these notes:
<craft weapon:1>
<craft weapon:13>
<craft gold:100>
<craft switch:10>

And in the game, it looks like this:

Posts

author=andreasaspenberg
is it possible to find a demo of this somewhere so that i can see it in action?
i have looked at it and it is good. i have one question however. is there a way to bind things to specific classes?(like only guns being craftable by for example a gunner)

In the game I used this in, one class had a skill which launched the craft through the event system.
I think you're asking for the available recipes to be restricted by the classes of the active party members though.
Without modifying the script, you could use the tool tag on a key item that's added at the same time as the party member (e.g. "gunsmith's toolkit"), or the switch tag with a global switch.
With modifications, adding more notetags like <class:id> or <actor:id> and checking the party members would be the way to go.
author=Beledal
This is a very well made, easy to follow script. However, I'm having trouble understanding how to develop recipes. I want to combine random items to make certain potions. Can anybody give me or point me to a step-by-step tutorial on making recipes with this script?


A basic example of a potion with 2 ingredients:
IDNameNotes
0034Ointment
<craft item:63>

<craft item:65>
0063Bug wing
0065Slime


As a crafting system, this is assembly from known recipes.
If you wanted the sort of system in survival sandbox games or alchemy in elder scrolls where you combine ingredients and either get something useful or garbage, this is probably not the right script.
author=bparlor
This looks SO AWESOME! Any plans to convert this script to RPG Maker MV? It would be just the thing for a game I'm working on!


I just got MV in a steam sale. As it uses javascript not ruby, it would need to be re-implemented.
I'll consider it, but I see there are a few crafting plugins out there already.
MV plugins at least look easier to configure for the user than VXace scripts.
Having looked at what's out there, Yanfly's "Item Synthesis" and "Item Disassemble" plugins already provide this function for MV.
Really enjoying using this script.

I want to make it so that my blueprints/recipes have levels. A level 5 Smith can't make an item using a blueprint higher than level 5. Is there a way to have a chance of leveling up each time you craft an item? I don't want to add that to the event because you could feasibly just use the furnace and not attempt to make anything.

I don't think this functionality is coded into the script, but maybe there's a way of using switches? My Smithing Level is simply a series of switches (so Level 1 is switch #421, Level 2 is #422 and so on). Would be good to either add a number to a variable each time you craft something, and when that number reaches a certain value, the level increases (turns next level switch on), or to have a random chance of turning the next switch on each time you craft.

Currently, you can't use a blueprint until the appropriate level switch is on (using craft switch:x), but I can't think of a way to actually turn those switches on after crafting.

Many thanks for any ideas/suggestions!
Hi gsuk,

To extend the script to do something more after successfully crafting an item, you could alias and override thus:

class Scene_Crafting < Scene_CraftBase
  #--------------------------------------------------------------------------
  # * Item [OK]
  # remove ingredients, add new item to inventory
  #--------------------------------------------------------------------------
  alias gsuk_on_item_ok on_item_ok
  def on_item_ok
    gsuk_on_item_ok # call original function
    # extra stuff here
    print("do a thing\n")
    if rand < 0.1
      # 10% chance
    end
  end
end


A <craft variable:id:level> tag would have helped you, but I didn't have a reason for it at the time of writing this script.
Hi Coelocanth!

Thanks for getting back soooo quickly – I wasn't sure if anyone would respond. I'm really not great with the whole scripting thing (understatement), so I have a couple of questions, if you'll indulge me:

1. Where do I put this script? Separately, or somewhere in the original script?
2. # extra stuff here
print("do a thing\n")
I don't know what extra stuff I'd need to put there, and how to add the 10% chance of changing the switches. I guess I'd need some kind of branch that checks which level switch is on and then turns the switch+1 on if the 10% chance hits (but not past the max level).

Thanks for any help!
1. It would be a new script underneath the crafting script.
2. To turn a switch on/off:
# id is the switch number
$game_switches[id] = true # turn on
$game_switches[id] = true # turn off

To test a switch is on/off:
if $game_switches[id]
  # switch is on
else
  # switch is off
end


To loop over a range of switches and turn on the first one that is not on:
for id in 11 .. 20 do
  unless $game_switches[id]
    $game_switches[id] = true
    break
  end
end


Any print statements go to the debug window which you can turn on for test play using the "game" menu.

The help file for VXA includes a ruby reference in the RGSS section.
Perfect!

I actually changed it a bit so it uses a variable instead of switches to track the level:

class Scene_Crafting < Scene_CraftBase
#--------------------------------------------------------------------------
# * Item
# remove ingredients, add new item to inventory
#--------------------------------------------------------------------------
alias gsuk_on_item_ok on_item_ok
def on_item_ok
gsuk_on_item_ok # call original function
# extra stuff here
print("do a thing\n")
if rand < 0.1 # 10% chance
$game_variables = $game_variables + 1 # add 1 to lvl
end
end
end

Thanks a lot for the help! I just need to figure out a way to display a message on level up. Will end up doing it through a complicated event, probably. :D

EDIT: I figured out the message display.

There's one last thing that I'd like to do, but I feel like it would be taking advantage a little to ask, so feel free to say it's not possible / too much effort, but a problem I now have is that the player can level up by crafting any item. Ideally, the player wouldn't be able to increase their level by crafting an item that is too simple for them. The items can't be assigned crafting levels as such in the script, but they do require certain switches to be on in order to craft the item (in my case, the player has to have a certain crafting level in order to be able to make various items). I don't know if it's possible to set it up somehow that if a player's crafting level is, say, 10, they can't increase their skill by crafting a level 1 item (requiring the lowest level skill switch being on).
Your code has been mangled by bb tags, you should use "code" bb tags to wrap it when posting on rmn.

However, to answer your question, use an if condition that checks the current level (your game variable) against
item.crafting_switches
, which is a list of the switch IDs you set in the requirements.
Sorry about the mangled code.

How would I make the condition to check to level against the item/crafting_switches?

For example:

To make a Bone Shield, you need to be have crafting level 2. The item is tagged with <craft switch:422> which is the level 2 switch. If this switch is off, the item doesn't appear in the crafting window.
I also have a variable ($game_variables) which ranges from 1–50 to designate the player's crafting level. When the variable is 2, the switch 422 turns on, making the Bone Shield item available in the crafting window. When the variable is 3, switch 423 turns on (making level 3 items appear), and so on.

At level 1, the player can currently only craft level 1 items, which is fine. But when the player reaches, say, level 10, I don't want them to be able to continue increasing their crafting level by making level 1 items.

If the player has crafting level 10, all ten switches (421–431) are ON, because they can still craft items of any level 10 or lower.

So I guess the comparison I need is something like "if the item craft level (the item.crafting_switch) is 4 or more levels lower than the player's crafting level, then skip the 10% chance of skill up.

Example:

Player crafting level is 10 (switches 421–431 are ON, and variable 63 = 10).
Item crafting level is 5 (craft switch:426 in item tag).
No chance to skill up in this case.

I don't know how I'd go about comparing a variable to a switch.
Marrend
Guardian of the Description Thread
21781
Player crafting level is 10 (switches 421–431 are ON, and variable 63 = 10).
Item crafting level is 5 (craft switch:426 in item tag).
No chance to skill up in this case.

I don't know how I'd go about comparing a variable to a switch.

I think we might be able to take the previously mentioned loop...
for id in 11 .. 20 do
  unless $game_switches[id]
    $game_switches[id] = true
    break
  end
end

...and revise it somewhat?

count = 0
for id in 421 .. 431 do
  if $game_switches[id]
    count += 1
  end
end
if count == 11 && $game_variables[63] == 10
  # All crafting level 10 switches are on, and the crafting level variable is 10.
  # I'm not sure how this is all set up, but, the idea in my head would be to do call a separate script that does a 'case' clause
  # on the item's crafting level, where the 'else' case would be the minimum point at which no skill improvement would occur?
end

Would this work for any crafting item of any level? your example shows switches 421–431, so would that only work for level 10?

I think I might be making this more complicated / requiring heavy scripting.
Marrend
Guardian of the Description Thread
21781
That particular example was specifically checking switches 421-431. I think a more generic version might look something like...

def compare_crafting_level(level)
  count = 0
  for id in 0 ... 10 do
    val = 320 + id + level
    if $game_switches[val] == true
      count += 1
    end
   end
   craft_level = $game_variables[63]
   level_difference = craft_level - count
   case level_difference
     when 0
       # Character crafting level is the same as item level; normal skill gain.
     when 1
       # Character crafting level is one level higher than item's level; some skill gain.
     when 2
       # Character crafting level is two levels higher than item's level; slight skill gain.
     when 3
       # Character crafting level is three levels higher than item's level; minimal skill gain.
     else
       # Character crafting level is four levels higher than item, or is lower; no XP gain from either being to
       # hard/impossible, or too skilled.
     end
  end
end

...this. Or some-such. Don't have the time to double-check it at the moment.
Thanks! I'm trying it at the moment. Currently, nothing is happening (I'm not getting skill ups), but I think it's because of the "for id" and "val" parts at the top – I don't know which values I should substitute in here depending on the switches/variables I'm using.
Marrend
Guardian of the Description Thread
21781
Looking at my code above, I think I screwed up with how "val" would be calculated. Like, the idea in my head was that there's 10 game-switches appropriated for each crafting level. My logic was that, going backwards, the first switch for crafting level 1 would be $game_switches[321], and would increment by from there. So, I think that particular line it might look more like...

val = 320 + id + (level*id)


...this? What you might want to do to double-check things is use a "puts" line...

val = 320 + id + level
puts(val)
if $game_switches[val] == true
  count += 1
end
# Rest of script.


...to output the value of "val" into the debugging window, and see which game-switch it's actually looking at. There's a "Show Console" tickbox in the "Game" menu that enables/disables that window. Personally speaking, calling it a "console" is a little disingenuous to me, as, I don't think you can actually input data into it (outside of a "puts" command), but, that's being a tad technical.
Thanks. I tried that, putting the values in, but still nothing happening. the puts code isn't displaying anything in my console and the variable is not increasing.

I changed the value of 320 to 431, as that's the first of my level variables. 431–481 is the range (50 levels), but even if I can just get it working for the first level, I can adapt that! I changed to 'for id in' part from 0 ... 10 to 0 ... 50. Why does it start at 0 (I tried 1, and still nothing happens)?

the rest of my script is just the original "if rand" part that I used before that worked (increases the variable 63 by 1 with a random chance).

My whole script:


https://imgur.com/a/5V3n8W8

Marrend
Guardian of the Description Thread
21781
Why does it start at 0 (I tried 1, and still nothing happens)?


The "for" statement is a loop/iterator. So, for this example, the statement "for id in 1 .. 50", it replaces instances of the variable "id" within the "for" statement with a number 1 to 50. At least, that's my understanding of how it's supposed to work.

As for the other issue...

I tried that, putting the values in, but still nothing happening.


...may I ask where/how you are calling the function "compare_crafting_level"? For what little it's worth, the test-event I generally run to debug stuff looks something like...


Show Message: Yo! What's up?
Script: test


def test
  compare_crafting_level
  #SceneManager.call(Scene_Test)
end


...this.
All I have is the script in my list below the original crafting script. I didn't know I had to call it. How do I do that? The original crafting script is called with a script in an event: SceneManager.call(Scene_Crafting)

I feel like the compare_crafting_level script has to run alongside that so that it can work for every instance of crafting (you can craft several items at once). Do I need to call it within the original script somehow?
Marrend
Guardian of the Description Thread
21781
I would believe that the context of the script-call would ultimately be inserted somewhere within Scene_Crafting. Probably during the process where the player crafts? You'll have to forgive me for not knowing, exactly, where that is.

However, for what it is worth, I would advise making a copy of the function(s) that you are editing into a separate code-section, and keep the original in tact.