diff --git a/src/lib/ui/components/ServerCard.svelte b/src/lib/ui/components/ServerCard.svelte
index e710c7c..637a626 100644
--- a/src/lib/ui/components/ServerCard.svelte
+++ b/src/lib/ui/components/ServerCard.svelte
@@ -65,7 +65,8 @@
const currentRound = $derived(!gameEndedAt ? (round !== undefined ? round : reportedRound) : null);
const gameElapsed = $derived(gameStartedAt && !gameEndedAt ? elapsedSince(gameStartedAt, $uiNow) : null);
const emptyElapsed = $derived(elapsedSince(inactiveSince, $uiNow));
- const knownCapacity = $derived(capacity !== null && Number.isFinite(capacity) && capacity > 0 ? capacity : null);
+ // These lobbies have four slots when the live status omits the limit.
+ const displayCapacity = $derived(capacity !== null && Number.isSafeInteger(capacity) && capacity > 0 ? capacity : 4);
const cardStyle = $derived(`view-transition-name: server-${name.replace(/[^a-z0-9_-]/gi, '-')};`);
@@ -90,7 +91,7 @@
{#if showMap}
{health === 'online' ? 'Current map' : 'Last map'}: {mapLabel}
{/if}
{#if health === 'online'}
- - Players
- {players ?? '—'}/{knownCapacity ?? '?'}
+ - Players
- {players ?? '—'}/{displayCapacity}
- Round
- {currentRound ?? '—'}
- Match time
- {gameElapsed ?? '—'}
diff --git a/tests/unit/ui-server-card.test.ts b/tests/unit/ui-server-card.test.ts
index c8e7733..97d2a18 100644
--- a/tests/unit/ui-server-card.test.ts
+++ b/tests/unit/ui-server-card.test.ts
@@ -29,11 +29,14 @@ describe('compact server cards', () => {
expect(body).not.toMatch(/Last seen|Last reported|Zombies Classic|>Active);
});
- it('keeps capacity unknown when unavailable and never invents a four-player limit', () => {
- const body = html({ players: 2, capacity: null });
- expect(body).toContain('title="Capacity unavailable"');
- expect(body).toMatch(/>2]*>\/\?<\/span>/);
- expect(body).not.toContain('/4');
+ it('defaults to four lobby slots when capacity is unavailable, while preserving a reported limit', () => {
+ for (const capacity of [null, undefined, 0, -1, 4.5, NaN, Infinity]) {
+ const body = html({ players: 2, capacity });
+ expect(body).toContain('title="4 player capacity"');
+ expect(body).toMatch(/>2]*>\/4<\/span>/);
+ expect(body).not.toContain('/?');
+ }
+ expect(html({ players: 2, capacity: 8 })).toMatch(/>2]*>\/8<\/span>/);
});
it('uses the newest fresh report while respecting explicit round data and match boundaries', () => {