I’ve been trying to make a queue system for my game recently, got it working but not in an efficient way. Let’s say that 4 players enter the queue and there are 3 “servers/cashiers”, the first 3 players get their order and the 4th waits until one of the servers are available. I tried doing that, but only 1 cashier is used at a time. Here’s what I’ve tried doing for the queue:
local prompt = script.Parent
local restaurant = prompt.Parent.Parent
local queue = {}
local ordered = {}
prompt.Triggered:Connect(function(p)
if not table.find(ordered, p) then
game.ReplicatedStorage.events.queuePos:FireClient(p, #queue + 1) -- shows the player their current position on the queue
table.insert(queue, p) -- adds player to queue
table.insert(ordered, p) -- prevents player from ordering twice at a time
end
end)
while wait() do
if queue[1] then
for _, c in pairs(restaurant.cashiers:GetChildren()) do -- for better understanding, c in this case is the cashier, they all have 2 bools and a controller script, the bools are available (bool) and attending (object
if c.available.Value then
c.available.Value = false
c.attending.Value = queue[1]
table.remove(queue, 1)
for i, p in ipairs(queue) do
game.ReplicatedStorage.events.queuePos:FireClient(p, i)
end
end
end
end
end
The controller script is the same for all cashiers, and it works perfectly, so the problem is in the queue. Can someone help me?
Here is some updated code using an event driven approach.
local prompt = script.Parent
local restaurant = prompt.Parent.Parent
local queue = {}
local ordered = {}
prompt.Triggered:Connect(function(p)
if not table.find(ordered, p) then
game.ReplicatedStorage.events.queuePos:FireClient(p, #queue + 1) -- shows the player their current position in the queue
table.insert(queue, p) -- adds player to the queue
table.insert(ordered, p) -- prevents player from ordering twice at a time
end
end)
local function processQueue()
while #queue > 0 do
for _, c in pairs(restaurant.cashiers:GetChildren()) do
if c.available.Value then
c.available.Value = false
c.attending.Value = queue[1]
table.remove(queue, 1)
for i, p in ipairs(queue) do
game.ReplicatedStorage.events.queuePos:FireClient(p, i)
end
break -- Exit the loop after assigning a cashier
end
end
task.wait() -- Yield to prevent performance issues
end
end
game:GetService("RunService").Heartbeat:Connect(processQueue)
works perfectly! thank you so much! only did a few tweaks, here is my final script:
local prompt = script.Parent
local running = false
local restaurant = prompt.Parent.Parent
local queue = {}
local ordered = {}
prompt.Triggered:Connect(function(p)
if not table.find(ordered, p) then
game.ReplicatedStorage.events.queuePos:FireClient(p, #queue + 1)
table.insert(queue, p)
table.insert(ordered, p)
end
end)
game:GetService("RunService").Heartbeat:Connect(function()
while #queue > 0 and not running and task.wait() do
running = true
for _, c in pairs(restaurant.cashiers:GetChildren()) do
if c.available.Value then
c.available.Value = false
c.attending.Value = queue[1]
table.remove(queue, 1)
for i, p in ipairs(queue) do
game.ReplicatedStorage.events.queuePos:FireClient(p, i)
end
running = false
break
end
end
end
end)