mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-28 11:54:16 +00:00
feat: timer starts if enough player or enough time (#229)
Avoid these huge lobbies
This commit is contained in:
@@ -88,6 +88,8 @@ export class PublicLobby extends LitElement {
|
||||
const minutes = Math.floor(timeRemaining / 60);
|
||||
const seconds = timeRemaining % 60;
|
||||
const timeDisplay = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
||||
const playersRemainingBeforeMax =
|
||||
lobby.gameConfig.maxPlayers - lobby.numClients;
|
||||
|
||||
return html`
|
||||
<button
|
||||
@@ -118,8 +120,8 @@ export class PublicLobby extends LitElement {
|
||||
</div>
|
||||
<div class="flex flex-col items-start">
|
||||
<div class="text-md font-medium text-blue-100">
|
||||
${lobby.numClients}
|
||||
${lobby.numClients === 1 ? "Player" : "Players"} waiting
|
||||
${lobby.numClients} / ${lobby.gameConfig.maxPlayers} players
|
||||
waiting
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
@@ -129,6 +131,12 @@ export class PublicLobby extends LitElement {
|
||||
${timeDisplay}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-start">
|
||||
<div class="text-md font-medium text-blue-100">
|
||||
Game starts when ${playersRemainingBeforeMax} more players join
|
||||
or in ${timeDisplay} seconds.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -110,6 +110,7 @@ const GameConfigSchema = z.object({
|
||||
infiniteGold: z.boolean(),
|
||||
infiniteTroops: z.boolean(),
|
||||
instantBuild: z.boolean(),
|
||||
maxPlayers: z.number().optional(),
|
||||
});
|
||||
|
||||
const SafeString = z
|
||||
|
||||
@@ -90,7 +90,8 @@ function getServerConfig(gameEnv: string) {
|
||||
export interface ServerConfig {
|
||||
turnIntervalMs(): number;
|
||||
gameCreationRate(highTraffic: boolean): number;
|
||||
lobbyLifetime(highTraffic): number;
|
||||
lobbyLifetime(highTraffic: boolean): number;
|
||||
lobbyMaxPlayers(): number;
|
||||
discordRedirectURI(): string;
|
||||
numWorkers(): number;
|
||||
workerIndex(gameID: GameID): number;
|
||||
|
||||
@@ -54,6 +54,9 @@ export abstract class DefaultServerConfig implements ServerConfig {
|
||||
return 50 * 1000;
|
||||
}
|
||||
}
|
||||
lobbyMaxPlayers(): number {
|
||||
return Math.random() < 0.1 ? 100 : 35;
|
||||
}
|
||||
lobbyLifetime(highTraffic: boolean): number {
|
||||
return this.gameCreationRate(highTraffic) * 2;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ export class DevServerConfig extends DefaultServerConfig {
|
||||
return 5 * 1000;
|
||||
}
|
||||
|
||||
lobbyMaxPlayers(): number {
|
||||
return Math.random() < 0.5 ? 2 : 3;
|
||||
}
|
||||
|
||||
discordRedirectURI(): string {
|
||||
return "http://localhost:3000/auth/callback";
|
||||
}
|
||||
|
||||
@@ -380,7 +380,14 @@ export class GameServer {
|
||||
}
|
||||
}
|
||||
|
||||
if (now - this.createdAt < this.config.lobbyLifetime(this.highTraffic)) {
|
||||
const msSinceCreation = now - this.createdAt;
|
||||
const lessThanLifetime =
|
||||
msSinceCreation < this.config.lobbyLifetime(this.highTraffic);
|
||||
const notEnoughPlayers =
|
||||
this.gameConfig.gameType == GameType.Public &&
|
||||
this.gameConfig.maxPlayers &&
|
||||
this.activeClients.length < this.gameConfig.maxPlayers;
|
||||
if (lessThanLifetime && notEnoughPlayers) {
|
||||
return GamePhase.Lobby;
|
||||
}
|
||||
const warmupOver =
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
GameEnv,
|
||||
getServerConfigFromServer,
|
||||
} from "../core/configuration/Config";
|
||||
import { GameInfo } from "../core/Schemas";
|
||||
import { GameConfig, GameInfo } from "../core/Schemas";
|
||||
import path from "path";
|
||||
import rateLimit from "express-rate-limit";
|
||||
import { fileURLToPath } from "url";
|
||||
@@ -199,7 +199,7 @@ async function fetchLobbies(): Promise<void> {
|
||||
});
|
||||
|
||||
lobbyInfos.forEach((l) => {
|
||||
if (l.msUntilStart <= 250) {
|
||||
if (l.msUntilStart <= 250 || l.gameConfig.maxPlayers == l.numClients) {
|
||||
publicLobbyIDs.delete(l.gameID);
|
||||
}
|
||||
});
|
||||
@@ -217,6 +217,7 @@ async function schedulePublicGame() {
|
||||
// Create the default public game config (from your GameManager)
|
||||
const defaultGameConfig = {
|
||||
gameMap: getNextMap(),
|
||||
maxPlayers: config.lobbyMaxPlayers(),
|
||||
gameType: GameType.Public,
|
||||
difficulty: Difficulty.Medium,
|
||||
infiniteGold: false,
|
||||
@@ -224,7 +225,7 @@ async function schedulePublicGame() {
|
||||
instantBuild: false,
|
||||
disableNPCs: false,
|
||||
bots: 400,
|
||||
};
|
||||
} as GameConfig;
|
||||
|
||||
const workerPath = config.workerPath(gameID);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user