Skip to main content

Matchmaking step names and algorithm flow

This document describes all of the steps that the matchmaking algorithm can be in, and how it moves between each of these steps. The step names shown in each node will match the step name given to you by the progress event. The set of steps related to abandonment are shown in a separate graph since the matchmaking algorithm can enter the abandonment sequence at any time.

Matchmaking

This is the algorithm used by the matchmaking plugin to match players. The primary mechanism by which matchmaking takes place is the searching and follow request concepts, where hosts search for suitable matches they'd like to have merged into their match. They then send the follow request to the target match, and the target either accepts (and merges) or rejects it.

Once the match is full, the matchmaking algorithm then also takes care of starting a listen server or finding a dedicated server, and then notifying the other players of the session ID or connection string depending on the matchmaking request configuration.

graph TD ValidateRequest --> |If the request is invalid|Error --> OnErrorEvent["OnError Event"] ValidateRequest --> |If you're queuing as the host|LockParty ValidateRequest --> |If you're queuing<br/>as a client|WaitForPartyLeader WaitForPartyLeader --> |Once the host tells us the<br/>matchmaking lobby ID to join,<br/>and we've joined it|FollowHost LockParty --> |After locking the party or if you're not in a party,<br />and after fetching skill stats|CreateMatchmakingFollowRequestLobby CreateMatchmakingFollowRequestLobby --> |After the follow lobby is created|CreateMatchmakingLobby CreateMatchmakingLobby --> |If you're in a party|NotifyExistingParty NotifyExistingParty --> |Once players have been notified<br/>of matchmaking lobby ID|WaitingForPlayersToJoin CreateMatchmakingLobby --> |If you're not in a party|WaitingForPlayersToJoin WaitingForPlayersToJoin --> |Once all players have joined<br/>the matchmaking lobby|Searching Searching --> |"After waiting a delay"|SearchingMoveToSearchingStatus Searching -.-> IncomingFollowRequestVerifyPre SearchingMoveToSearchingStatus --> |After we've updated our<br/>lobby status attribute|SearchingPerformSearch SearchingMoveToSearchingStatus -.-> IncomingFollowRequestVerifyPre SearchingPerformSearch --> |We encounter a temporary error,<br/>have no suitable results, or<br/>time out in WaitUntilFull mode|Searching SearchingPerformSearch --> |We time out in CompletePartiallyFilled<br/>or CompleteFillWithAI mode|SearchingMoveToSearchingStatusPost SearchingMoveToSearchingStatus --> |If the match is complete|SearchingMoveToSearchingStatusPost SearchingPerformSearch --> |We find a suitable result|SearchingSendFollowRequest SearchingPerformSearch -.-> IncomingFollowRequestVerifyPre SearchingMoveToSearchingStatusPost(("•")) --> CompleteMatch SearchingSendFollowRequest --> SearchingSendFollowRequestMoveToWaitingStatus SearchingSendFollowRequestMoveToWaitingStatus --> |After we've updated our<br/>lobby status attribute|SearchingSendFollowRequestDoRequest SearchingSendFollowRequestDoRequest --> |If the target lobby does<br/>not respond within a time out,<br />we time out waiting for players, <br/>or the lobby rejects the request|Searching SearchingSendFollowRequestDoRequest --> |If accepted, after all target<br/>players have joined our lobby|SearchingSendFollowRequestDoRequestPost SearchingSendFollowRequestDoRequestPost(("•")) --> |If the match is full|CompleteMatch SearchingSendFollowRequestDoRequestPost --> |If we need more players|Searching IncomingFollowRequestVerifyPre(("•")) -.->|Interrupted with a follow request|IncomingFollowRequestVerify IncomingFollowRequestVerify --> |If we can't join the requesting lobby|IncomingFollowRequestReject IncomingFollowRequestVerify --> |If we can connect<br/>to the requesting lobby|IncomingFollowRequestAccept IncomingFollowRequestReject --> Searching IncomingFollowRequestAccept --> |If we can't tell existing<br/>members the new lobby ID|Searching IncomingFollowRequestAccept --> |After notifying other members<br/>and disconnecting from our lobby|FollowHost FollowHost -.-> |Notified our host moved to a new lobby|ChainFollowOntoNewHost FollowHost -.-> |Notified the match is complete|CompleteMatchAsClient ChainFollowOntoNewHost --> |After joining the new lobby|FollowHost CompleteMatchAsClient --> |If we are in return results mode|OnCompleteEvent["OnComplete Event"] CompleteMatchAsClient --> |If we are in start listen server<br/>or join dedicated server mode|WaitForSessionIdOrConnectionString WaitForSessionIdOrConnectionString -.-> |If we get a session ID|JoinServerSession JoinServerSession --> |Once we've joined the session|ConnectToGameServer WaitForSessionIdOrConnectionString -.-> |If we get a connection string|ConnectToGameServer ConnectToGameServer --> |Once we've connected to the game server|OnCompleteEvent["OnComplete Event"] CompleteMatch --> |It does not exist|CompleteMatchComputeResult CompleteMatch --> |The follow request lobby still exists|DeleteMatchmakingFollowRequestLobby DeleteMatchmakingFollowRequestLobby --> CompleteMatchComputeResult CompleteMatchComputeResult -->|After computing the final results and notifying clients|ComputeMatchFinalizeLobby ComputeMatchFinalizeLobby -->|After finalizing the party|CompleteUnlockParty CompleteUnlockParty -->|After the party is unlocked|CompleteMatchAsHost CompleteMatchAsHost -->|If we are in return results mode|OnCompleteEvent["OnComplete Event"] CompleteMatchAsHost -->|If we are in start listen server mode|StartListenServer StartListenServer -->|Once the listen server is started|CreateSessionForListenServer CreateSessionForListenServer -->|Once the session is created|SendSessionIdOrConnectionStringForListenServer SendSessionIdOrConnectionStringForListenServer -->|Once the other players have been notified|OnCompleteEvent["OnComplete Event"] CompleteMatchAsHost -->|If we are in find dedicated server mode|FindDedicatedServerSession FindDedicatedServerSession -->|Once we find a suitable dedicated server|ReserveDedicatedServerForMatch ReserveDedicatedServerForMatch -->|If we could not reserve it|FindDedicatedServerSession ReserveDedicatedServerForMatch -->|If we could reserve it,<br/>we've notified other players<br/>and we're joining by session ID|JoinServerSession ReserveDedicatedServerForMatch -->|If we could reserve it,<br/>we've notified other players<br/>and we're joining by connection string|ConnectToGameServer

Abandonment

Abandonment is used by the matchmaking algorithm when something goes wrong or one of the members of the match cancels matchmaking. When abandonment happens, all of the members that are currently in the match unwind their state to the way it was when they initially queued, and then they either restart matchmaking (if it was a temporary error or a cancellation by some other party), or they fire the OnCancelled event.

graph TD AbandonStart --> |If you're in a party|AbandonNotifyParty AbandonStart --> |If you're not in a party|AbandonNotifyMatch AbandonNotifyParty --> |If we're the leader, after notifying party|AbandonUnlockParty AbandonNotifyParty --> |If we're not the leader|AbandonWaitForPartyLeader AbandonNotifyParty --> |Various error states|AbandonUnlockParty AbandonUnlockParty --> |After unlocking party|AbandonNotifyMatch AbandonNotifyParty --> |After notifying party|AbandonNotifyMatch AbandonWaitForPartyLeader --> |Once the party leader has been notified,<br />and has notified everyone else|AbandonNotifyMatch AbandonNotifyMatch --> |If we're not in a matchmaking lobby|AbandonFinish AbandonNotifyMatch --> |If we can't notify the matchmaking lobby|AbandonFinish AbandonNotifyMatch --> |After we've notified other match members,<br />disconnected from the matchmaking lobby<br />and cleaned everything up|AbandonFinish AbandonFinish --> |"If we're restarting: someone else abandoned or<br />we had a recoverable error"|ValidateRequest AbandonFinish --> |"If we're cancelling: user cancelled or<br />unrecoverable error"|OnCancelledEvent["OnCancelled Event"]