When searching for a game in my queue system, the user is not being reconized, thus not pairing up people in the queue.
I am guessing the problem is within the "UserId"s, but I am not ultimately sure. Here is the code:
local lookForGameEvent = game.ReplicatedStorage.LookForGameEvent
local rankedList = require(game.ServerStorage.MatchmakingRankedListModule)
local ratingData = game:GetService("DataStoreService"):GetDataStore("PlayerRating")
local coinData = game:GetService("DataStoreService"):GetDataStore("PlayerCoin")
local gemData = game:GetService("DataStoreService"):GetDataStore("PlayerGems")
local teleportService = game:GetService("TeleportService")
local arenaPlaceTemplateId = 1983540262
-- Table to hold the queue of players looking for a game
local matchMakingQueue = {}
-- Add player's id to the queue as well as the time that they entered the queue
local addToMMQueue = function(playerId, enteredTime)
local data = {}
data.UserId = playerId
data.EnteredQueue = enteredTime
table.insert(matchMakingQueue, data)
end
-- Remove player from the queue
local removeFromMMQueue = function(playerId)
for i, playerData in pairs(matchMakingQueue) do
if playerData.UserId == playerId then
table.remove(matchMakingQueue, i)
return
end
end
end
-- Handle player joining the game. If they are a new player we need to give them
-- an initial rank. For existing players we need to fetch their rank from our
-- DataStore. Lastly, we want to display the player's rank in the Leaderboard
game.Players.PlayerAdded:connect(function(player)
local playerData = {}
-- Create a default rating of 100 if the player's data is not in the DataStore
ratingData:UpdateAsync(player.UserId, function(oldValue)
local newValue = oldValue
if not newValue then
newValue = {Rating = 100}
end
return newValue
end)
coinData:UpdateAsync(player.UserId, function(oldvalue2)
local newValue2 = oldvalue2
if not newValue2 then
newValue2 = {Coins = 10}
end
return newValue2
end)
gemData:UpdateAsync(player.UserId, function(oldvalue3)
local newValue3 = oldvalue3
if not newValue3 then
newValue3 = {Gems = 0}
end
return newValue3
end)
playerData.Score = ratingData:GetAsync(tostring(player.UserId)).Rating
playerData.Score2 = coinData:GetAsync(tostring(player.UserId)).Coins
playerData.Score3 = gemData:GetAsync(tostring(player.UserId)).Gems
-- Display rating in Leaderboard
local stats = Instance.new("Folder", player)
stats.Name = "leaderstats"
local displayRating = Instance.new("IntValue", stats)
displayRating.Name = "Rating"
displayRating.Value = playerData.Score
local displayCoins = Instance.new("IntValue", stats)
displayCoins.Name = "Coins"
displayCoins.Value = playerData.Score2
local displayGems = Instance.new("IntValue", stats)
displayGems.Name = "Gems"
displayGems.Value = playerData.Score3
end)
-- Adds player both to queue and list to search for match
local function playerSearchingForMatch(UserId, rank)
local now = os.time()
addToMMQueue(UserId, now)
rankedList:AddPlayer(UserId, rank, now)
end
-- Remove player from list and queue when they leave the game
game.Players.PlayerRemoving:connect(function(player)
removeFromMMQueue(player.UserId)
rankedList:RemovePlayer(player.UserId)
end)
-- Handle remote event to either add or remove player from the queue
lookForGameEvent.OnServerEvent:connect(function(player, lookingForGame)
if lookingForGame then
print(player.Name .. " now looking for game")
local enteredTime = os.time()
playerSearchingForMatch(player.UserId, player.leaderstats.Rating.Value)
else
print(player.Name .. " has left the queue")
removeFromMMQueue(player.UserId)
rankedList:RemovePlayer(player.UserId)
end
end)
-- Returns a rank range to search through based on time waiting in the queue.
-- If player has been waiting too long just return math.huge so the player can
-- be matched with anyone.
local getRange = function(timeWaiting)
if timeWaiting < 10 then
return 100
elseif timeWaiting >=10 and timeWaiting < 20 then
return 200
elseif timeWaiting >=20 and timeWaiting <= 35 then
return 300
end
return math.huge
end
-- Creates place for game and teleports both players to it
local startGame = function(playerAId, playerBId)
local message = ""
print("starting game with " .. playerAId .. " and " .. playerBId)
--[[if playerAId == playerBId then
print("same ID!")
return
end--]]
-- Get both player objects
local playerA = nil
local playerB = nil
for _, player in pairs(game.Players:GetPlayers()) do
if player.UserId == playerAId then
playerA = player
end
if player.UserId == playerBId then
playerB = player
end
end
-- Create arena place and get its id
local arenaPlaceId = game:GetService("AssetService"):CreatePlaceAsync(
"Match: " .. playerAId .. " VS. " .. playerBId, arenaPlaceTemplateId)
-- Bind OnTeleport event to playerA (who is teleported first). If that teleport is successful
-- then we want playerB to be teleported to the same instance
local connection = playerA.OnTeleport:connect(function(teleportState, placeId)
if teleportState == Enum.TeleportState.Started then
local teleportStarted = os.time()
-- Keep checking if playerA has arrived in other instance.
while true do
local success, error, placeId, arenaInstanceId = teleportService:GetPlayerPlaceInstanceAsync(playerAId)
-- If playerA is in the correct place then we can teleport playerB there as well
if success then -- placeId == arenaPlaceId
teleportService:Teleport(arenaPlaceId, playerB)
return
end
wait()
end
end
end)
wait(1)
-- Teleport playerA to the arena
teleportService:Teleport(arenaPlaceId, playerA)
end
-- Matchmaking loop. Cycles about every 5 seconds to match players.
while true do
local now = os.time()
-- Cycle through queue, try to find players in range
for _, mmData in pairs(matchMakingQueue) do
print("attempting to find match for " .. mmData.UserId)
-- Get rank range to search
local range = getRange(now - mmData.EnteredQueue)
-- Use list to find a player in player's rank range
local otherPlayerId = rankedList:FindPlayerInRange(mmData.UserId, range)
if otherPlayerId then
-- Another player was found. Remove both players from the queue and list so they
-- can't be matched with anyone else
print("found player: " .. otherPlayerId)
rankedList:RemovePlayer(mmData.UserId)
rankedList:RemovePlayer(otherPlayerId)
removeFromMMQueue(mmData.UserId)
removeFromMMQueue(otherPlayerId)
-- Start game with the two players. This function can take some times, so start a
-- coroutine so the loop can continue.
local thread = coroutine.create(function() startGame(mmData.UserId, otherPlayerId) end)
coroutine.resume(thread)
end
end
wait(5)
end
