Add timing logs to gameController to diagnose remaining load time (#6022)

Breaking down the ~280ms gap between PersistedHistory and "Finished loading":
- loadTextStore: Loading ClientTextStore from disk (5MB+ completeText.txt)
- pregenAndRecovery: Populating pregenerated texts and recovering missing names
- buildController: Creating HeroGenerator, EngineImpl, and GameController

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 15:15:10 -08:00
committed by GitHub
co-authored by Claude Opus 4.5
parent 7ee5b35696
commit 90ebd1a5be
@@ -208,18 +208,21 @@ object GamesManager {
userToFid: Map[UserId, FactionId],
pregeneratedHeroes: Vector[HeroWithName]
): GameController = {
val loadedTextStore = ClientTextStoreImpl
val textStoreStart = System.currentTimeMillis()
val loadedTextStore = ClientTextStoreImpl
.loaded(
pregenerated = pregeneratedTexts,
persister = gamePersister
)
.get
val textStoreDuration = System.currentTimeMillis() - textStoreStart
// Check all heroes' nameTextIds and recover any missing name requests
val allHeroes = (history.last.resultingState.killedHeroes ++
history.last.resultingState.heroes).values
val factionIds = history.last.resultingState.factions.keys.toVector
val pregeneratedStart = System.currentTimeMillis()
// Populate pregenerated texts for all heroes in this game.
// This ensures games are self-contained and old games get the texts they need.
val withPregeneratedTexts = withPopulatedPregeneratedTexts(
@@ -228,12 +231,13 @@ object GamesManager {
factionIds = factionIds
)
val recoveryResult = MissingHeroNameRecovery.recoverMissingHeroNames(
val recoveryResult = MissingHeroNameRecovery.recoverMissingHeroNames(
clientTextStore = withPregeneratedTexts,
heroes = allHeroes,
gameId = gameId,
factionIds = factionIds
)
val pregeneratedDuration = System.currentTimeMillis() - pregeneratedStart
val clientTextStore = recoveryResult.clientTextStore
val existingNames = recoveryResult.resolvedNames
@@ -241,7 +245,8 @@ object GamesManager {
val pregenHeroes =
pregeneratedHeroes.filterNot(heroWithName => existingNames.contains(heroWithName.name))
HeroGenerator(
val controllerStart = System.currentTimeMillis()
val controller = HeroGenerator(
pregeneratedHeroes = pregenHeroes,
excludingNames = existingNames,
// FIXME: use a seed saved for this purpose
@@ -268,8 +273,18 @@ object GamesManager {
.performAiCommands(gcwpr)
.gameController
}
}
}.newValue
}.newValue
val controllerDuration = System.currentTimeMillis() - controllerStart
println(
s"[GameLoad] gameId=0x${gameId.toHexString}: " +
s"loadTextStore=${textStoreDuration}ms, " +
s"pregenAndRecovery=${pregeneratedDuration}ms, " +
s"buildController=${controllerDuration}ms"
)
controller
}
}
class GamesManager(