From 3e4d618aa7831c0b4818ca617a1ed66c2c2fc0a7 Mon Sep 17 00:00:00 2001
From: Alexa <53471801+Alexa-RR@users.noreply.github.com>
Date: Sun, 28 Jun 2026 01:35:57 +0300
Subject: [PATCH] feat: Matchmade sessions respect room's subroom Max Player
Count
GameSessionService previously hardcoded MaxCapacity=8 for new sessions,
fragmenting matchmade joiners 8-per-instance regardless of the host's
'Max Player Count in This Subroom' slider. New sessions now resolve the
room's entry subroom (lowest OrderIndex) RoomSceneEntity.MaxPlayers,
clamped 1-80, falling back to 8 for system rooms (dorm GUID roomIds).
---
DorkNet.Server/Services/GameSessionService.cs | 29 ++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/DorkNet.Server/Services/GameSessionService.cs b/DorkNet.Server/Services/GameSessionService.cs
index 71d2aab..0c9c4ea 100644
--- a/DorkNet.Server/Services/GameSessionService.cs
+++ b/DorkNet.Server/Services/GameSessionService.cs
@@ -64,7 +64,12 @@ public class GameSessionService(DorkNetDbContext db)
// in, so we save once with a placeholder, then patch and save
// again. Two SaveChangesAsync calls is cheap at our QPS.
PhotonRoomName = "pending",
- MaxCapacity = 8,
+ // Track the room's "Max Player Count in This Subroom" slider
+ // instead of a hardcoded 8, so matchmade joiners fill the room to
+ // the host's chosen limit rather than fragmenting into a new
+ // instance every 8 players. (Existing sessions keep whatever cap
+ // they were created with.)
+ MaxCapacity = await ResolveRoomMaxCapacityAsync(effectiveRoom),
PlayerCount = 1,
CreatedAt = DateTime.UtcNow,
};
@@ -75,6 +80,28 @@ public class GameSessionService(DorkNetDbContext db)
return ToDto(session);
}
+ // Default session cap when we can't resolve a room-specific value (system
+ // rooms like the dorm use a GUID roomId that doesn't map to a RoomEntity).
+ private const int DefaultMaxCapacity = 8;
+
+ /// Resolve a new session's capacity from the room's entry
+ /// subroom (lowest OrderIndex)
+ /// — the value the in-game "Max Player Count in This Subroom" slider
+ /// writes. Matchmade sessions land in the entry subroom, so its cap is the
+ /// right ceiling. GameSession roomIds are the room's numeric Id as a
+ /// string for user rooms; non-numeric (dorm GUID, etc.) → default. Clamped
+ /// to a sane Photon ceiling.
+ private async Task ResolveRoomMaxCapacityAsync(string roomId)
+ {
+ if (!long.TryParse(roomId, out var roomLongId)) return DefaultMaxCapacity;
+ var max = await db.RoomScenes
+ .Where(s => s.RoomId == roomLongId)
+ .OrderBy(s => s.OrderIndex)
+ .Select(s => (int?)s.MaxPlayers)
+ .FirstOrDefaultAsync();
+ return max is int v && v > 0 ? Math.Clamp(v, 1, 80) : DefaultMaxCapacity;
+ }
+
public async Task GetByIdAsync(long id)
{
var s = await db.GameSessions.AsNoTracking()