Crafting with tables

local Table = {Stats.Item1, 1, Stats.Item2, 1, Stats.Item3, 3, Stats.Item4, 5}

local Success = 0

for i = 1, #Table do
	if Table[i]:IsA("IntValue") then
		if Table[i].Value >= Table[i+1] then
			print(Table[i].." is greater than or equal to "..Table[i+1])
			Success = Success + 1
			if Success == #Table/2 then
				print("Ok")
				Success = 0
			end
		else
			print(Table[i].." is not greater than or equal to "..Table[i+1])
		end
	end
end

This is the best I’ve came up with. I hope this is what you’re looking for.

1 Like

It doesn’t work as intended but thank you for the help

Is there any way to get specific columns in the table?

To get specific parts of a table with number indexes:

local Table = {2,2,7,9,5,6}

print(Table[3]) --prints7
1 Like

Can you explain further what you mean by “doesn’t work as intended”?

Well, the crafting doesn’t work. So in brief terms, the script doen’t work

Not the issue here; Lua automatically coerces all non-nil non-false values as truthy whenever they’re needed for logic/flow.

1 Like
local player = game.Players.LocalPlayer
local Stats = player:WaitForChild("Stats")
local Level = Stats:WaitForChild("Level")
local Item1= Stats:WaitForChild("Item1")
local Item2= Stats:WaitForChild("Item2")

local Table = {Item1, 1, Item2, 1}

local Success = 0

for i = 1, #Table do
	if Table[i]:IsA("IntValue") then
		if Table[i].Value >= Table[i+1] then
			Success = Success + 1
			if Success == #Table/2 then
				print("Ok")
				Success = 0
			end
		end
	end
end

The code works as intended when I tested it. It checks if Item1 and Item2 is greater than or equal to 1.

3 Likes

10:48:24.237 - Players.TOP_Crundee123.PlayerGui.UI.CraftingInterface.ScrollingFrame.Register:12: attempt to call method ‘IsA’ (a nil value)

Edit: Never mind I fixed it. So since I need to detect if there is enough materials to craft for a lot of things, is for i loops going to be too resource intensive(looping through tens of items with that script)

So is this script efficient?:

local player = game.Players.LocalPlayer
local Stats = player:WaitForChild("Stats")
local Level = Stats:WaitForChild("Level")
local Item1= Stats:WaitForChild("Item1")
local Item2= Stats:WaitForChild("Item2")

local Craft= {Item1, 1, Item2, 1}
local Craft2= {Item1, 1, Item2, 100}

local Success = 0

Item1.Changed:Connect(function()
	for i = 1, #Craft, 2 do
		print(i)
		if Craft[i]:FindFirstAncestor("Stats") then
			if Craft[i].Value >= Craft[i+1] then
				Success = Success + 1
				if Success == #Craft/2 then
					Success = 0
				end
			end
		end
	end
    	for i = 1, #Craft2, 2 do
		print(i)
		if Craft2[i]:FindFirstAncestor("Stats") then
			if Craft2[i].Value >= Craft2[i+1] then
				Success = Success + 1
				if Success == #Craft2/2 then
					Success = 0
				end
			end
		end
	end
-- and so on and so fourth
end)

how can I improve this?

I wouldn’t advise using dozens of loops for each craft table. I’b probably create one function that does all the work for me like such:

local player = game.Players.LocalPlayer
local Stats = player:WaitForChild("Stats")
local Level = Stats:WaitForChild("Level")
local Item1= Stats:WaitForChild("Item1")
local Item2= Stats:WaitForChild("Item2")

local Craft= {Item1, 1, Item2, 1}
local Craft2= {Item1, 1, Item2, 100}

local function VerifyRequirements(CraftTable)
    local Success = 0
    for i, v in ipairs(CraftTable) do
        if v:IsA("IntValue") then
            if v.Value >= CraftTable[i + 1] then
                Success = Success + 1
                if Success == #CraftTable/2 and i == #CraftTable then
                    print("Requirements Complete")
                elseif Success ~= #CraftTable/2 and i== #CraftTable then
                    print("Requirements Incomplete")
                end
            end
        end
    end
end

VerifyRequirements(Craft)
VerifyRequirements(Craft2)

Note:
I just realised that the previous code samples I posted did not take into account when the crafting requirements were incomplete, hence breaking the code logic. Please use this code as a reference instead of the previous ones.

2 Likes

so this script would verify the requirements whenever the item values change? Because I just need to make sure(I don’t know, but is there supposed to be a .Changed in there?)

There doesn’t need to be a Changed event in the function as it will always get the updated values upon running it.

1 Like

no, like when the item values change I want it to fire again

Just setup an event connection

local Item1= Stats:WaitForChild("Item1")
local Item2= Stats:WaitForChild("Item2")

Item1.Changed:Connect(function() VerifyRequirements(Craft) end)
Item2.Changed:Connect(function() VerifyRequirements(Craft2) end)

However, I don’t think this is very efficient if you will be having a dozen more Items so I’d create a background loop by using spawn() or while loops or coroutine or Heartbeat

Ive never used spawn() coroutine or Heartbeat before, can you explain further? May you give me an example?

Spawn

spawn(function()
    while true do
        VerifyRequirements(Craft)
        VerifyRequirements(Craft2)
        wait(0.1)
    end
end)

Coroutine

local Coroutine = coroutine.create(function()
    while true do
        VerifyRequirements(Craft)
        VerifyRequirements(Craft2)
        wait(0.1)
    end
end)

coroutine.resume(Coroutine)

While Loops

while ThisConditionIsTrue do
    VerifyRequirements(Craft)
    VerifyRequirements(Craft2)
    wait(0.1)
end

Heartbeat

RunService.Heartbeat:Connect(function()
    VerifyRequirements(Craft)
    VerifyRequirements(Craft2)
end)

I personally prefer coroutines, but it comes down to what exactly you need for what you’re coding

1 Like

Can you elaborate on the things you showed be a bit? Everything except for the while loop. Like, what does coroutine and heartbeat do?, and what is spawn? Thank you so much.

Spawn will create a function on a separate thread other than its own. Note that creating a lot of these will have some performance impacts.

Coroutine is like creating a task that you can control. You can check if that task is running, what’s currently the status and yield the task. I also think this is better in terms of controlling loops.

Heartbeat is an event that fires after physics calculations per frame

1 Like

Isn’t looping them over and over again going to cause tremendous lag?