Pick random value from a table

So there’s a table of foods(intValue) but those foods can be sold out and customers can’t order them. I made this script when customers come and only be able to pick random available food.
The problems:

  1. I don’t know how to get local player from server script since i need to get the intValue (food) that is the child of player
  2. I don’t know how to pick random value from the AvailableFood table
  3. I’m not sure I’m doing this right so far

while wait() do
local player = game.Players.LocalPlayer
local Food = {
player.burger,
player.hotdog,
player.pizza
}
for i, v in ipairs(Food) do
if v.Value >= 1 then
local AvailableFood = {v}
local ChoosenFood =
print(ChoosenFood)
–customers order the choosen food–
end
end
wait(5)
end
Thank you for help

1 Like

You can’t directly get game.Players.LocalPlayer from a server script.

So, get the player by doing a playeradded function and add a player parameter.

game.Players.PlayerAdded:Connect(function(player)
local Food = {
player.burger,
player.hotdog,
player.pizza
}
while wait(.01) do
for i, v in ipairs(Food) do
if v.Value >= 1 then
local AvailableFood = {v}
local ChoosenFood =
print(ChoosenFood)
–customers order the choosen food–
end
end
wait(5)
end
end)

I moved the table out of the while do loop to prevent some issues.
I highly recommend to stay away from while do loops that never break, it can be very costly on performance.
Instead of a while do loop, I recommend a Changed function.


To pick a random number from a table, you can use math.random.
math.random(lowest number, highest number)
So in this case,

local randomfood = math.random(#Food)

We can just say one argument in this case since if we don’t specify one argument, the first argument by default is 1.
Putting a hashtag before referencing the table gets the amount of objects in that table.

2 Likes

Is the randomfood going to print values or the name of the values? I need the value’s name so i can decrease the food value when customers order it.
I also tried to test it. I tried to print the randomfood but it always print “1” (none of the food value is 1)
Also if i use the playeradded, the script will only works when player join, not every second
Thank you for helping

game.Players.PlayerAdded:Connect(function(player)
local Food = {
player.burger,
player.hotdog,
player.pizza
}
while wait(.01) do
for i, v in ipairs(Food) do
if v.Value >= 1 then
local AvailableFood = {v}
local randomfood = Food[math.random(#Food)]
print(randomfood)
–customers order the choosen food–
end
end
wait(5)
end
end)

Oh, because it’s just picking a number, not a table value. My fault, it should be fixed in the script.

No, this script plays a while do loop when a player joins the game. The while do loop plays every .01 seconds.

1 Like
game.Players.PlayerAdded:Connect(function(player)
    	wait(5) --wait until all values loaded--
    	local Food = {
    		player.Values.burger,
    		player.Values.hotdog,
    		player.Values.pizza
    	}
    	while wait(.01) do
    		for i, v in ipairs(Food) do
    			if v.Value >= 1 then
    				local AvailableFood = {v}
    				local choosenfood = #AvailableFood[math.random(#AvailableFood)]
    				print(choosenfood)
    				--customers order the choosenfood
    			else
    				
    			end
    		end
    		wait(5)
    	end
    end)

local choosenfood = #AvailableFood[math.random(#AvailableFood)]

^This prints out “attempt to get length of a Instance value”

if v.Value >= 1 then
local AvailableFood = {v}
local choosenfood = #AvailableFood[math.random(#AvailableFood)]

^Also I don’t think this will work. If I’m not wrong, here the AvailableFood will only has 1 content at a time, starts from the 1st(burger), 2nd(hotdog), etc

Should i do this instead? (I make 2 table, the first one is the list of foods, the sec one is the “only available food”. I use table.insert and table.remove to keep updating the available food table)

game.Players.PlayerAdded:Connect(function(player)
	wait(5)
	local Food = {
		player.Values.burger,
		player.Values.hotdog,
		player.Values.pizza
	}
	local AvailableFood = {
	} --filled with food that has more than 1 value from food table, customer will randomly order from AvailableFood

	while wait(.01) do
		for i, v in ipairs(Food) do
			if v.Value >= 1 then
				table.insert(AvailableFood,v)
			local choosenfood = #AvailableFood[math.random(#AvailableFood)]
				--customers order the choosenfood
			elseif v.Value == 0 then
				table.remove(AvailableFood,v)
			end
		end
		wait(5)
	end
end)

but it prints out “invalid argument #2 to ‘remove’ (number expected, got Instance)” here:

table.remove(AvailableFood,v)

and prints “attempt to get length of a Instance value” here:

local choosenfood = #AvailableFood[math.random(#AvailableFood)]

Thank you for helping

When you are printing out the chosen food, print out their name.

print(choosenfood.Name)
1 Like

I did not take a look at the if statement yet, what are you trying to have it do?

1 Like

First. To get a random item from a table you’d use math.random(). Any one of the randoms work, but math.random() is the easiest, in my opinion, to remember.

local list = {
245,
"Hello",
"Third Element",
909,
}

local randomItem = list[math.random(1, #list)] -- Returns a random index from the table

print(randomItem)

Second, you can’t retrieve a player using LocalPlayer in a server script, just not how it works. You could hook this up to a player added event and capture the player like that. Or if this is a script within a client service, i.e StarterGui. You could just do “local player = script.Parent.Parent”, depending on it’s parents and grandparents.

2 Likes

Also, I’d recommend using events instead of loops. Best practise and everyone knows that event handling is better than looping indefinitely waiting for something to happen. Uses less memory and resources and generally looks better. Down side is you’re going to have to disconnect the events yourself, to prevent memory leaks.

1 Like

I think you want something like this try it

local player = game:GetService("Players").LocalPlayer

local Food = { -- Food variables locations
	player.burger,
	player.hotdog,
	player.pizza
}

local AvailableFood = {} --AvailableFood Table

while true do
	
	for i, v in ipairs(Food) do
		if v.Value >= 1 then -- check if there food
			AvailableFood[v.Name] = AvailableFood[v] --insert to AvailableFood	
		end
	end
	
	local ChoosenFood = AvailableFood[math.random(1,#AvailableFood)] -- Get a random food from the AvailableFood Table 
	print(ChoosenFood) -- print ChoosenFood
	wait(5)
	
	AvailableFood = {} -- reset the table
end
1 Like

invalid argument #2 to ‘random’ (interval is empty)

Also I want to know why is this error

Still doesn’t work, I think the problem is here, because its an instance value

I don’t really get what you ask…The table will only has 1 content at a time because of the while do loops. So I can’t choose random food from that table. Or it’s not what you want to know?

Yes i also want to use changed function but I don’t know how to apply that in this case since there are multiple values that has to be checked

try now this will work fine

local player = game:GetService("Players").LocalPlayer

local Food = { -- Food variables
	"burger",
	"hotdog",
	"pizza"
}

local AvailableFood = {} --AvailableFood Table

while true do

	for i, v in ipairs(Food) do
		local FindFood = player:FindFirstChild(v)
		if FindFood and FindFood.Value >= 1 then -- check if there food
			table.insert(AvailableFood, FindFood) --insert to AvailableFood	
		end
	end
	
	if #AvailableFood >= 1 then
		local RandomNumber = math.random(1,#AvailableFood) -- Get a random number from the total sum of the food
		local ChoosenFood = AvailableFood[RandomNumber] -- Get a random food from the AvailableFood Table
		print(ChoosenFood) -- print ChoosenFood
	end
	
	wait(5)

	AvailableFood = {} -- reset the table
end

Use this for the random food. Putting a hashtag there won’t work.

1 Like

So you want to know a value has been changed? You could use Quenty’s Nevermore Signal Framework but that’s most likely too advanced, uses OOP and metatables.

1 Like