Merge branch 'main' into 2393-show-boat-troops-as-attacking-troops

This commit is contained in:
Rj Manhas
2025-11-10 22:41:03 -07:00
committed by GitHub
8 changed files with 26 additions and 0 deletions
+1
View File
@@ -245,6 +245,7 @@ export class ClientGameRunner {
startTime(),
Date.now(),
update.winner,
this.lobby.gameStartInfo.lobbyCreatedAt,
);
endGame(record);
}
+1
View File
@@ -84,6 +84,7 @@ export class LocalServer {
type: "start",
gameStartInfo: this.lobbyConfig.gameStartInfo,
turns: [],
lobbyCreatedAt: this.lobbyConfig.gameStartInfo.lobbyCreatedAt,
} satisfies ServerStartGameMessage);
}
+1
View File
@@ -597,6 +597,7 @@ export class SinglePlayerModal extends LitElement {
disableNPCs: this.disableNPCs,
}),
},
lobbyCreatedAt: Date.now(), // ms; server should be authoritative in MP
},
} satisfies JoinLobbyEvent,
bubbles: true,
+3
View File
@@ -428,6 +428,7 @@ export const PlayerSchema = z.object({
export const GameStartInfoSchema = z.object({
gameID: ID,
lobbyCreatedAt: z.number(),
config: GameConfigSchema,
players: PlayerSchema.array(),
});
@@ -464,6 +465,7 @@ export const ServerStartGameMessageSchema = z.object({
// Turns the client missed if they are late to the game.
turns: TurnSchema.array(),
gameStartInfo: GameStartInfoSchema,
lobbyCreatedAt: z.number(),
});
export const ServerDesyncSchema = z.object({
@@ -560,6 +562,7 @@ export const GameEndInfoSchema = GameStartInfoSchema.extend({
duration: z.number().nonnegative(),
num_turns: z.number(),
winner: WinnerSchema,
lobbyFillTime: z.number().nonnegative(),
});
export type GameEndInfo = z.infer<typeof GameEndInfoSchema>;
+12
View File
@@ -194,15 +194,27 @@ export function createPartialGameRecord(
start: number,
end: number,
winner: Winner,
// lobby creation time (ms). Defaults to start time for singleplayer.
lobbyCreatedAt?: number,
): PartialGameRecord {
const duration = Math.floor((end - start) / 1000);
const num_turns = allTurns.length;
const turns = allTurns.filter(
(t) => t.intents.length !== 0 || t.hash !== undefined,
);
// Use start time as lobby creation time for singleplayer
const actualLobbyCreatedAt = lobbyCreatedAt ?? start;
const lobbyFillTime = Math.max(
0,
start - Math.min(actualLobbyCreatedAt, start),
);
const record: PartialGameRecord = {
info: {
gameID,
lobbyCreatedAt: actualLobbyCreatedAt,
lobbyFillTime,
config,
players,
start,
+3
View File
@@ -23,6 +23,9 @@ export interface Stats {
// Player betrays another player
betray(player: Player): void;
// Time between lobby creation and game start (ms)
lobbyFillTime(fillTimeMs: number): void;
// Player sends a trade ship to target
boatSendTrade(player: Player, target: Player): void;
+2
View File
@@ -264,4 +264,6 @@ export class StatsImpl implements Stats {
playerKilled(player: Player, tick: number): void {
this._addPlayerKilled(player, tick);
}
lobbyFillTime(fillTimeMs: number): void {}
}
+3
View File
@@ -401,6 +401,7 @@ export class GameServer {
const result = GameStartInfoSchema.safeParse({
gameID: this.id,
lobbyCreatedAt: this.createdAt,
config: this.gameConfig,
players: this.activeClients.map((c) => ({
username: c.username,
@@ -439,6 +440,7 @@ export class GameServer {
type: "start",
turns: this.turns.slice(lastTurn),
gameStartInfo: this.gameStartInfo,
lobbyCreatedAt: this.createdAt,
} satisfies ServerStartGameMessage),
);
} catch (error) {
@@ -706,6 +708,7 @@ export class GameServer {
this._startTime ?? 0,
Date.now(),
this.winner?.winner,
this.createdAt,
),
),
);