Can you send data in and back? What I’m trying to say can we send saved data to another game and bring it back to the original game?
Another question that I have, is this going to be fast? Does this use or can we use the same system TDS uses for matchmaking? Which is where it would get the closest players to you.
This is awesome I could use this in future games thank you
Is there a way to turn off multiplayer teleports if you leave or get disconnected? My game doesn’t support that feature. Also, if you do not even teleport, you get teleported solo anyway, which is a bad user experience. Would appreciate a way to turn that oof.
If you’re here for the hold explanation, it’s at the bottom of this post.
This is a matchmaking service, the most it provides is matchmaking and sending relevant data to games, if you want to send data back, you’d need to handle that yourself using any method you want. I don’t want to bloat the service with things potentially unrelated to matchmaking which would slow down the service for people that don’t want/need the functionality.
You can use it to append custom data relevant to the games/players which are being sent that you can then access on the game servers after a match is found, but it does not relay any info back after the game is over, other than potentially updating a player’s rating, which isn’t really going back to the other server at all it’s just updating it in a datastore.
I don’t know what TDS is, however there is no geolocation check in MMS, if that’s what you mean. It uses a FIFO priority-based queue (it’s essentially FIFO, but parties are handled a little differently).
I’m unsure what you mean. MMS does not handle reconnecting disconnected users to games anywhere in its code (it doesn’t even connect to PlayerAdded at all)
As for teleporting solo, MMS looks at your maps min/max values and will teleport users as soon as it reaches min, so if you don’t want users to teleport solo set min higher.
If you believe you have found a bug, please gather evidence (recordings are the easiest to follow) then submit that.
For everyone else regarding the future of this project
As of right now this project is on hold. MMS is a passion project of mine, I made it for the community. I don’t ask for or expect anything in return, I don’t even ask for, or care for any credit. I’m currently very busy with life at the moment. I’m a full time college student with finals coming up. I’m also an intern at roblox working on a game through the accelerator program as my full time job at the moment. Needless to say, I’m extremely busy and have very little free time, and the free time I do have I don’t want to turn into work time. I do other things in my life than program that I’d like to do when I have time.
I don’t plan on fully discontinuing this project anytime soon, however, just know that there will be no updates unless it’s to fix breaking bugs until I’m done with college, the internship, and probably find a new job afterwards. I’d like to settle in and get into a good rhythm again since right now, it really isn’t.
And of course, this project will always be free and open source. If you want to contribute, head over to the github, fork the project, add some changes, then PR it into the main repo and leave a reply here if I don’t see it. The beauty of open source software is that anyone can work on it.
I hope you understand where I’m coming from with this,
Steven
Not wanting to bump the topic, I did release 2.0.3 which is a small fix that doesn’t even add any lines of code:
Version 2.0.3
Changes (breaking):
- None
Changes (non-breaking):
- None
Fixes:
- [Fix] Attempted a fix for an issue that would cause an error when teleporting players to existing games with no custom teleport data.
This is fully understandable Steven. It’s really amazing what you have done for all of us, and we really can’t thank you enough for sharing this with the community.
Furthermore, I am very grateful for you still fixing game-breaking bugs even though you‘re (understandably) very busy!
Thanks for everything, and good luck on your other projects too. I‘m sure we‘ll all keep in touch, and the project isn‘t disbanded - rather mothballed until you have more time
Great module! The only problem I’m having is that
:SetPlayerRange(…)
isn’t working for me. I set the minimum amount to 2 players but when I queue up with 1 player I get teleported anyway. I think I followed the steps correctly,
hub server:
local MatchmakingService = require(script:WaitForChild("MatchMaking")).GetSingleton()
local MPremote = game:GetService("ReplicatedStorage"):WaitForChild("startMultiplayer")
-- Game modes ..................................................
gameModes = {
["Distance"] = {},
["Elimination"] = {}, -- disabled
["Dodge"] = {} -- disabled
}
MatchmakingService:SetPlayerRange("Distance", NumberRange.new(2, 4))
MatchmakingService:AddGamePlace("Distance", 7523477758)
--..............................................................
MPremote.OnServerEvent:connect(function(player, gameMode)
if gameModes[gameMode] then
print("exists")
MatchmakingService:QueuePlayer(player, "unranked", gameMode)
else
player:Kick("Multiplayer game mode does not exist")
end
end)
instance server:
local MatchmakingService = require(script:WaitForChild("MatchMaking")).GetSingleton()
-- Game modes ..................................................
gameModes = {
["Distance"] = {},
["Elimination"] = {}, -- disabled
["Dodge"] = {} -- disabled
}
MatchmakingService:SetPlayerRange("Distance", NumberRange.new(2, 4))
--..............................................................
MatchmakingService:SetIsGameServer(true)
local gameData
game.Players.PlayerAdded:Connect(function(player)
if not gameData then
gameData = MatchmakingService:GetGameData()
end
if #game.Players:GetPlayers() >= 2 then
--Start()
MatchmakingService:StartGame(gameData.gameCode, false) -- joinable = false
end
end)
This shouldn’t be possible considering, even if the value was incorrect, the default is minimum 6 players. I’m not actually sure what causes this issue for you, however the first thing that comes to mind that may fix this for you is:
- Join the game
- Press F9, and open the developer console
- Enter the command:
MatchmakingService:Clear()
(replaceMatchmakingService
with a reference to the actual matchmaking service singleton, i.e. it should have the same location asrequire(script:WaitForChild("MatchMaking")).GetSingleton()
from your script) to purge all ephemeral memory from your game (this may interrupt any currently running games and cause them to break when they close, so it’s recommended to restart your game before doing this)
If there’s an issue with games not being cleaned up for some reason it could be sending players to a game it thinks is still running and has players.
Also, I see that you’re using a version that’s imported manually so could you tell me what version you’re using?
Thanks for the fast reply! I got the module from the Roblox library today. I found out why this problem happens. Because of my unfinished UI, I can keep firing the remote which contains QueuePlayer(…). I’m queuing up with myself every time and verified this in debug mode (the minimum was set to 4 players in the image):
I’ll fix this by keeping a list of all players currently looking for a server to only allow QueuePlayer once per player (in case exploiters abuse the remote)
Ah alright. Glad to hear you figured it out. I would do checks myself to prevent double queuing, however that would mean a lot of extra resources being used to search through memory, a local solution would be best. Just remember to remove the player from the list after they are removed from the game or you could very quickly create a memory leak.
Hello, sorry to bother you. I have an issue with my rating going below 0? I am up to date on the version. There are no errors in output or anything like that.
Hub Server Script:
-- Obtain the service
local smodule = require(game.ServerStorage.SideModule)
local MatchmakingService = require(7567983240).GetSingleton()
-- Set the game place
gameData = MatchmakingService:GetGameData()
MatchmakingService:AddGamePlace("Map 1", 9432073031)
MatchmakingService:SetPlayerRange("Map 1", NumberRange.new(2, 2))
local delayy = 10
MatchmakingService:SetFoundGameDelay(delayy)
-- Queue players (you can call QueuePlayer from anywhere)
game.ReplicatedStorage.rtt.OnServerEvent:Connect(function(player)
local queueonce = player:FindFirstChild("queueonce")
local rawr = player.PlayerGui.PlayScreen.MidBar.TextButton.Frame.Status
local frames = player.PlayerGui.PlayScreen.MidBar.TextButton.Frame
local status = player:FindFirstChild("status")
local tab = {"f", "c"}
local currentlysearching = player:FindFirstChild("cs")
if queueonce.Value == false then
MatchmakingService:QueuePlayer(player, "RankedTest2", "Map 1")
queueonce.Value = true
status.Value = "s"
if currentlysearching.Value == false then
while true do
currentlysearching.Value = true
if status.Value == {"f", "c"} then
currentlysearching.Value = false
break
end
rawr.Text = "Searching"
if status.Value == {"f", "c"} then
currentlysearching.Value = false
break
end
wait(0.4)
rawr.Text = "Searching."
if status.Value == {"f", "c"} then
currentlysearching.Value = false
break
end
wait(0.4)
rawr.Text = "Searching.."
if status.Value == {"f", "c"} then
currentlysearching.Value = false
break
end
wait(0.4)
rawr.Text = "Searching..."
if status.Value == {"f", "c"} then
currentlysearching.Value = false
break
end
wait(0.4)
if status.Value == {"f", "c"} then
currentlysearching.Value = false
break
end
end
end
print("queued")
else
print("Already queued up")
end
end)
game.ReplicatedStorage.cancel.OnServerEvent:Connect(function(plr)
local queueonce = plr:FindFirstChild("queueonce")
local status = plr:FindFirstChild("status")
if queueonce.Value == true then
queueonce.Value = false
end
MatchmakingService:RemovePlayerFromQueueId(plr.UserId)
end)
game.Players.PlayerAdded:Connect(function(plr)
MatchmakingService.FoundGame:Connect(function()
local Players = game:GetService("Players")
print("Found match!")
local frame = plr.PlayerGui.PlayScreen.MidBar.TextButton.Frame
local Status = frame:FindFirstChild("FoundG")
local canc = frame:FindFirstChild("Cancel")
local arr = frame:FindFirstChild("Status")
arr.Visible = false
canc.Visible = false
local status = plr:FindFirstChild("status").Value
status = "f"
Status.Visible = true
frame.Status.Text = "Found Match!"
wait(2)
while true do
Status.Text = "Joining"
wait(0.4)
Status.Text = "Joining."
wait(0.4)
Status.Text = "Joining.."
wait(0.4)
Status.Text = "Joining..."
wait(0.4)
end
end)
local queueonce = Instance.new("BoolValue")
queueonce.Parent = plr
queueonce.Name = "queueonce"
queueonce.Value = false
local status = Instance.new("StringValue")
status.Parent = plr
status.Name = "status"
status.Value = "n"
local cs = Instance.new("BoolValue")
cs.Parent = plr
cs.Name = "cs"
cs.Value = false
end)
game.ReplicatedStorage.rank.OnServerEvent:Connect(function(player, frame)
local rating = MatchmakingService:GetPlayerRating(player, "RankedTest2")
local ratingnu = MatchmakingService:ToRatingNumber(rating)
local ratingnus = ratingnu * 15
local ratingnum = math.ceil(ratingnus)
local frame = player.PlayerGui.PlayScreen.MidBar.Ranks.Frame
frame.Ones.Text = "1v1, MMR: "..ratingnum
if ratingnum < 250 then
frame.Ones.TextLabel.Text = "Silver"
frame.Ones.TextLabel.TextColor3 = Color3.new(0.6, 0.6, 0.6)
frame.Ones.ImageLabel.Image = "http://www.roblox.com/asset/?id=9406476107"
end
if ratingnum > 250 then
if ratingnum < 425 then
frame.Ones.TextLabel.Text = "Gold"
frame.Ones.TextLabel.TextColor3 = Color3.new(0.690196, 0.678431, 0.333333)
frame.Ones.ImageLabel.Image = "http://www.roblox.com/asset/?id=9406479274"
end
end
if ratingnum > 425 then
if ratingnum < 675 then
frame.Ones.TextLabel.Text = "Platinum"
frame.Ones.TextLabel.TextColor3 = Color3.new(0.0745098, 0.415686, 0.509804)
frame.Ones.ImageLabel.Image = "http://www.roblox.com/asset/?id=9406481687"
end
end
if ratingnum > 675 then
if ratingnum < 900 then
frame.Ones.TextLabel.Text = "Diamond"
frame.Ones.TextLabel.TextColor3 = Color3.new(0.192157, 0.270588, 0.54902)
frame.Ones.ImageLabel.Image = "http://www.roblox.com/asset/?id=9406484073"
end
end
if ratingnum > 900 then
if ratingnum < 1240 then
frame.Ones.TextLabel.Text = "Bedrock"
frame.Ones.TextLabel.TextColor3 = Color3.new(0.129412, 0.137255, 0.117647)
frame.Ones.ImageLabel.Image = "http://www.roblox.com/asset/?id=9406489538"
end
end
if ratingnum > 1240 then
frame.Ones.TextLabel.Text = "Emerald"
frame.Ones.TextLabel.TextColor3 = Color3.new(0.352941, 0.552941, 0.266667)
frame.Ones.ImageLabel.Image = "http://www.roblox.com/asset/?id=9406486698"
end
end)
Game server script:
local MatchmakingService = require(7567983240).GetSingleton()
local Module = require(game.ServerStorage.MainModule)
local DataStore = require(1936396537)
-- It's important game servers know how large they can get. You don't really need every map here,
-- but you do need whichever map this is.
-- Tell the service this is a game server
MatchmakingService:SetIsGameServer(true)
MatchmakingService:SetPlayerRange("Map 1", NumberRange.new(2, 2))
local TweenService = game:GetService("TweenService")
started = false
endgame = false
local gameData = nil
local t1 = {}
local t2 = {}
local MMRbefore1 = 0
local MMRbefore2 = 0
-- Basic start function
function Start()
if started == false then
started = true
print("Started")
MatchmakingService:StartGame(gameData.gameCode)
-- Simple teams for a 1v1.
local p = game.Players:GetPlayers()
table.insert(t1, p[1])
table.insert(t2, p[2])
local rating1 = MatchmakingService:GetPlayerRating(p[1], "RankedTest2")
local ratingnu1 = MatchmakingService:ToRatingNumber(rating1)
local ratingnus1 = ratingnu1 * 15
local ratingnum1 = math.ceil(ratingnus1)
MMRbefore1 = ratingnum1
local rating2 = MatchmakingService:GetPlayerRating(p[2], "RankedTest2")
local ratingnu2 = MatchmakingService:ToRatingNumber(rating2)
local ratingnus2 = ratingnu2 * 15
local ratingnum2 = math.ceil(ratingnus2)
MMRbefore2 = ratingnum2
p[1].Character:FindFirstChild("HumanoidRootPart").CFrame = game.Workspace.Arena.TeleportPlr.CFrame
p[2].Character:FindFirstChild("HumanoidRootPart").CFrame = game.Workspace.Arena.TeleportPlr2.CFrame
end
end
-- YOU MUST CALL UpdateRatings BEFORE THE GAME IS CLOSED. YOU CANNOT PUT THIS IN BindToClose!
function EndGame(winner)
if endgame == false then
endgame = true
MatchmakingService:UpdateRatings("RankedTest2", {if winner == 1 then 1 else 2, if winner == 2 then 1 else 2}, {t1, t2})
for i, v in ipairs(game.Players:GetPlayers()) do
if table.find(t1,v) == 1 then
if winner == 1 then
local Data1 = DataStore("PB",v)
local amount = math.random(45,75)
local amaz = 75 * 2
local MPS = game:GetService("MarketplaceService")
local GPI = 41074223
local ifprem = false
local ifvip = false
if MPS:UserOwnsGamePassAsync(v.UserId, GPI) then
Data1:Increment(amaz,0)
ifvip = true
end
if v.MembershipType == Enum.MembershipType.Premium then
if ifvip == true then
else
ifprem = true
Data1:Increment(amaz,0)
end
end
if ifvip == false then
if ifprem == false then
Data1:Increment(amount,0)
end
end
local clone = game.ReplicatedStorage.EndScreen:Clone()
clone.Frame.Results.Won.Text = "You won!"
clone.Frame.Results.Made.Text = "MMR: "..MMRbefore1
clone.Frame.Results.ImageLabel.Image = "rbxassetid://9428519351"
clone.Parent = v.PlayerGui
local label = clone.Frame.Results.Made
local arrow = clone.Frame.Results.ImageLabel
local rating1 = MatchmakingService:GetPlayerRating(v, "RankedTest2")
local ratingnu1 = MatchmakingService:ToRatingNumber(rating1)
local ratingnus1 = ratingnu1 * 15
local ratingnum1 = math.ceil(ratingnus1)
local tweenInfoWon = TweenInfo.new(
0.5, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tweenInfoArrow = TweenInfo.new(
0.2, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tween = TweenService:Create(label, tweenInfoWon, {TextTransparency = 1})
local tween2 = TweenService:Create(label, tweenInfoWon, {TextTransparency = 0})
local tween3 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween4 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local tween5 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween6 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local function arrowtween()
repeat
tween3:Play()
wait(0.5)
tween4:Play()
wait(0.5)
tween5:Play()
wait(0.5)
tween6:Play()
wait(0.5)
until wait(3)
end
tween:Play()
wait(0.8)
clone.Frame.Results.Made.Text = "MMR: "..ratingnum1
tween2:Play()
arrowtween:Play()
wait(5)
v:Kick()
end
if winner == 2 then
local Data1 = DataStore("PB",v)
local amount = math.random(1,45)
local amaz = 45 * 2
local MPS = game:GetService("MarketplaceService")
local GPI = 41074223
local ifprem = false
local ifvip = false
if MPS:UserOwnsGamePassAsync(v.UserId, GPI) then
Data1:Increment(amaz,0)
ifvip = true
end
if v.MembershipType == Enum.MembershipType.Premium then
if ifvip == true then
else
ifprem = true
Data1:Increment(amaz,0)
end
end
if ifvip == false then
if ifprem == false then
Data1:Increment(amount,0)
end
end
local clone = game.ReplicatedStorage.EndScreen:Clone()
clone.Frame.Results.Won.Text = "You lost :("
clone.Frame.Results.Made.Text = "MMR: "..MMRbefore1
clone.Frame.Results.ImageLabel.Image = "rbxassetid://9428495112"
clone.Parent = v.PlayerGui
local label = clone.Frame.Results.Made
local arrow = clone.Frame.Results.ImageLabel
local rating1 = MatchmakingService:GetPlayerRating(v, "RankedTest2")
local ratingnu1 = MatchmakingService:ToRatingNumber(rating1)
local ratingnus1 = ratingnu1 * 15
local ratingnum1 = math.ceil(ratingnus1)
local tweenInfoLost = TweenInfo.new(
0.5, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tweenInfoArrow = TweenInfo.new(
0.2, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tween = TweenService:Create(label, tweenInfoLost, {TextTransparency = 1})
local tween2 = TweenService:Create(label, tweenInfoLost, {TextTransparency = 0})
local tween3 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween4 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local tween5 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween6 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local function arrowtween()
repeat
tween3:Play()
wait(0.5)
tween4:Play()
wait(0.5)
tween5:Play()
wait(0.5)
tween6:Play()
wait(0.5)
until wait(3)
end
wait(1.8)
tween:Play()
wait(0.8)
clone.Frame.Results.Made.Text = "MMR: "..ratingnum1
tween2:Play()
arrowtween()
wait(5)
v:Kick()
end
end
if table.find(t2,v) then
if winner == 2 then
local Data1 = DataStore("PB",v)
local amount = math.random(45,75)
local amaz = 75 * 2
local MPS = game:GetService("MarketplaceService")
local GPI = 41074223
local ifprem = false
local ifvip = false
if MPS:UserOwnsGamePassAsync(v.UserId, GPI) then
Data1:Increment(amaz,0)
ifvip = true
end
if v.MembershipType == Enum.MembershipType.Premium then
if ifvip == true then
else
ifprem = true
Data1:Increment(amaz,0)
end
end
if ifvip == false then
if ifprem == false then
Data1:Increment(amount,0)
end
end
local clone = game.ReplicatedStorage.EndScreen:Clone()
clone.Frame.Results.Won.Text = "You won!"
clone.Frame.Results.Made.Text = "MMR: "..MMRbefore2
clone.Frame.Results.ImageLabel.Image = "rbxassetid://9428519351"
clone.Parent = v.PlayerGui
local label = clone.Frame.Results.Made
local arrow = clone.Frame.Results.ImageLabel
local rating1 = MatchmakingService:GetPlayerRating(v, "RankedTest2")
local ratingnu1 = MatchmakingService:ToRatingNumber(rating1)
local ratingnus1 = ratingnu1 * 15
local ratingnum1 = math.ceil(ratingnus1)
local tweenInfoWon = TweenInfo.new(
0.5, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tweenInfoArrow = TweenInfo.new(
0.2, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tween = TweenService:Create(label, tweenInfoWon, {TextTransparency = 1})
local tween2 = TweenService:Create(label, tweenInfoWon, {TextTransparency = 0})
local tween3 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween4 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local tween5 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween6 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local function arrowtween()
repeat
tween3:Play()
wait(0.5)
tween4:Play()
wait(0.5)
tween5:Play()
wait(0.5)
tween6:Play()
wait(0.5)
until wait(3)
end
wait(1.8)
tween:Play()
wait(0.8)
clone.Frame.Results.Made.Text = "MMR: "..ratingnum1
tween2:Play()
arrowtween()
wait(5)
v:Kick()
end
if winner == 1 then
local Data1 = DataStore("PB",v)
local amount = math.random(1,45)
local amaz = 75 * 2
local MPS = game:GetService("MarketplaceService")
local GPI = 41074223
local ifprem = false
local ifvip = false
if MPS:UserOwnsGamePassAsync(v.UserId, GPI) then
Data1:Increment(amaz,0)
ifvip = true
end
if v.MembershipType == Enum.MembershipType.Premium then
if ifvip == true then
else
ifprem = true
Data1:Increment(amaz,0)
end
end
if ifvip == false then
if ifprem == false then
Data1:Increment(amount,0)
end
end
local clone = game.ReplicatedStorage.EndScreen:Clone()
clone.Frame.Results.Won.Text = "You lost :("
clone.Frame.Results.Made.Text = "MMR: "..MMRbefore2
clone.Frame.Results.ImageLabel.Image = "rbxassetid://9428495112"
clone.Parent = v.PlayerGui
local label = clone.Frame.Results.Made
local arrow = clone.Frame.Results.ImageLabel
local rating1 = MatchmakingService:GetPlayerRating(v, "RankedTest2")
local ratingnu1 = MatchmakingService:ToRatingNumber(rating1)
local ratingnus1 = ratingnu1 * 15
local ratingnum1 = math.ceil(ratingnus1)
local tweenInfoWon = TweenInfo.new(
0.5, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tweenInfoArrow = TweenInfo.new(
0.2, -- The time the tween takes to complete
Enum.EasingStyle.Linear, -- The tween style.
Enum.EasingDirection.Out, -- EasingDirection
0, -- How many times you want the tween to repeat. If you make it less than 0 it will repeat forever.
false, -- Reverse?
0 -- Delay
)
local tween = TweenService:Create(label, tweenInfoWon, {TextTransparency = 1})
local tween2 = TweenService:Create(label, tweenInfoWon, {TextTransparency = 0})
local tween3 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween4 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local tween5 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 1})
local tween6 = TweenService:Create(arrow, tweenInfoArrow, {ImageTransparency = 0})
local function arrowtween()
repeat
tween3:Play()
wait(0.5)
tween4:Play()
wait(0.5)
tween5:Play()
wait(0.5)
tween6:Play()
wait(0.5)
until wait(3)
end
wait(1.8)
tween:Play()
wait(0.8)
clone.Frame.Results.Made.Text = "MMR: "..ratingnum1
tween2:Play()
arrowtween()
wait(5)
v:Kick()
end
end
end
end
end
game.Players.PlayerAdded:Connect(function(player)
if not gameData then
gameData = MatchmakingService:GetGameData()
end
if #game.Players:GetPlayers() >= 2 then
if started == false then
Start()
print(gameData.started)
end
end
end)
game.Players.PlayerRemoving:Connect(function(player)
if table.find(t1, player) == 1 then
local winner = 2
EndGame(winner)
else
local winner = 1
EndGame(winner)
end
wait()
end)
Thank you for making this module, everything works perfectly except for my rating going below zero. I am on (V2.0.2)
When I updated to open skill I removed the 0 bound because I believed it was unnecessary. This is because the way openskill works is that it uses multiple values to represent a player. This would make it hard to put a cap on since if one value is low, it does not necessarily mean that their rating is actually below 0 because there’s multiple values that represent the player’s returned ordinal skill. Is this behavior causing trouble?
Ohh alright that makes much more sense. I show the user their MMR in my game, any way I could stop it from showing a negative number? I know I could set it to 0 if it’s below 0 but that wouldn’t make much sense. I might just not show the user their MMR then. Thank you for the quick response and this module is amazing.
Edit: I also forgot to say when I had a negative number and I tried to queue with someone that had a positive number, it never found a match? Not sure if I did something wrong there.
This happens because it only searches close to the same value (in pockets of 10). It expands every 10 seconds, but you can set that here: Main Documentation - Matchmaking Service. As for not showing a negative number, you could have a transformation function that adds a static value to their rating that you’re showing that you think is low enough that no one will perform bad enough to go under that value. This also makes it seem like they start higher
Ohh! I always thought that it would queue between 50 rating, but that’s actually pretty smart. Thank you for solving my issue! I should have probably checked the documentation, thanks!
Is there no problem in using the same place the instance servers use when a player gets teleported with TeleportService (for singleplayer)? Because certain functions like :SetIsGameServer(true)
still get called
Is it possible to party users who are in separate servers together?
MMS doesn’t handle parties, so if you can make a way that can do cross server parties, yes it is possible to queue a party cross server using player ids: MatchmakingService:QueuePartyId(players, ratingType, map)
https://github.com/steven4547466/MatchmakingService/blob/master/matchmakingservice.lua#L1108