Skip to content

Commit 2f4e7ac

Browse files
RockasMockasMaxCWhiteheaddeficzicklagTekhnaeRaav
authored
feat: Matchmaker Rework (#431)
This PR covers a large rework of the matchmaker and its entire flow to bones & the dev interface. In short the major changes include: #### Matchmaker: - Supports multiple games running a single matchmaker, thanks to GameID now integrated - Internal state revamped to support now both Matchmaking & newly added Lobbies - Bones <-> Matchmaker messaging flow rework to support more than just 1 "endpoint", and importantly enable long-lived connections which is a requirement for lobbies - Updated the interface for devs to interact with the matchmaker to provide a standardized/clean interface that we can scale with new features #### Matchmaking Changes: - Robustness was the main focus, so now implements a simple wait/retry protocol when the matchmaking room is full, thus avoiding previous issues with failure during lots of players starting matchmaking at once. - Implements dead connection cleaning, guaranteeing that when a match starts all player clients have active connections (are alive) and starting the match can proceed - Adds an explicit stop matchmaking search message, making the matchmaking flow more "proper/clean" and allowing us to do proper local error checking to prevent bad states without straining the matchmaker (ie. you can't create a lobby if you're in matchmaking). - A number of smaller edge case fixes/reworking internals to make things nicer to work with. ### Lobbies Changes: - They now exist, freshly implemented - The core mechanics are in place for list/create/join lobbies - Supports password-protected lobbies to make it easy for users to play with their friends Of note, this PR is already quite large and covers the majority of breaking changes to the matchmaker needed in the short term, while getting the flow of matchmaking to feel quite robust with the edge cases addressed. Lobbies still need further work to be robust, and the randomness seed/match_data pushing into the ggrs session runner hasn't been done here yet, however I feel this PR is encompassing enough as-is and would prefer to move forward with smaller/lighter PRs for the extra functionality. --------- Co-authored-by: Max Whitehead <[email protected]> Co-authored-by: Jeremias <[email protected]> Co-authored-by: Zicklag <[email protected]> Co-authored-by: Tekhnaeraav <[email protected]>
1 parent 1ecb3dd commit 2f4e7ac

File tree

16 files changed

+1384
-478
lines changed

16 files changed

+1384
-478
lines changed

Cargo.lock

Lines changed: 27 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

framework_crates/bones_framework/src/networking.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Networked multi-player plugin.
22

3-
Jumpy uses a Peer-to-Peer, rollback networking model built on [GGRS].
3+
Bones uses a Peer-to-Peer, rollback networking model built on [GGRS].
44

55
Messages are serialized/deserialized to a binary representation using [`serde`] and the [`postcard`]
66
crate.

framework_crates/bones_framework/src/networking.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use crate::input::PlayerControls as PlayerControlsTrait;
2323
pub mod input;
2424
pub mod lan;
2525
pub mod online;
26+
pub mod online_lobby;
27+
pub mod online_matchmaking;
2628
pub mod proto;
2729
pub mod socket;
2830

Lines changed: 36 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,54 @@
1-
Contains the online matchmaker.
1+
# Matchmaking
22

3-
## Matchmaking
3+
For online matchmaking, we use a centralized matchmaking server to connect peers to each-other and to forward the peers' network traffic. All connections utilize UDP and the QUIC protocol.
44

5-
For online matchmaking, we use a centralized matchmaking server to connect peers to each-other and
6-
to forward the peers' network traffic. All connections utilize UDP and the QUIC protocol.
5+
The matchmaking server is implemented in the [`bones_matchmaker`] crate. It binds to a single UDP port and listens for client connections. QUIC's multiplexing capabilities allow the server to handle any number of clients on this single port.
76

8-
In order to establish the peer connections we use a matchmaking server implemented in the
9-
[`bones_matchmaker`] crate. This server binds one UDP port and listens for client connections.
10-
Because QUIC supports mutliplexing connections, we are able to handle any number of clients on a
11-
single UDP port.
7+
Once a match starts, client traffic is proxied through the matchmaking server. While not true peer-to-peer networking, clients logically send messages to each other, with the server acting as an intermediary.
128

13-
All client traffic is proxied to other peers through the matchmaking server. In this way it is not
14-
true peer-to-peer networking, but logically, once the match starts, clients are sending messages to
15-
each-other, and the server doesn't take part in the match protocol.
9+
Pros of this approach:
10+
- Reduced connections per peer (one connection to the matchmaker only)
11+
- Client IP addresses are hidden from each other
12+
- Easier to bypass firewalls and NATs
13+
- Simplified connection process
1614

17-
Having the matchmaker proxy client messages has the following pros and cons:
15+
Cons:
16+
- Increased server bandwidth usage
17+
- Additional network hop between peers, potentially increasing latency
1818

19-
**Cons:**
20-
21-
- It uses up more of the matchmaking server's bandwidth
22-
- It adds an extra network hop between peers, increasing latency.
23-
24-
**Pros:**
25-
26-
- It reduces the number of connections each peer needs to make. Each peer only holds one
27-
connection to the matchmaking server and nothing else.
28-
- It hides the IP addresses of clients from each-other. This is an important privacy feature.
29-
- It avoids a number of difficulties that you may run into while trying to establish true
30-
peer-to-peer connections, and makes it much easier to bypass firewalls, NATs, etc.
31-
32-
This doesn't prevent us from supporting true peer-to-peer connections in the future, though.
33-
Similarly, another scenario we will support in the future is LAN games that you can join without
34-
needing a matchmaking server.
19+
This design doesn't preclude future support for true peer-to-peer connections or LAN games without a matchmaker.
3520

3621
[`bones_matchmaker`]: https://github.com/fishfolk/bones/tree/main/crates/bones_matchmaker
3722

38-
### Matchmaking Protocol
39-
40-
> **ℹ️ Note:** This is meant as an overview and is not an exact specification of the matchmaking
41-
> protocol.
42-
43-
#### Initial Connection
44-
45-
When a client connects to the matchmaking server, the very first thing it will do is send a
46-
[`RequestMatch`][crate::external::bones_matchmaker_proto::MatchmakerRequest::RequestMatch] message
47-
to the server over a reliable channel.
48-
49-
This message contains the [`MatchInfo`] that tells the server how many players the client wants to
50-
connect to for the match, along with an arbitrary byte sequence for the `match_data`.
51-
52-
In order for players to end up in the same match as each-other, they must specify the _exact_ same
53-
`MatchInfo`, including the `match_data`. We use the `match_data` as a way to specify which game mode
54-
and parameters, etc. that the player wants to connect to, so that all the players that are connected
55-
to each-other are playing the same mode.
56-
57-
The `match_data` also contains the game name and version. Because the matchmaker does not take part
58-
in the match protocol itself, just the matchmaking protocol, **this makes the matchmaking server
59-
game agnostic**. Different games can connect to the same matchmaking server, and they can make sure
60-
they are only connected to players playing the same game, by specifying a unique `match_data`.
61-
62-
> **Note:** To be clear, the game implementation sets the `match_data` for players. Players are
63-
> never exposed directly to the concept of the `match_data`.
23+
## Matchmaking Protocol
6424

65-
#### Waiting For Players
25+
### Initial Connection
6626

67-
After the initial connection and match request, the server will send the client an
68-
[`Accepted`][crate::external::bones_matchmaker_proto::MatchmakerResponse::Accepted] message.
27+
1. The client connects to the matchmaking server.
28+
2. The client sends a [`RequestMatchmaking`][crate::external::bones_matchmaker_proto::MatchmakerRequest::RequestMatchmaking] message over a reliable channel.
29+
3. This message contains [`MatchInfo`] with:
30+
- The desired number of players
31+
- A `game_id` to identify the game
32+
- `match_data` (arbitrary bytes for game mode, parameters, etc.)
33+
- `player_idx_assignment` to specify how player ids should be assigned (ie. randomly assign a side for a pvp match)
6934

70-
If the waiting room for that match already has the desired number of players in it, the server will
71-
then respond immediately with a
72-
[`Success`][crate::external::bones_matchmaker_proto::MatchmakerResponse::Success] message. This
73-
message comes with:
35+
Players must specify identical `MatchInfo` to be matched together. The `match_data` ensures players are connected for the same game mode and version.
7436

75-
- a `random_seed` that can be used by all clients to generate deterministic random numbers, and
76-
- a `player_idx` that tells the client _which_ player in the match it is. This is used throughout
77-
the game to keep track of the players, and is between `0` and `player_count - 1`.
37+
### Waiting for Players
7838

79-
#### In the Match
39+
1. The server responds with an [`Accepted`][crate::external::bones_matchmaker_proto::MatchmakerResponse::Accepted] message.
40+
2. While waiting, the server may send [`MatchmakingUpdate`][crate::external::bones_matchmaker_proto::MatchmakerResponse::MatchmakingUpdate] messages with the current player count.
41+
3. When the desired number of players is reached, the server sends a [`Success`][crate::external::bones_matchmaker_proto::MatchmakerResponse::Success] message containing:
42+
- A `random_seed` for deterministic random number generation
43+
- The client's `player_idx`
44+
- The total `player_count`
45+
- A list of `player_ids` with their network addresses
8046

81-
Immediately after the desired number of clients have joined and the `Success` message has been sent
82-
to all players, the matchmaker goes into proxy mode for all clients in the match.
47+
### In the Match
8348

84-
Once in proxy mode, the server listens for
85-
[`SendProxyMessage`][crate::external::bones_matchmaker_proto::SendProxyMessage]s from clients. Each
86-
message simply specifies a [`TargetClient`][crate::external::bones_matchmaker_proto::TargetClient] (
87-
either a specific client or all of them ), and a binary message data.
49+
Once all players have received the `Success` message, the matchmaker enters proxy mode:
8850

89-
Once it a `SendProxyMessage` it will send it to the target client, which will receive it in the form
90-
of a [`RecvProxyMessage`][crate::external::bones_matchmaker_proto::RecvProxyMessage], containing the
91-
message data, and the index of the client that sent the message.
51+
1. Clients send [`SendProxyMessage`][crate::external::bones_matchmaker_proto::SendProxyMessage]s to the server, specifying a target client (or all clients) and the message data.
52+
2. The server forwards these as [`RecvProxyMessage`][crate::external::bones_matchmaker_proto::RecvProxyMessage]s to the target client(s), including the sender's player index.
9253

93-
The matchmaking server supports forwarding both reliable and unreliable message in this way,
94-
allowing the game to chose any kind of protocol it sees fit to synchronize the match data.
54+
The matchmaker supports both reliable and unreliable message forwarding, allowing the game to implement its preferred synchronization protocol.

0 commit comments

Comments
 (0)