Single Server Matchmaking

I’m creating a system where a raider can find an active server and join it.

The difference between this post and the existing relevant ones is that it’s mostly a queue-based matchmaking while I only want the raider’s server to search for the raidee’s server and for only the raider to join only that.
I’d prefer using MessagingService, but do suggest other ideas too.

Any ideas on how to start?

1 Like

If you want to implement a matchmaking system where a raider can find an active server to join, you could use a server-to-server communication method to share information about active servers.

One possible approach is to use MessagingService as you suggested. You could create a “matchmaking” channel and have servers publish their availability and capacity to join the raid. The raiders would then query the channel for available servers and join one of their choice.

Here’s how you can use MessagingService for this purpose:

  1. Server registration: Each active server could register itself to the matchmaking channel by publishing a message with information about its capacity, player count, and other relevant details. You could use the MessagingService:PublishAsync() method to publish the message.
  2. Server query: Raiders looking to join a server could query the matchmaking channel for available servers by calling the MessagingService:GetMessagesAsync() method with a filter that matches the server registration messages.
  3. Server selection: Once the raider receives the available server messages, they could choose a server to join based on the server’s capacity, player count, and other factors.
  4. Server join: Finally, the raider could join the selected server by sending a message to the server, notifying it of the player’s intention to join. You could use a custom remote function to handle the server join logic.

Note that you will need to handle edge cases such as server capacity being reached, server availability changing rapidly, and server communication errors. However, using MessagingService for server-to-server communication can simplify the matchmaking process and allow you to easily scale the system as needed.

I will make to you a little script example so you can start, wait a little.

1 Like

Here’s an example of how you can use MessagingService to implement a basic matchmaking system:

local MatchmakingChannel = game:GetService("MessagingService"):SubscribeAsync("matchmaking")
local Servers = {}

-- Register server to matchmaking channel
function RegisterServer(serverId, capacity, playerCount)
    local serverData = {
        Id = serverId,
        Capacity = capacity,
        PlayerCount = playerCount,
    }
    table.insert(Servers, serverData)
    game:GetService("MessagingService"):PublishAsync("matchmaking", serverData)
end

-- Query available servers
function QueryServers()
    local availableServers = {}
    for _, message in ipairs(game:GetService("MessagingService"):GetMessagesAsync("matchmaking").Messages) do
        for _, serverData in ipairs(Servers) do
            if message.Data.Id == serverData.Id then
                serverData.Available = true
                serverData.Players = message.Data.Players
                table.insert(availableServers, serverData)
            end
        end
    end
    return availableServers
end

-- Join server
function JoinServer(player, serverId)
    local server = nil
    for _, serverData in ipairs(Servers) do
        if serverData.Id == serverId and serverData.Available then
            server = serverData
            serverData.Available = false
            serverData.Players = serverData.Players + 1
            break
        end
    end
    if server then
        -- Handle joining logic (e.g. teleport player to server)
    else
        -- Server not available or doesn't exist
    end
end

-- Example usage:
RegisterServer("Server1", 10, 5) -- Register server with id "Server1", capacity of 10, and 5 players
local availableServers = QueryServers() -- Get available servers
JoinServer(game.Players.LocalPlayer, availableServers[1].Id) -- Join first available server

In this example, RegisterServer() is used to register a server with the matchmaking channel by publishing a message containing its capacity, player count, and other relevant details. QueryServers() is used to retrieve a list of available servers by filtering the messages in the matchmaking channel and matching them with the registered servers. JoinServer() is used to join a selected server by updating its availability and player count and handling the joining logic.

Note that this is just a basic example and you would need to add more error handling and edge case handling to make the matchmaking system more robust.

1 Like

How do I send the player to a server without the job id? I supposed I can register that instead of “Server1” in your example. Is this plausible or is there another way?

Yes, you can use any unique identifier for the server, including a job ID or a randomly generated ID. The important thing is that you register the server with a unique identifier that can later be used to identify the server.

In the example code you provided, you would replace “Server1” with the unique identifier you want to use for your server when calling the RegisterServer() function.

To send the player to a server without using the unique identifier directly, you could modify the JoinServer() function to accept a server object instead of a server ID. For example:

function JoinServer(player, server)
    if server.Available then
        server.Available = false
        server.PlayerCount = server.PlayerCount + 1
        -- Handle joining logic (e.g. teleport player to server)
    else
        -- Server not available or doesn't exist
    end
end

Then, you could pass the server object retrieved from QueryServers() to JoinServer() instead of the server ID:

local availableServers = QueryServers()
JoinServer(game.Players.LocalPlayer, availableServers[1])

This way, you don’t need to expose the server ID to the client, and you can pass the server object directly to JoinServer() instead.

Also, how would I add a “raid protection” feature to deny a matchmake if active? For example a BoolValue that is checked is under raid protection.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.