Turn a 'Server queue' into a 'Client queue'

Recently I found out that the current script below (without the comments) was a ‘server’ queue. Meaning that when the function was called more than once it would queue on the server when it should queue on the client, causing a mess. This would affect things like: when I would update the game only 1 person at a time got the alert.

How can I go about fixing this? LocalScripts and ServerScripts require this module and use it for different purposes.

Module:

local GUI = {}
--local Queue = {}
local TweenService = game:GetService("TweenService")
local TransitionInfo = TweenInfo.new(0.3, Enum.EasingStyle.Quad)
--local IsAlerting = false

function GUI.Alert(Text, Time, Color, Player)
	--[[if IsAlerting then
		table.insert(Queue, {Text, Time, Color, Player})
		return
	end
	IsAlerting = true]]
	local AlertLabel = script.Assets.AlertLabel
	local NewAlertLabel = AlertLabel:Clone()
	NewAlertLabel.Name = "Alert"
	NewAlertLabel.BackgroundColor3 = Color
	NewAlertLabel.Text = Text
	NewAlertLabel.Parent = game.Players[tostring(Player)].PlayerGui.Notifacation.GUIHolder
	TweenService:Create(NewAlertLabel, TransitionInfo, {BackgroundTransparency = 0}):Play()
	TweenService:Create(NewAlertLabel, TransitionInfo, {TextTransparency = 0}):Play()
	local TweenWait = TweenService:Create(NewAlertLabel, TransitionInfo, {Position = UDim2.new(0.5, 0, 0.94, 0)})
	TweenWait:Play()
	
	TweenWait.Completed:Connect(function()
		wait(Time)
		TweenService:Create(NewAlertLabel, TransitionInfo, {BackgroundTransparency = 1}):Play()
		TweenService:Create(NewAlertLabel, TransitionInfo, {TextTransparency = 1}):Play()
		local TweenWait = TweenService:Create(NewAlertLabel, TransitionInfo, {Position = UDim2.new(0.5, 0, 0.88, 0)})
		TweenWait:Play()
		
		TweenWait.Completed:Connect(function()
			NewAlertLabel:Destroy()
			--[[task.wait()
			IsAlerting = false
			if #Queue >= 1 then
				wait(0.25)
				GUI.Alert(table.unpack(table.remove(Queue, 1)))
			end]]
		end)
	end)
end

return GUI```

You need to make a few changes to your code. Mainly the creation of a client-sided queue and the use of LocalScript to create the notifications.

Move the Alert function to a LocalScript. Attach that to a ScreenGui or bind it to an event in a ModuleScript which is linked to a LocalScript. This will ensure that it runs on the client side, not the server.

local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local TransitionInfo = TweenInfo.new(0.3, Enum.EasingStyle.Quad)

local Player = Players.LocalPlayer

-- We will use the Queue for queuing the alerts on each client
local AlertQueue = {}

local function Alert() -- Removed arguments
	while true do
		if #AlertQueue ~= 0 then 
			local Task = table.remove(AlertQueue, 1) -- Dequeue
			local Text = Task.Text
			local Time = Task.Time
			local Color = Task.Color

			local AlertLabel = script.Assets.AlertLabel
			local NewAlertLabel = AlertLabel:Clone()
			NewAlertLabel.Name = "Alert"
			NewAlertLabel.BackgroundColor3 = Color
			NewAlertLabel.Text = Text
			NewAlertLabel.Parent = Player.PlayerGui.Notifacation.GUIHolder
			TweenService:Create(NewAlertLabel, TransitionInfo, {BackgroundTransparency = 0}):Play()
			
			-- ... Rest of the tween stuff ...

			wait(Time)
		else
			wait(1)
		end
	end
end

spawn(Alert) -- Run the loop in a separate thread

As for interacting with the notifications from a ModuleScript:

local ClientAlert = {}

function ClientAlert.Alert(Text, Time, Color)
	table.insert(AlertQueue, {Text=Text, Time=Time, Color=Color})
end

return ClientAlert

Remember to require this ModuleScript with a LocalScript and use the Alert function it provides.