diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts
index ee52675a5..f7a55cc4f 100644
--- a/src/client/HostLobbyModal.ts
+++ b/src/client/HostLobbyModal.ts
@@ -167,13 +167,13 @@ export class HostLobbyModal extends LitElement {
}
private async handleMapChange(e: Event) {
- this.selectedMap = Number((e.target as HTMLSelectElement).value) as GameMap;
+ this.selectedMap = String((e.target as HTMLSelectElement).value) as GameMap;
console.log(`updating map to ${this.selectedMap}`)
this.putGameConfig()
}
private async handleDifficultyChange(e: Event) {
- this.selectedDiffculty = Number((e.target as HTMLSelectElement).value) as Difficulty;
+ this.selectedDiffculty = String((e.target as HTMLSelectElement).value) as Difficulty;
console.log(`updating difficulty to ${this.selectedDiffculty}`)
this.putGameConfig()
}
diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts
index b2810bd39..a4fbfb759 100644
--- a/src/client/SinglePlayerModal.ts
+++ b/src/client/SinglePlayerModal.ts
@@ -84,7 +84,7 @@ export class SinglePlayerModal extends LitElement {
.filter(([key]) => isNaN(Number(key)))
.map(([key, value]) => html`
`)}
@@ -96,7 +96,7 @@ export class SinglePlayerModal extends LitElement {
.filter(([key]) => isNaN(Number(key)))
.map(([key, value]) => html`
`)}
@@ -117,10 +117,10 @@ export class SinglePlayerModal extends LitElement {
}
private handleMapChange(e: Event) {
- this.selectedMap = Number((e.target as HTMLSelectElement).value) as GameMap;
+ this.selectedMap = String((e.target as HTMLSelectElement).value) as GameMap;
}
private handleDifficultyChange(e: Event) {
- this.selectedDifficulty = Number((e.target as HTMLSelectElement).value) as Difficulty;
+ this.selectedDifficulty = String((e.target as HTMLSelectElement).value) as Difficulty;
}
private startGame() {
console.log(`Starting single player game with map: ${GameMap[this.selectedMap]}`);
diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts
index 8b22023f5..262539116 100644
--- a/src/core/Schemas.ts
+++ b/src/core/Schemas.ts
@@ -242,5 +242,6 @@ export const GameRecordSchema = z.object({
durationSeconds: z.number(),
date: z.string(),
usernames: z.array(z.string()),
+ num_turns: z.number(),
turns: z.array(TurnSchema)
})
\ No newline at end of file
diff --git a/src/core/Util.ts b/src/core/Util.ts
index 9873d9693..39fcdadf7 100644
--- a/src/core/Util.ts
+++ b/src/core/Util.ts
@@ -246,6 +246,7 @@ export function CreateGameRecord(id: GameID, gameConfig: GameConfig, turns: Turn
}
record.usernames = Array.from(usernames)
record.durationSeconds = Math.floor((record.endTimestampMS - record.startTimestampMS) / 1000)
+ record.num_turns = turns.length
return record;
}
diff --git a/src/core/configuration/Config.ts b/src/core/configuration/Config.ts
index 30cf8854a..d08524820 100644
--- a/src/core/configuration/Config.ts
+++ b/src/core/configuration/Config.ts
@@ -1,4 +1,4 @@
-import { GameType, Gold, Player, PlayerID, PlayerInfo, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game";
+import { Difficulty, GameType, Gold, Player, PlayerID, PlayerInfo, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game";
import { Colord, colord } from "colord";
import { devConfig } from "./DevConfig";
import { defaultConfig } from "./DefaultConfig";
@@ -64,6 +64,7 @@ export interface Config {
defensePostRange(): number
defensePostDefenseBonus(): number
falloutDefenseModifier(): number
+ difficultyModifier(difficulty: Difficulty): number
}
export interface Theme {
diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts
index 5a1f84914..6faf08363 100644
--- a/src/core/configuration/DefaultConfig.ts
+++ b/src/core/configuration/DefaultConfig.ts
@@ -1,4 +1,4 @@
-import { GameType, Gold, Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game";
+import { Difficulty, GameType, Gold, Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tick, Tile, Unit, UnitInfo, UnitType } from "../game/Game";
import { GameID } from "../Schemas";
import { assertNever, distSort, manhattanDist, simpleHash, within } from "../Util";
import { Config, Theme } from "./Config";
@@ -7,6 +7,19 @@ import { pastelTheme } from "./PastelTheme";
export class DefaultConfig implements Config {
+ difficultyModifier(difficulty: Difficulty): number {
+ switch (difficulty) {
+ case Difficulty.Easy:
+ return 1
+ case Difficulty.Medium:
+ return 3
+ case Difficulty.Hard:
+ return 9
+ case Difficulty.Impossible:
+ return 18
+ }
+ }
+
cityPopulationIncrease(): number {
return 250_000
diff --git a/src/core/execution/ExecutionManager.ts b/src/core/execution/ExecutionManager.ts
index 4bfbdfdee..b1811b056 100644
--- a/src/core/execution/ExecutionManager.ts
+++ b/src/core/execution/ExecutionManager.ts
@@ -125,7 +125,7 @@ export class Executor {
this.random.nextID()
),
nation.cell,
- nation.strength * this.gs.gameConfig().difficulty
+ nation.strength * this.gs.config().difficultyModifier(this.gs.gameConfig().difficulty)
))
}
return execs
diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts
index 29467f096..9313c2150 100644
--- a/src/core/game/Game.ts
+++ b/src/core/game/Game.ts
@@ -11,24 +11,24 @@ export type Gold = number
export const AllPlayers = "AllPlayers" as const;
export enum Difficulty {
- Easy = 1,
- Medium = 3,
- Hard = 9,
- Impossible = 18,
+ Easy = "Easy",
+ Medium = "Medium",
+ Hard = "Hard",
+ Impossible = "Impossible",
}
export enum GameMap {
- World,
- Europe,
- Mena,
- NorthAmerica,
- Oceania
+ World = "World",
+ Europe = "Europe",
+ Mena = "Mena",
+ NorthAmerica = "North America",
+ Oceania = "Oceania"
}
export enum GameType {
- Singleplayer,
- Public,
- Private,
+ Singleplayer = "Singleplayer",
+ Public = "Public",
+ Private = "Private",
}
export interface UnitInfo {
diff --git a/src/server/Archive.ts b/src/server/Archive.ts
index e3e838568..c8cfe615b 100644
--- a/src/server/Archive.ts
+++ b/src/server/Archive.ts
@@ -14,6 +14,26 @@ export async function archive(gameRecord: GameRecord) {
await file.save(JSON.stringify(GameRecordSchema.parse(gameRecord)), {
contentType: 'application/json'
});
+ // Save metadata to BigQuery
+ const row = {
+ id: gameRecord.id,
+ start: new Date(gameRecord.startTimestampMS),
+ end: new Date(gameRecord.endTimestampMS),
+ duration_seconds: gameRecord.durationSeconds,
+ number_turns: gameRecord.num_turns,
+ usernames: gameRecord.usernames,
+ game_mode: gameRecord.gameConfig.gameType,
+ winner: null,
+ difficulty: gameRecord.gameConfig.difficulty,
+ map: gameRecord.gameConfig.gameMap,
+ };
+
+ await bigquery
+ .dataset('game_archive')
+ .table('game_results')
+ .insert([row]);
+
+ console.log(`wrote game metadata to BigQuery: ${gameRecord.id}`);
} catch (error) {
console.log(`error writing to gcs: ${error}`)
}