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

Pages: first 1234 next last
Hello. Is there a way to make the same item be accessed through different switches? For example: I want weapon 1 to be accessed in switches 1 and 2, but not in switch 3.
author=coelocanth
author=Nanjo
1) Is there an easy way to disable item categories in the script?
There isn't.
The script re-uses Window_ItemCategory, in create_category_window.
You could replace the Window_ItemCategory with your own window that has fewer options; or change the scene to not have a category window at all and jump directly in to the specific category.
But there's no built-in option for it.
I see. Coincidentally, I found my way after I submitted that post.
I tracked down the file in which the categories are handled myself when I read the "create_category_window" function, and hid the Items and Key Items categories there behind a
if $game_switches[3] != true

Naturally, I made the crafting system set that Switch when it's activated and clear it when it's no longer active, and that does seem to work nicely, though now I kinda want to center the Weapons and Armours categories, since they start on the far end left which is kinda ugly, hehe.
https://i.imgur.com/thXMjrZ.png

Any tips you could give me about that? Right now my plan is to track down the location of "add_command" and see where that takes me.

author=coelocanth
author=Nanjo
2) How can I change the sound effect that plays when you make an item?
By default it seems to be "Decision3".
I tried to comment out the 2 uses of "Sound.play_ok" and add a "RPG::SE.new("Bell2", 50, 100).play" right after, but that didn't seem to work.
This seems like the right track, you could also try Audio.se_play.
Thanks!
I tried the following and it worked nicely:
Audio.se_play('Audio/SE/Bell2', 100, 0)

However, I notice that Decision3 is still playing at the same time.
I imagine that's tied to one of the default RPGMVXA that are being used here in this crafting system?
https://streamable.com/hcojxt

On a separate note, I honestly didn't think you'd still be active seeing how the last reply before mine was from 2021.
Thank you very very much for giving me a hand here, and for making this awesome script!
It looks nice and it's really simple to use!

EDIT: Actually, instead of bothering with centering the Weapons and Armours options, would it be easier to just enter a specific mode and category?

I'm realizing I don't need to reinforce Armours per se.

So basically, is there a script I could call from within an event in a map that would open the "Crafting - Weapons" window directly?

EDIT2: I'm not exactly proud of this because it looks rather hacky, but the result looks much better InGame this way (in my personal opinion of course), so I think I'll keep it.

I basically wrote a script by copy-pasting functions from the default scripts that would allow me to merge the 4 item categories for shops into a single one if the specified Switch (in this case the 3rd) is enabled. That is, the same Switch I made this Item Crafting script of yours toggle On and Off on its own.
https://pastebin.com/ebPu7Ung

I wish I could have just made the interface enter the menu to craft weapons straight up without showing or having to choose a category at all, but I'm happy enough with this result too.
https://streamable.com/zqfffi

Thank you for everything, seriously!
author=Nanjo
1) Is there an easy way to disable item categories in the script?

There isn't.
The script re-uses Window_ItemCategory, in create_category_window.
You could replace the Window_ItemCategory with your own window that has fewer options; or change the scene to not have a category window at all and jump directly in to the specific category.
But there's no built-in option for it.

2) How can I change the sound effect that plays when you make an item?
By default it seems to be "Decision3".
I tried to comment out the 2 uses of "Sound.play_ok" and add a "RPG::SE.new("Bell2", 50, 100).play" right after, but that didn't seem to work.

This seems like the right track, you could also try Audio.se_play.
Hi! I have 2 questions.

1) Is there an easy way to disable item categories in the script?
For example, what if I don't want the Crafting window to show Items or Key Items?
I tried to look for common words that the script uses in an example project like "Key Items" though I tried to look for "keyitem", "key_item" or "key.item" too, but that didn't work out.

2) How can I change the sound effect that plays when you make an item?
By default it seems to be "Decision3".
I tried to comment out the 2 uses of "Sound.play_ok" and add a "RPG::SE.new("Bell2", 50, 100).play" right after, but that didn't seem to work.

Thanks!
Thanks for the effort.

I copied it into the original script in the place you said (replacing nothing in the original script), and upon launch I get "undefined method 'on_item_ok'"
Marrend
Guardian of the Description Thread
21781
Well, I've taken a brief look at the code. The solution that makes the most sense (given what I believe you're looking for), is to attach the process to Scene_Crafting...

class Scene_Crafting < Scene_CraftBase
  #--------------------------------------------------------------------------
  # * Item [OK]
  # remove ingredients, add new item to inventory
  #--------------------------------------------------------------------------
  alias altered_on_item_ok on_item_ok
  def on_item_ok
    altered_on_item_ok
    compare_crafting_level
  end

  def compare_crafting_level
    count = 0
    for id in 1 .. 50
      val = 431 + id
      puts(val)
      if $game_switches[val] == true
        count += 1
      end
    end
  
    craft_level = $game_variables[63]
    level_difference = craft_level - count
    
    case level_difference
    when 0
      if rand <= 0.2
        # 20% chance of level-up
        $game_switches[63] += 1
      end
    when 1
      if rand <= 0.17
        # 17% chance of level-up
        $game_switches[63] += 1
      end
    when 2
      if rand <= 0.15
        # 15% chance of level-up
        $game_switches[63] += 1
      end
    when 3
      if rand <= 0.1
        # 10% chance of level-up
        $game_switches[63] += 1
      end
    end
    # In any other case, the crafting level is either too high, or too low.
    # No way skill can increment, so no need to create additional functionality.
  end
end

...like so. Again, using a separate code-section as to allow the original script to exist untampered.

*Edit: I think there would be an error in the calculation of "level_difference", but, if that's the only error that is caused, I think I would be happy for a little while.
yes. what is the call I should put there? I tried just putting SceneManager.call(compare_crafting_level) at the end of the script (I wasn't expecting success!), and of course I got an error on loading.
Then I can experiment with putting it in different places and see if anything works.

EDIT: Was looking at posts on forums and it seems that you cannot call scripts from other scripts, only functions inside that script. So, I don't know if what I want is going to be possible.
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.
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
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.
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
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'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
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.
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
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

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.
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.
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).
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.
Pages: first 1234 next last