Problem with crafting system

I have a problem with my crafting system. Let me show you an example for it.
I want to craft a sword.
I need 1 stick and 2 wood, but I have 0 sticks and 2 wood.
The sword is still being crafted and added to player’s backpack. That means you only need 1 ingredient required to craft the tool.

Server script:

local recipeIngredients = require(replicatedStorage:WaitForChild("Ingredients"))
replicatedStorage.CraftTool.OnServerInvoke = function(player, tool, amout)
	local inventory = player.Inventory
	local mainGui = player.PlayerGui.InventoryGui
	local inventoryGui = mainGui.Inventory
	local done = false
	for itemName, value in pairs(recipeIngredients[tool]) do
		print(itemName)
		if inventory:FindFirstChild(itemName) then
			if inventory:FindFirstChild(itemName).Value >= value then
				inventory[itemName].Value = inventory[itemName].Value - value
				inventoryGui[itemName].ItemCount.Text = inventory[itemName].Value
				done = true
				if inventory[itemName].Value == 0 then
					inventoryGui[itemName].Visible = false
				else
					inventoryGui[itemName].Visible = true
				end
			else
				print("Not enough materials")
				done = false
				end
			end
		end
	if done == true then
		local cloneTool = replicatedStorage.Items[tool]:Clone()
		cloneTool.Parent = player.Backpack
	end
	end

Module script:

	["Plank"] = {
	 ["Wood"] = 2;
	};
	["Stick"] = {
	 ["Wood"] = 1;
	};
	["IronSword"] = {
	 ["IronBar"] = 3;
	};
	["WoodSword"] = {
	 ["Plank"] = 2;
	 ["Stick"] = 1;
	};
	["BattleHammer"] = {
	 ["IronBar"] = 8;
	 ["Stick"] = 2;
	};
};
return ingredients

Local script just fires the remote function and name of the tool.

>script.Parent.Craft.MouseButton1Click:Connect(function()
	local item = "IronSword"
	local craftItem = game.ReplicatedStorage.CraftTool:InvokeServer(item)
end)

It would be easier on the eyes if there were indents

I don’t really know how to make them…

Press tab at the start of the line

Ok I will try to make it easier

1 Like

I did it but it still shows like this

Can you edit your post with the indented script

You are using a blockquote instead of a code block:

Block Quote:

local yes = "Yes:

CodeBlock:

local Yes = "Yes"

To use a code block do this ``` and `.`` but with no dot.
Do this so we can see your code better

2 Likes

Ok, the editing is done, you can see the code better

1 Like

You’re using the index, not the actual object. And you are only checking it once to make done equal to true, so the other check is more or less useless, instead of making done a bool, make it an integer. You also subtracted the stats before you can actually craft the tool, so if there were not enough sticks and enough wood for example, the sticks would go away and you get nothing. Only subtract the stats after you check it. You also should edit GUI’s in a server script. I’ve also shortened the script because you coul’ve stored inventory:FindFirstChild(itemName) as a variable to make it shorter.

local Check = 0
for itemName, value in pairs(recipeIngredients[tool]) do
	local Item = inventory:FindFirstChild(itemName)
	if Item then
		if Item.Value >= value then
			Check = Check + 1
			Item.Value = Item.Value - value
			inventoryGui[itemName].ItemCount.Text = inventory[itemName].Value
			if Item.Value == 0 then
				inventoryGui[itemName].Visible = false
			else
				inventoryGui[itemName].Visible = true
			end
		end
	end
end

if Check == #recipeIngredients[tool] then
	-- subtract stats and give tool here
end
2 Likes

Or you can,

Change that to

local done

and
add this to the beginning of the for loop:

if done == false then
	break
end

And as @VegetationBush mentioned, you should subtract the amount of items after it’s confirmed that you have the items required.

The final check:

if Check == #recipeIngredients[tool] then
--code
end

Not working, when I tried to print it, it printed 0 even when I had the required ingredients.

Try doing

["WoodSword"] = {
	 [1] = {"Plank", 2};
	 [2] = {"Stick", 1};
	};

And corresponding to that make the variable Item to

local Item = inventory:FindFirstChild(value[1])

You also have to change the variable value to value[2] to get the amount of wood or sticks it costs.

local Check = 0
for itemName, value in pairs(recipeIngredients[tool]) do
	local Item = inventory:FindFirstChild(value[1])
	if Item then
		if Item.Value >= value[2] then
			Check = Check + 1
			Item.Value = Item.Value - value[2]
			inventoryGui[itemName].ItemCount.Text = inventory[itemName].Value
			if Item.Value == 0 then
				inventoryGui[itemName].Visible = false
			else
				inventoryGui[itemName].Visible = true
			end
		end
	end
end

if Check == #recipeIngredients[tool] then
	-- subtract stats and give tool here
end

Make sure to do something similar for the client as well.

Getting error:

17:29:38.838 - ServerScriptService.ToolCraftingHandler:12: attempt to compare table and number
17:29:38.839 - Stack Begin
17:29:38.839 - Script ‘Players.xaoix00.PlayerGui.CraftingGui.Crafting.WoodSword.LocalScript’, Line 4
17:29:38.839 - Stack End

This happens both on client and server

Nvm, I figured everything out.