simple crafting system

Started by
21 comments, last by imontheverge7 9 years, 6 months ago
Im trying to create a simple crafting system for my game. I havent come up with anything useful yet though. I was thinking that each time i pick up and item, i loop through my inventory and set a bool value to true. So if i need three items to create another, and i have them all in my inventory, an option will appear to make the item.

Does this make sense? Or is there an easier way to do this?
Advertisement

First of all, there would be a way to 'invoke' said option, right? Because having it pop up automatically every time a certain combination appears in your inventory could annoy the player. Of course, if your game is a puzzle game which main mechanism is combining objects, then you could. But in a standard RPG/adventure game, the player must do a certain action to open that option. Perhaps by pressing a certain button, or using a ingame forge, etc.

If so, then I probably would have a list of some kind (an array maybe, or a key-value pair, or whatever) representing my inventory. I'd also make a 'reciple' or 'plan' object for each ingame item the player could currently craft. Every time the player 'invoke' the craft option, each 'recipe' objects would see through the inventory to see if the items needed to craft it are there. If yes, mark the 'recipe' as available, and move on to the next, until all currently known 'recipe' has been checked. This might sound slow, but it doesn't matter much, since the player won't 'invoke' the option that often anyway.

For now, im just having the console write a line when all the items for a certain recipe are in my inventory, just until i know the crafting system works.

I have a list of inventory slots. The slot contains a parameter Item. So i can get my item from each slot.

How would i create a recipe for an item? I can use a bool value to determine if the object can be crafted but i dont understand how i would check each item in the inventory against the recipe

Personally Ive always created a recipe object that at its core has the inputs and outputs. I can then just have a list of recipes (initially at least). This basically goes through every recipe and the players entire inventory for each, so don't plan to use it every frame or such (i.e. I don't have this bool thing of yours, since there is generally no need).


class ItemStack
{
    Item item;//reference to an item type, e.g. sand, glass, etc.
    int quantity;//the number of units in this stack
};

class Recipe
{
    List<ItemStack> inputs;//This can assume that each ItemStack has a unique item
    ItemStack output;//could be extended to List<ItemStack> outputs, but makes things a bit more complex and is a rarer feature/requriement

    //Goes through inputs and sees if inventory contains everything
    //you may also want to check there is space for the output
    //this is used to show in the UI what items the player is currently able to craft
    bool canCraft(Inventory inventory);

    //Craft the item, checks canCraft again to sure, removes all the inputs from inventory, and puts the output in the inventory
    void craft(Inventory inventory);
};
List<Recipe> recipes;//all the recipes...

The other nice thing about this is that it becomes really easy to add and modify recipes (no new code), and its even easy to load them from a file

I like the idea of having a RecipeItem class which holds variables Item and Amount, not unlike your itemstack class. My next problem is creating the actual recipe for an item. Say i have an item that needs a rock and twig. How do i store what that item needs in that items recipe?

Edit: i missed your list of ItemStacks. So i could use a list for each recipe. Great!!

I have always disliked crafting system where you supposedly have to discover a recipe to use it (=look it up on the wiki because theres no logic to the crafting ingredients required to make something)

So I personally would prefer a very transparent crafting system. Basically an ingame list of all craftable items, structured logically. And highlight items you might want to craft (relevant to current situation), AND items you can craft or almost can craft (you have the ingredients in inventory).

o3o

So I'm gonna post what I have so far. I've used the ideas you guys have posted and for now I'm just writing a line in the console when all the items I have in my inventory can make hammer. I've set a breakpoint and all the variables are initialized, and the lists are populated as they should be. The only problem is that nothing is being written in the console, so I'm missing something here.


    public class RecipeItem
    {
        public Item Item;
        public int Amount;

        public RecipeItem(Item item, int amount)
        {
            this.Item = item;
            this.Amount = amount;
        }
    }

public class ItemRecipe
    {
        public List<RecipeItem> RecipeItems;

        public bool CanCraft;

        public bool CheckForItemsNeeded(Player player)
        {
            foreach (InventorySlot slot in player.PlayerInventory.itemSlots)
            {
                foreach (RecipeItem item in RecipeItems)
                {
                    if (slot.item == item.Item)
                        CanCraft = true;
                }
            }
            return false;
        }

        //in order to create a hammer, one rock, one twig, and one vine is needed
        public class HammerRecipe : ItemRecipe
        {
            public HammerRecipe()
            {
                RecipeItems = new List<RecipeItem>();
                RecipeItems.Add(new RecipeItem(new Twig(), 1));
                RecipeItems.Add(new RecipeItem(new Vine(), 1));
                RecipeItems.Add(new RecipeItem(new Rock(), 1));

                CanCraft = false;
            }
        }

Crafting system class


 private void LoadCraftingList()
        {
            CraftingList = new List<ItemRecipe>();

            CraftingList.Add(new survival.ItemRecipe.HammerRecipe());
        }

        public void CheckForAvailableCrafts(Player player)
        {
            foreach (ItemRecipe recipe in CraftingList)
            {
                foreach (InventorySlot slot in player.PlayerInventory.itemSlots)
                {
                    recipe.CheckForItemsNeeded(player);

                    if (recipe.CanCraft == true)
                    {
                        Console.WriteLine("true");
                    }
                }
            }
        }

"class RecipeItem"

My main thought on this is there is nothing here specific to a recipe. Why not just have it as a generic Item & Amount class?

"public bool CanCraft;"

What is this?

"public bool CheckForItemsNeeded(Player player)"

Appears to be wrong. Should it not return true if the player has all the items, and false otherwise?

Currently it returns false always, and sets CanCraft to true if the player has any required item (rather than all), and regardless of quantity.

"slot.item == item.Item"

Not sure what language you are using, but since your using types/objects, it is likely that == here is not going to do what you want, since I suspect it is comparing specific instances of an item, not the type of item. e.g. in Java you should use "item.Item.equals(slot.item)" (and override Item.equals appropriately), or if you only care about the types (not the data in the instances), use "item.Item.getClass() == slot.item.getClass()".

"public class HammerRecipe : ItemRecipe"

Personally id prefer to avoid the subclass...

"CheckForAvailableCrafts"

Makes even less sense. You start off well by iterating over the crafting list, by why iterate the inventory? CheckForItemsNeeded should already be taking care of that, your just calling it multiple times for no reason.

"if (recipe.CanCraft == true)"

Like I said, why does CanCraft exist? Use the return value of CheckForItemsNeeded.

1) i created that class so its easier to make new recipes and keep the recipe and item seperate, it was easier for me to understand that way :p

2) That variable is there because...i think i left it there while trying out something else and didnt remove it? I dont really nees it.

3/)4Im trying to return true if all the items are matching the items in the recipe. Im using c# and comparing each Item that is in the recipe and inventory.

5)You're right on this one.

I think my problem here is that I'm not comparing my InventorySlot list to my RecipeItem list correctly, but i may be wrong

Just be sure you're not "overcoding" things. You don't always need an elaborate class or several functions to handle something that could, technically, be stored in a handful of variables. I'm no expert, but the way I see it is that you need to ask what the computer is actually, at the end of the day, doing that produces the effect (or illusion, rather) of crafting. Technically, there's no crafting taking place here, it just emerges into that when certain things render according to certain conditions.

My two cents (rewrote this reply for clarity).

This topic is closed to new replies.

Advertisement