Summary
I'd like to add an optional ELO range to the custom match creation flow in GameClient, so a host can restrict their lobby to players within a configured rating window. The check would be enforced server-side here in Services, on the lobby join endpoint, so it can't be bypassed by a modified client. This issue is to coordinate the design before any PRs are opened.
Motivation
Custom lobbies today have no skill-matching at all — only QuickMatch uses ELO. Hosts who want a "1200-1800 only" practice lobby currently have to police it manually after the fact. A first-class field would let lobbies self-select players at their level and reduce mismatches.
Proposed shape (open to feedback)
GameClient side
- Two new fields in
PopupHostGame.wnd (min ELO, max ELO), with sane "no limit" defaults so existing host flow is unchanged.
createGame() in PopupHostGame.cpp reads them and passes through OnlineServices_LobbyInterface::CreateLobby().
LobbyEntry extended with the new fields so they round-trip via the JSON request.
- On join failure due to ELO, surface a clear message: "This lobby requires ELO X–Y; yours is Z."
- Mirror to the
Generals/ tree per CONTRIBUTING.md.
Services side
Lobby model gains MinElo / MaxElo (sentinel -1 = no limit, or a separate EloFilterMode enum — happy to follow whichever pattern you'd prefer).
LobbiesController POST: deserialize from request body, validate (min ≤ max, both ≥ 0, both ≤ some sane ceiling), persist on the Lobby instance.
LobbyController PUT (Put, the join handler): after the existing password check (~line 791), look up the joining user's ELO via the existing PlayerStats path, compare to lobby.MinElo/MaxElo, and return a new status (proposing 403 Forbidden) with the lobby's range and the joiner's rating in the response body if the check fails.
- No change to the ELO scoring system itself — read-only access to existing
Database.PlayerStats.
Open questions for maintainers
- UI semantics: min+max range, or just a single threshold? (I'm leaning min+max because it's strictly more flexible and the server logic is the same.)
- Unrated players (
elo_num_matches < N): always allow? always block? host-configurable?
- Lobby browser display: show the ELO window in the listing so players can self-select before clicking?
- Status code: is
403 acceptable, or do you prefer reusing 406 (currently "lobby full") with a discriminator in the body?
- Persistence: should the host's last-used ELO range be saved in
UserLobbyPreferences like other custom-game prefs?
- Repo question: is
GameClient still the right place to add new custom-lobby UI, or should new feature work be going into SuperHackers_GO? I want to make sure I PR the active codebase.
Happy to split this into separate Services and GameClient PRs or land them in coordination — whatever works best for your review process. I'll wait for guidance here before writing any code.
Summary
I'd like to add an optional ELO range to the custom match creation flow in
GameClient, so a host can restrict their lobby to players within a configured rating window. The check would be enforced server-side here inServices, on the lobby join endpoint, so it can't be bypassed by a modified client. This issue is to coordinate the design before any PRs are opened.Motivation
Custom lobbies today have no skill-matching at all — only QuickMatch uses ELO. Hosts who want a "1200-1800 only" practice lobby currently have to police it manually after the fact. A first-class field would let lobbies self-select players at their level and reduce mismatches.
Proposed shape (open to feedback)
GameClientsidePopupHostGame.wnd(min ELO, max ELO), with sane "no limit" defaults so existing host flow is unchanged.createGame()inPopupHostGame.cppreads them and passes throughOnlineServices_LobbyInterface::CreateLobby().LobbyEntryextended with the new fields so they round-trip via the JSON request.Generals/tree per CONTRIBUTING.md.ServicessideLobbymodel gainsMinElo/MaxElo(sentinel-1= no limit, or a separateEloFilterModeenum — happy to follow whichever pattern you'd prefer).LobbiesControllerPOST: deserialize from request body, validate (min ≤ max, both ≥ 0, both ≤ some sane ceiling), persist on theLobbyinstance.LobbyControllerPUT (Put, the join handler): after the existing password check (~line 791), look up the joining user's ELO via the existingPlayerStatspath, compare tolobby.MinElo/MaxElo, and return a new status (proposing403 Forbidden) with the lobby's range and the joiner's rating in the response body if the check fails.Database.PlayerStats.Open questions for maintainers
elo_num_matches < N): always allow? always block? host-configurable?403acceptable, or do you prefer reusing406(currently "lobby full") with a discriminator in the body?UserLobbyPreferenceslike other custom-game prefs?GameClientstill the right place to add new custom-lobby UI, or should new feature work be going intoSuperHackers_GO? I want to make sure I PR the active codebase.Happy to split this into separate
ServicesandGameClientPRs or land them in coordination — whatever works best for your review process. I'll wait for guidance here before writing any code.