SetNet.Matchmaking
1.2.0
dotnet add package SetNet.Matchmaking --version 1.2.0
NuGet\Install-Package SetNet.Matchmaking -Version 1.2.0
<PackageReference Include="SetNet.Matchmaking" Version="1.2.0" />
<PackageVersion Include="SetNet.Matchmaking" Version="1.2.0" />
<PackageReference Include="SetNet.Matchmaking" />
paket add SetNet.Matchmaking --version 1.2.0
#r "nuget: SetNet.Matchmaking, 1.2.0"
#:package SetNet.Matchmaking@1.2.0
#addin nuget:?package=SetNet.Matchmaking&version=1.2.0
#tool nuget:?package=SetNet.Matchmaking&version=1.2.0
<p align="center"> <img src="https://raw.githubusercontent.com/Povstalez/SetNet/master/assets/icon.png" alt="SetNet" width="96"> </p>
SetNet.Matchmaking
Matchmaking for SetNet, on top of SetNet.Rooms.
Queue players into matches — FIFO or skill-based with a widening acceptance window so nobody waits forever — then drop each formed match into a freshly created room they join. Added by composition: no base class, works alongside your regular messages.
var match = await matchmaking.FindMatchAsync(new MatchRequest { Queue = "ranked", Skill = 1500 });
await rooms.JoinAsync(match.RoomCode); // now you're in a room with your opponents
Install
dotnet add package SetNet
dotnet add package SetNet.Rooms
dotnet add package SetNet.Matchmaking
At startup (before constructing your client/server), enable both layers and register a serializer:
SetNetSerializer.Use(new MessagePackNetSerializer()); // from SetNet.MessagePack
RoomsRuntime.Enable();
MatchmakingRuntime.Enable();
Server
Pass the same IRoomStore to UseRooms and UseMatchmaking — matched players are placed into a room created in that store, which they then join through Rooms:
var store = new MemoryRoomStore(); // share one store
server.UseRooms(store);
server.UseMatchmaking(store, new MatchmakingOptions
{
MatchSize = 2, // players per match
UseSkill = true, // group by rating (omit for pure FIFO)
TickIntervalMs = 500,
});
Client
var rooms = client.UseRooms();
var matchmaking = client.UseMatchmaking();
// Enter the queue and await a match (cancel the token to leave the queue):
var match = await matchmaking.FindMatchAsync(new MatchRequest { Queue = "ranked", Skill = 1500 });
Console.WriteLine($"Matched with {match.Players.Count} players in room {match.RoomCode}");
await rooms.JoinAsync(match.RoomCode);
// …or do both in one call:
var room = await matchmaking.FindAndJoinAsync(new MatchRequest { Queue = "ranked" }, rooms);
MatchFound also fires as an event, and CancelAsync() leaves the queue.
How matching works
- Players are grouped per queue — only players in the same
Queuestring can match (use it for mode + region, e.g."ranked-eu"). - FIFO by default (
UseSkill = false): the oldestMatchSizewaiting players form a match. - Skill-based (
UseSkill = true): the server sorts waiting players by rating and forms a group whose skill spread fits inside every member's acceptance window. That window starts atBaseSkillWindowand grows bySkillWindowGrowthPerSecondfor every second a player waits — so a close match is preferred early, but a long wait eventually matches anyone. - A background ticker (
TickIntervalMs) forms matches; when one forms, the server creates a room (capacityMatchedRoomMaxPlayers, defaultMatchSize) and pushes aMatchFoundonly to those players. - A player who disconnects or cancels is removed from the queue automatically (via the core
PeerDisconnectedevent).
Options
| Option | Default | Meaning |
|---|---|---|
MatchSize |
2 |
Players per match |
UseSkill |
false |
Skill-based grouping vs pure FIFO |
BaseSkillWindow |
100 |
Initial ± skill spread a group may span |
SkillWindowGrowthPerSecond |
50 |
How fast the window widens while waiting |
TickIntervalMs |
500 |
How often the matchmaker runs |
MatchedRoomMaxPlayers |
0 (= MatchSize) |
Capacity of the created room |
Notes
- Runs on a dedicated server (the same node that hosts Rooms). Because rooms are node-local, matchmaking is node-local too; a multi-node deployment would coordinate through a shared
IRoomStoreimplementation. - Rides the unified SetNet.Protocol messaging layer on the
Channels.Matchmakingchannel (all modules share one envelope wire type,65447) — no per-module wire ids to reserve. Serializer-agnostic: the control protocol is hand-framedbyte[], your payloads use yourSetNetSerializer. - Depends on
SetNet+SetNet.Rooms; serializer-agnostic (hand-framedbyte[]protocol).
Documentation & source
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- SetNet (>= 1.2.0)
- SetNet.Rooms (>= 1.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.