Hey guys, I am making a matchmatching system, but it causes a lot of
DataStore request was added to queue. If request queue fills, further requests will be dropped. Try sending fewer requests.Key = Matchs
How can I improve it?
To make it faster and less requests.
local RepStorage = game:GetService("ReplicatedStorage")
local MessagingService = game:GetService("MessagingService")
local Datastore = game:GetService("DataStoreService")
local Matchmatching = Datastore:GetDataStore("Matchmatching")
local PlayersInside = {}
local Matches = {}
local Settings = require(script.Parent.Handler.Settings)
local Players = game:GetService('Players')
local TeleportService = game:GetService("TeleportService")
RepStorage.Events.EnterMatchmatching.OnServerEvent:Connect(function(Player)
if (PlayersInside[Player]) then -- If player clicked already :D
return
end
PlayersInside[Player] = true -- Adding to prevent player click multiple times :D
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
if (suc) then
if (returned) then
RepStorage.Events.NotifyClient:FireClient(Player,"Searching in; "..#returned.." servers for a match.",4) -- Just to see how much people is searching for matchs too :D
end
end
RepStorage.Events.EnterMatchmatching:FireClient(Player,1) -- UI effects, DW :D
MessagingService:PublishAsync("MatchmatchingEnter",Player.UserId) -- Add him to matchmatching, try to find him a server!
end)
RepStorage.Events.LeaveMatchmatching.OnServerEvent:Connect(function(Player)
PlayersInside[Player] = nil
MessagingService:PublishAsync("PlayerLeftMatch",Player.UserId)
end)
local function StartMatch(Table)
coroutine.wrap(function()
local Players = Table.Players
local PlayerNames = {}
for i,v in pairs(Players) do
table.insert(PlayerNames,game.Players:GetNameFromUserIdAsync(v))
end
warn("Starting match with;",table.concat(PlayerNames," & "))
if (#Players >= 2) then
local ReservedServer = TeleportService:ReserveServer(game.PlaceId)
MessagingService:PublishAsync("TeleportPlayers",{Players = PlayerNames,ServerCode = ReservedServer})
end
end)()
end
local function CheckForMatchStart()
coroutine.wrap(function()
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
if (suc) then
if (returned) then
for i,v in pairs(returned) do
if (os.time() - v.TimeCreated) >= 40 then
StartMatch(v)
table.remove(returned,i)
end
end
end
Matchmatching:UpdateAsync("Matchs",function(x)
return returned or x
end)
end
end)()
end
local function createMatch(owner)
coroutine.wrap(function()
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
warn(suc)
if (suc) then
returned = returned and returned or {}
table.insert(returned,{Players = {owner},Owner = owner,TimeCreated = os.time()})
Matchmatching:UpdateAsync("Matchs",function(x)
return returned or x
end)
return returned
end
end)()
return nil
end
local function FindPlayerInMatch(plrID)
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
warn(suc)
if (suc) then
if (returned) then
for i,v in pairs(returned) do
if (table.find(v.Players,plrID)) then
return true
end
end
end
end
return false
end
local function CheckMatchs()
coroutine.wrap(function()
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
if (suc) then
if (returned) then
print("returned, and running.")
for index,match in pairs(returned) do
if (#match.Players <= 0) then
warn("Delete this match.")
table.remove(returned,index)
end
end
Matchmatching:UpdateAsync("Matchs",function(x)
print("save.")
return returned or x
end)
end
end
end)()
end
local function RemovePlayerFromMatch(plrID)
coroutine.wrap(function()
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
warn(suc)
if (suc) then
if (returned) then
for i,v in pairs(returned) do
if (table.find(v.Players,plrID)) then
table.remove(v.Players,table.find(v.Players,plrID))
print('removed from Players.',plrID)
end
end
Matchmatching:UpdateAsync("Matchs",function(x)
return returned or x
end)
CheckMatchs()
end
end
end)()
end
local function InsertPlayerInMatch(userId,returned,index)
coroutine.wrap(function()
assert(userId ~= nil,"user ID is nil") -- Want to make sure UserId is NOT nil :D
if (returned) then -- If returned is not nil.
warn(returned,index,returned[index],returned[index].Owner) -- To check what returns, all works perfectly!
local Table = returned[index] -- Just a variable to reduce code :D
if (table.find(Table.Players,userId)) then -- Oh no, I found the player, it's already in this MATCH!
table.remove(returned[index].Players,userId) -- Let's remove him and continue.
end
print("now inserting.")
table.insert(returned[index].Players,userId) -- Let's add him to match!
Matchmatching:UpdateAsync("Matchs",function(x)
print('oh no, this doesnt PRINTS.')
return returned or x -- Cool! Time to save this.
end)
local x = {Owner = game.Players:GetNameFromUserIdAsync(Table.Owner),Name = game.Players:GetNameFromUserIdAsync(userId),Amount = Table.Players}
if (game.Players:FindFirstChild(x.Name)) then
RepStorage.Events.EnterMatchmatching:FireClient(game.Players[x.Name],#x.Amount) -- UI effects :D
end
coroutine.wrap(function()
MessagingService:PublishAsync("PlayerJoined",x) -- Let's notify the players inside match this player Joined.
end)()
end
end)()
end
MessagingService:SubscribeAsync("PlayerLeftMatch",function(Message)
local UserId = Message.Data
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs")
if (suc) then
if (returned) then
for i,v in pairs(returned) do
if (table.find(v.Players,UserId)) then
print("remove him.")
table.remove(v.Players,table.find(v.Players,UserId))
local name = game.Players:GetNameFromUserIdAsync(UserId)
if (#v.Players <= 0) then
coroutine.wrap(function()
CheckMatchs()
end)()
end
for _,id in pairs(v.Players) do
local name2 = game.Players:GetNameFromUserIdAsync(id)
if (game.Players:FindFirstChild(name2)) then
print("found",name2)
RepStorage.Events.NotifyClient:FireClient(game.Players[name2],name.." has left the match you are in.",4)
RepStorage.Events.EnterMatchmatching:FireClient(game.Players[name2],#v.Players)
end
end
end
end
Matchmatching:UpdateAsync("Matchs",function(x)
return returned or x
end)
end
end
end)
MessagingService:SubscribeAsync("TeleportPlayers",function(msg)
local Data = msg.Data
local Server = Data.ServerCode
local Players = Data.Players
print(table.unpack(Players))
for i,v in pairs(Players) do
print("Attempting to find",v)
if (game.Players:FindFirstChild(v)) then
TeleportService:TeleportToPrivateServer(game.PlaceId,Server,{game.Players[v]},nil,nil,game.ServerStorage.UI.LoadingScreen)
end
end
end)
MessagingService:SubscribeAsync("PlayerJoined",function(msg)
local Data = msg.Data
local Owner = Data.Owner
local Players = #Data.Amount
local NameOfWhoJoined = Data.Name
for i,v in pairs(Data.Amount) do
local name = game.Players:GetNameFromUserIdAsync(v)
if (game.Players:FindFirstChild(name)) then
print("found",name)
RepStorage.Events.NotifyClient:FireClient(game.Players[name],NameOfWhoJoined.." has joined the same match you are in.",4)
RepStorage.Events.EnterMatchmatching:FireClient(game.Players[name],Players)
end
end
end)
MessagingService:SubscribeAsync("MatchmatchingEnter",function(msg)
local UserId = msg.Data
CheckMatchs() -- Deletes the matches that has less than 1 players :D
local suc,returned = pcall(Matchmatching.GetAsync,Matchmatching,"Matchs") -- Retrieving data.
if (suc) then
if (returned) then
table.sort(returned,
function(a,b)
return (a.Players < b.Players)
end
) -- Sorting the table to find the player the match with more Players :D
local x = false
for i,v in pairs(returned) do
if (#v.Players < Settings.MaxPlayers) then -- Checking to see how much players the match has!
InsertPlayerInMatch(UserId,returned,i) -- Cool! Let's insert him to match :D!
x = true -- forget this :D
break -- breaking it
end
end
if (not x) then
createMatch(UserId)
end
else
print('creating a new match. CREATED BY:',game.Players:GetNameFromUserIdAsync(UserId))
createMatch(UserId)
end
end
end)
Players.PlayerRemoving:Connect(function(Player)
MessagingService:PublishAsync("PlayerLeftMatch",Player.UserId)
end)
game:BindToClose(function()
CheckMatchs()
end)
CheckMatchs()
coroutine.wrap(function()
while (wait(60)) do
print('checking for match starting')
CheckForMatchStart()
end
end)()