diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts
index 2401c6d3a..e7d709c12 100644
--- a/src/client/HostLobbyModal.ts
+++ b/src/client/HostLobbyModal.ts
@@ -14,6 +14,7 @@ import {
UnitType,
mapCategories,
} from "../core/game/Game";
+import { getCompactMapNationCount } from "../core/game/NationCreation";
import { UserSettings } from "../core/game/UserSettings";
import {
ClientInfo,
@@ -27,7 +28,7 @@ import "./components/baseComponents/Modal";
import { BaseModal } from "./components/BaseModal";
import "./components/Difficulties";
import "./components/FluentSlider";
-import "./components/LobbyPlayerView";
+import "./components/LobbyTeamView";
import "./components/Maps";
import { modalHeader } from "./components/ui/ModalHeader";
import { crazyGamesSDK } from "./CrazyGamesSDK";
@@ -933,16 +934,33 @@ export class HostLobbyModal extends BaseModal {
- this.kickPlayer(clientID)}
- >
+
+
+
+ ${this.clients.length}
+ ${this.clients.length === 1
+ ? translateText("host_modal.player")
+ : translateText("host_modal.players")}
+ •
+ ${this.getEffectiveNationCount()}
+ ${this.getEffectiveNationCount() === 1
+ ? translateText("host_modal.nation_player")
+ : translateText("host_modal.nation_players")}
+
+
+
+
this.kickPlayer(clientID)}
+ >
+
@@ -1420,22 +1438,31 @@ export class HostLobbyModal extends BaseModal {
}
private async loadNationCount() {
- const currentMap = this.selectedMap;
try {
- const mapData = this.mapLoader.getMapData(currentMap);
+ const mapData = this.mapLoader.getMapData(this.selectedMap);
const manifest = await mapData.manifest();
- // Only update if the map hasn't changed
- if (this.selectedMap === currentMap) {
- this.nationCount = manifest.nations.length;
- }
+ this.nationCount = manifest.nations.length;
} catch (error) {
console.warn("Failed to load nation count", error);
- // Only update if the map hasn't changed
- if (this.selectedMap === currentMap) {
- this.nationCount = 0;
- }
+ this.nationCount = 0;
}
}
+
+ /**
+ * Returns the effective nation count for display purposes.
+ * In HumansVsNations mode, this equals the number of human players.
+ * For compact maps, only 25% of nations are used.
+ * Otherwise, it uses the manifest nation count (or 0 if nations are disabled).
+ */
+ private getEffectiveNationCount(): number {
+ if (this.disableNations) {
+ return 0;
+ }
+ if (this.gameMode === GameMode.Team && this.teamCount === HumansVsNations) {
+ return this.clients.length;
+ }
+ return getCompactMapNationCount(this.nationCount, this.compactMap);
+ }
}
async function createLobby(creatorClientID: string): Promise {
diff --git a/src/client/JoinPrivateLobbyModal.ts b/src/client/JoinPrivateLobbyModal.ts
index a618a9ccc..cb65b428f 100644
--- a/src/client/JoinPrivateLobbyModal.ts
+++ b/src/client/JoinPrivateLobbyModal.ts
@@ -10,14 +10,13 @@ import {
} from "../core/Schemas";
import { generateID } from "../core/Util";
import { getServerConfigFromClient } from "../core/configuration/ConfigLoader";
-import { GameMapSize, GameMode } from "../core/game/Game";
+import { GameMode } from "../core/game/Game";
import { UserSettings } from "../core/game/UserSettings";
import { getApiBase } from "./Api";
import { JoinLobbyEvent } from "./Main";
-import { terrainMapFileLoader } from "./TerrainMapFileLoader";
import { BaseModal } from "./components/BaseModal";
import "./components/Difficulties";
-import "./components/LobbyPlayerView";
+import "./components/LobbyTeamView";
import { modalHeader } from "./components/ui/ModalHeader";
@customElement("join-private-lobby-modal")
export class JoinPrivateLobbyModal extends BaseModal {
@@ -30,11 +29,9 @@ export class JoinPrivateLobbyModal extends BaseModal {
@state() private lobbyIdVisible: boolean = true;
@state() private copySuccess: boolean = false;
@state() private currentLobbyId: string = "";
- @state() private nationCount: number = 0;
private playersInterval: NodeJS.Timeout | null = null;
private userSettings: UserSettings = new UserSettings();
- private mapLoader = terrainMapFileLoader;
private leaveLobbyOnClose = true;
@@ -183,17 +180,26 @@ export class JoinPrivateLobbyModal extends BaseModal {
${this.renderGameConfig()}
${this.hasJoined && this.players.length > 0
? html`
-
+
+
+
+ ${this.players.length}
+ ${this.players.length === 1
+ ? translateText("private_lobby.player")
+ : translateText("private_lobby.players")}
+
+
+
+
+
`
: ""}
@@ -381,7 +387,6 @@ export class JoinPrivateLobbyModal extends BaseModal {
this.hasJoined = false;
this.message = "";
this.currentLobbyId = "";
- this.nationCount = 0;
this.leaveLobbyOnClose = true;
}
@@ -607,38 +612,11 @@ export class JoinPrivateLobbyModal extends BaseModal {
this.lobbyCreatorClientID = data.clients?.[0]?.clientID ?? null;
this.players = data.clients ?? [];
if (data.gameConfig) {
- const mapChanged =
- this.gameConfig?.gameMap !== data.gameConfig.gameMap;
this.gameConfig = data.gameConfig;
- if (mapChanged) {
- this.loadNationCount();
- }
}
})
.catch((error) => {
console.error("Error polling players:", error);
});
}
-
- private async loadNationCount() {
- if (!this.gameConfig) {
- this.nationCount = 0;
- return;
- }
- const currentMap = this.gameConfig.gameMap;
- try {
- const mapData = this.mapLoader.getMapData(currentMap);
- const manifest = await mapData.manifest();
- // Only update if the map hasn't changed
- if (this.gameConfig?.gameMap === currentMap) {
- this.nationCount = manifest.nations.length;
- }
- } catch (error) {
- console.warn("Failed to load nation count", error);
- // Only update if the map hasn't changed
- if (this.gameConfig?.gameMap === currentMap) {
- this.nationCount = 0;
- }
- }
- }
}
diff --git a/src/client/components/LobbyPlayerView.ts b/src/client/components/LobbyTeamView.ts
similarity index 83%
rename from src/client/components/LobbyPlayerView.ts
rename to src/client/components/LobbyTeamView.ts
index 2bcac3108..d85105c4b 100644
--- a/src/client/components/LobbyPlayerView.ts
+++ b/src/client/components/LobbyTeamView.ts
@@ -13,7 +13,6 @@ import {
Team,
Trios,
} from "../../core/game/Game";
-import { getCompactMapNationCount } from "../../core/game/NationCreation";
import { assignTeamsLobbyPreview } from "../../core/game/TeamAssignment";
import { ClientInfo, TeamCountConfig } from "../../core/Schemas";
import { translateText } from "../Utils";
@@ -23,7 +22,7 @@ export interface TeamPreviewData {
players: ClientInfo[];
}
-@customElement("lobby-player-view")
+@customElement("lobby-team-view")
export class LobbyTeamView extends LitElement {
@property({ type: String }) gameMode: GameMode = GameMode.FFA;
@property({ type: Array }) clients: ClientInfo[] = [];
@@ -33,8 +32,6 @@ export class LobbyTeamView extends LitElement {
@property({ attribute: "team-count" }) teamCount: TeamCountConfig = 2;
@property({ type: Function }) onKickPlayer?: (clientID: string) => void;
@property({ type: Number }) nationCount: number = 0;
- @property({ type: Boolean }) disableNations: boolean = false;
- @property({ type: Boolean }) isCompactMap: boolean = false;
private theme: PastelTheme = new PastelTheme();
@state() private showTeamColors: boolean = false;
@@ -55,32 +52,11 @@ export class LobbyTeamView extends LitElement {
}
render() {
- return html`
-
-
-
- ${this.clients.length}
- ${this.clients.length === 1
- ? translateText("host_modal.player")
- : translateText("host_modal.players")}
- •
- ${this.getEffectiveNationCount()}
- ${this.getEffectiveNationCount() === 1
- ? translateText("host_modal.nation_player")
- : translateText("host_modal.nation_players")}
-
-
-
- ${this.gameMode === GameMode.Team
- ? this.renderTeamMode()
- : this.renderFreeForAll()}
-
-
- `;
+ return html`
+ ${this.gameMode === GameMode.Team
+ ? this.renderTeamMode()
+ : this.renderFreeForAll()}
+
`;
}
createRenderRoot() {
@@ -172,15 +148,14 @@ export class LobbyTeamView extends LitElement {
}
private renderTeamCard(preview: TeamPreviewData, isEmpty: boolean = false) {
- const effectiveNationCount = this.getEffectiveNationCount();
const displayCount =
preview.team === ColoredTeams.Nations
- ? effectiveNationCount
+ ? this.nationCount
: preview.players.length;
const maxTeamSize =
preview.team === ColoredTeams.Nations
- ? effectiveNationCount
+ ? this.nationCount
: this.teamMaxSize;
return html`
@@ -333,20 +308,4 @@ export class LobbyTeamView extends LitElement {
players: buckets.get(t) ?? [],
}));
}
-
- /**
- * Returns the effective nation count for display purposes.
- * In HumansVsNations mode, this equals the number of human players.
- * For compact maps, only 25% of nations are used.
- * Otherwise, it uses the manifest nation count (or 0 if nations are disabled).
- */
- private getEffectiveNationCount(): number {
- if (this.disableNations) {
- return 0;
- }
- if (this.gameMode === GameMode.Team && this.teamCount === HumansVsNations) {
- return this.clients.length;
- }
- return getCompactMapNationCount(this.nationCount, this.isCompactMap);
- }
}
diff --git a/src/client/styles.css b/src/client/styles.css
index 7023676e8..9873cd4f0 100644
--- a/src/client/styles.css
+++ b/src/client/styles.css
@@ -546,6 +546,7 @@ label.option-card:hover {
flex-wrap: wrap;
gap: 8px;
justify-content: center;
+ padding: 0 16px;
}
/* News Button Notification */
diff --git a/src/server/MapPlaylist.ts b/src/server/MapPlaylist.ts
index 97b23f0e4..c4430e332 100644
--- a/src/server/MapPlaylist.ts
+++ b/src/server/MapPlaylist.ts
@@ -127,7 +127,9 @@ export class MapPlaylist {
publicGameModifiers: { isCompact, isRandomSpawn, startingGold },
startingGold,
difficulty:
- playerTeams === HumansVsNations ? Difficulty.Hard : Difficulty.Easy,
+ playerTeams === HumansVsNations
+ ? Difficulty.Impossible
+ : Difficulty.Easy,
infiniteGold: false,
infiniteTroops: false,
maxTimerValue: undefined,