diff --git a/docs/guides/quickmatch.md b/docs/guides/quickmatch.md index 70e0fb2..252bb9a 100644 --- a/docs/guides/quickmatch.md +++ b/docs/guides/quickmatch.md @@ -52,6 +52,8 @@ The `ConnectToNextAvailableQuickmatchRoom` method has two required fields: - **`roomGroupName`**: The name of the room group. Must be 1-32 characters, start with a letter, and contain only letters, numbers, hyphens, and underscores. - **`capacity`**: The maximum number of players per room (1-500). Used when creating new rooms. +You can also pass `ConnectOptions` and `QuickmatchOptions` as optional parameters. + ### Join with Room Code Quickmatch rooms have a short room code that's easy to share with friends. You can use `ConnectDirectlyToQuickmatchRoom()` to join a room using its room code: @@ -66,12 +68,36 @@ The `ConnectDirectlyToQuickmatchRoom` method has two required fields: - **`roomGroupName`**: The name of the room group. Must match the room group used when the room was created. - **`roomCode`**: The short room code to join. This is available via `Room.quickmatchRoomCode` after connecting. -You can also pass `ConnectOptions` as an optional third parameter. +You can also pass `ConnectOptions` and `QuickmatchOptions` as optional parameters. :::note This method can result in a [`QuickmatchRoomNotFound`](../room/disconnect-events#quickmatchroomnotfound) disconnect event if the room has been cleaned up, or a [`QuickmatchRoomFull`](../room/disconnect-events#quickmatchroomfull) event if the room is at capacity. See [Error Handling](#error-handling) for how to handle these cases. ::: +### Excluding Rooms + +You can prevent players from being matched into specific rooms by passing a `QuickmatchOptions` struct with an `excludeRoomCodes` list. This is useful when a player has left a room and you don't want them to be placed back into the same room: + +```csharp +// Player leaves a room — save the room code before disconnecting +string previousRoomCode = _realtime.room.quickmatchRoomCode; +_realtime.Disconnect(); + +// Reconnect, excluding the previous room +var quickmatchOptions = new Room.QuickmatchOptions { + excludeRoomCodes = new[] { previousRoomCode }, +}; +_realtime.ConnectToNextAvailableQuickmatchRoom( + roomGroupName: "lobby", + capacity: 8, + quickmatchOptions: quickmatchOptions +); +``` + +:::note +`excludeRoomCodes` only has an effect when using `ConnectToNextAvailableQuickmatchRoom()`. It is ignored when calling `ConnectDirectlyToQuickmatchRoom()`. +::: + ### Join with Room Name Quickmatch rooms function as regular Normcore rooms. After connecting, the room name is available via `Realtime.roomName`. Players can share this name with friends, who can join directly using the standard `Connect()` method: @@ -93,6 +119,10 @@ As long as the room has capacity, anyone can join. This method can result in a [`QuickmatchRoomNotFound`](../room/disconnect-events#quickmatchroomnotfound) disconnect event if the room has been cleaned up, or a [`QuickmatchRoomFull`](../room/disconnect-events#quickmatchroomfull) event if the room is at capacity. See [Error Handling](#error-handling) for how to handle these cases. ::: +:::note +If you're using [Normcore Private webhooks](../normcore-private/webhooks), all quickmatch connection methods are verified by the webhook before a room slot is reserved. See the [webhooks documentation](../normcore-private/webhooks#quickmatch-webhook-behavior) for details. +::: + ### Room Properties After connecting to a Quickmatch room, you can access the room code and capacity via the `Room` object: diff --git a/docs/normcore-private/webhooks.md b/docs/normcore-private/webhooks.md index 114b965..025cb24 100644 --- a/docs/normcore-private/webhooks.md +++ b/docs/normcore-private/webhooks.md @@ -21,7 +21,16 @@ Normcore sends webhook requests for the following actions: - **GetRegionsList**: Fired whenever a client requests a list of available regions. - **ConnectToNextAvailableQuickmatchRoom**: Called when a client requests connecting to the next available quickmatch room. The webhook can approve or deny the request before Normcore reserves space or spins up a fresh room. This action includes `roomGroupName` and `capacity` values. -- **ConnectToRoom**: Called whenever a client attempts to connect to a room server. This action is also called after a `ConnectToNextAvailableQuickmatchRoom` request is approved and a room has been selected for the client. +- **ConnectDirectlyToQuickmatchRoom**: Called when a client connects to a specific quickmatch room, whether by room code or room name. The webhook can approve or deny the request before Normcore reserves a spot. This action includes `roomGroupName` and `roomCode` values. +- **ConnectToRoom**: Called whenever a client attempts to connect to a room server. This action is also called after a quickmatch request is approved and a room has been selected for the client. + +### Quickmatch webhook behavior +When a client connects to a quickmatch room, Normcore sends two webhook requests in sequence: + +1. A quickmatch-specific webhook (`ConnectToNextAvailableQuickmatchRoom` or `ConnectDirectlyToQuickmatchRoom`) — this fires first, before any room slot is reserved. +2. A `ConnectToRoom` webhook — this fires after the quickmatch request is approved and a room has been assigned. + +If either webhook denies the request, the connection is rejected. This applies regardless of which API method the client used to connect — even if a client connects to a quickmatch room using `Connect()` with the room name, the quickmatch webhook fires first. ## Request format When the matcher needs to authenticate one or more requests, it sends a POST request to the webhook endpoint. The request includes a JSON-serialized body with a map of requests to verify. @@ -42,6 +51,18 @@ An example request looks like this: } ``` +A quickmatch webhook request includes the room group name and either the capacity or room code, depending on the action: +```json +{ + "a1b2c3d4-e5f6-7890-abcd-ef1234567890": { + "appKey": "f0b89d74-a4bb-4dc6-8bcb-0dc063c38e7c", + "action": "ConnectDirectlyToQuickmatchRoom", + "roomGroupName": "lobby", + "roomCode": "ABC123" + } +} +``` + The webhook endpoint is expected to reply with a status for each request. Any request GUIDs that are not included in the response to will fail. The webhook response should match this format: