Home › Dev CE (experimental) › GameEras

Experimental: needs Dev CE (fork of the Community Extension, release zip and source). A GameCore that adds these Lua methods by calling engine functions directly. Not part of the upstream Community Extension, single-player testing only. Descriptions on these pages were written by an AI assistant from decompiled code and are marked inferred unless a test result confirms them.

GameEras

66 methods (Dev CE test build). this is found with the game's own IGameEras instance resolver (virtual).

Method Signature Purpose (AI-written, inferred) Tested Engine function Current
ChangeEraScore GameEras:ChangeEraScore(ePlayer: integer, iAmount: integer, eScoreType: integer) No decompilation available; from name and signature only: likely adds an amount of era score of a given score type to a player. plumbing ✓ — 0x1e1dd0
ChangeExtraScorePerPrideMoment GameEras:ChangeExtraScorePerPrideMoment(ePlayer: integer, iDelta: integer) Adds a delta to the extra era score a player gets for each pride (historic) moment. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangeExtraScorePerPrideMoment 0x1e2260
ChangePlayerAlwaysAllowedCommemorationQuestCount GameEras:ChangePlayerAlwaysAllowedCommemorationQuestCount(ePlayer: integer, iAmount: integer) Adds a delta to a player's counter of always-allowed commemoration quests. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerAlwaysAllowedCommemorationQuestCount 0x1e22b0
ChangePlayerEraScorePerAerodromeBuildingConstructed GameEras:ChangePlayerEraScorePerAerodromeBuildingConstructed(ePlayer: integer, iAmount: integer) Adds an amount to a player's era-score value for each Aerodrome building constructed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerAerodromeBuildingConstructed 0x1e2300
ChangePlayerEraScorePerArmyKilled GameEras:ChangePlayerEraScorePerArmyKilled(ePlayer: integer, iAmount: integer) Adds an amount to a player's era-score value for armies killed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerArmyKilled 0x1e2380
ChangePlayerEraScorePerArtifactExtracted GameEras:ChangePlayerEraScorePerArtifactExtracted(ePlayer: integer, iAmount: integer) Adds an amount to a player's era-score value for artifacts extracted. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerArtifactExtracted 0x1e2400
ChangePlayerEraScorePerCityReligionConversion GameEras:ChangePlayerEraScorePerCityReligionConversion(ePlayer: integer, iAmount: integer) Adds an amount to a player's era-score value for city religion conversions. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerCityReligionConversion 0x1e2480
ChangePlayerEraScorePerCivicBoost GameEras:ChangePlayerEraScorePerCivicBoost(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for civic boosts earned and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerCivicBoost 0x1e2500
ChangePlayerEraScorePerContinentDiscovered GameEras:ChangePlayerEraScorePerContinentDiscovered(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for continents discovered and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerContinentDiscovered 0x1e2580
ChangePlayerEraScorePerCorpsKilled GameEras:ChangePlayerEraScorePerCorpsKilled(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for corps units killed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerCorpsKilled 0x1e2600
ChangePlayerEraScorePerCultureBuildingConstructed GameEras:ChangePlayerEraScorePerCultureBuildingConstructed(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for culture buildings constructed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerCultureBuildingConstructed 0x1e2680
ChangePlayerEraScorePerCurrentCivic GameEras:ChangePlayerEraScorePerCurrentCivic(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for currently known civics and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerCurrentCivic 0x1e2700
ChangePlayerEraScorePerCurrentTech GameEras:ChangePlayerEraScorePerCurrentTech(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for currently known techs and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerCurrentTech 0x1e2780
ChangePlayerEraScorePerDistrictConstructed GameEras:ChangePlayerEraScorePerDistrictConstructed(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for districts constructed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerDistrictConstructed 0x1e2800
ChangePlayerEraScorePerGreatPersonEarned GameEras:ChangePlayerEraScorePerGreatPersonEarned(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for great people earned and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerGreatPersonEarned 0x1e2880
ChangePlayerEraScorePerIndustrialBuildingConstructed GameEras:ChangePlayerEraScorePerIndustrialBuildingConstructed(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for industrial buildings constructed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerIndustrialBuildingConstructed 0x1e2900
ChangePlayerEraScorePerNaturalWonderDiscovered GameEras:ChangePlayerEraScorePerNaturalWonderDiscovered(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for natural wonders discovered and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerNaturalWonderDiscovered 0x1e2980
ChangePlayerEraScorePerNonBarbarianUnitKilledByGDR GameEras:ChangePlayerEraScorePerNonBarbarianUnitKilledByGDR(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for non-barbarian units killed by GDR (exact meaning of GDR unclear) and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerNonBarbarianUnitKilledByGDR 0x1e2a00
ChangePlayerEraScorePerNonBarbarianUnitSeaKilled GameEras:ChangePlayerEraScorePerNonBarbarianUnitSeaKilled(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for non-barbarian sea units killed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerNonBarbarianUnitSeaKilled 0x1e2a80
ChangePlayerEraScorePerScienceBuildingConstructed GameEras:ChangePlayerEraScorePerScienceBuildingConstructed(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for science buildings constructed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerScienceBuildingConstructed 0x1e2b00
ChangePlayerEraScorePerSpySuccessfulMission GameEras:ChangePlayerEraScorePerSpySuccessfulMission(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for successful spy missions and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerSpySuccessfulMission 0x1e2b80
ChangePlayerEraScorePerTechBoost GameEras:ChangePlayerEraScorePerTechBoost(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for tech boosts earned and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerTechBoost 0x1e2c00
ChangePlayerEraScorePerTradeRouteCompleted GameEras:ChangePlayerEraScorePerTradeRouteCompleted(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for trade routes completed and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerTradeRouteCompleted 0x1e2c80
ChangePlayerEraScorePerUnitPromotionEarned GameEras:ChangePlayerEraScorePerUnitPromotionEarned(ePlayer: integer, iAmount: integer) Adds a signed amount to the per-player era-score counter for unit promotions earned and notifies listeners that era score changed. plumbing ✓
ran ±1, reversible ✓, no visible effect
Game::Eras::ChangePlayerEraScorePerUnitPromotionEarned 0x1e2d00
Commemorate GameEras:Commemorate(ePlayer: integer, eCommemoration: integer) No decompilation available; from name and signature only: likely records a commemoration (era dedication) choice for a player. plumbing ✓ — 0x1e2d80
ComplimentPrideMoment GameEras:ComplimentPrideMoment(ePlayer: integer, iMomentID: integer) No decompilation available; from name and signature only: likely complements or boosts a pride moment of a player by ID. plumbing ✓ — 0x1e2fd0
DoGoldenAgesAndDarkAges GameEras:DoGoldenAgesAndDarkAges(eOldEra: integer, eNewEra: integer) Private era-transition step: for each player copies golden/dark age flags, clears existing flags, compares total era score to golden and dark age thresholds, and calls SetGoldenAge or SetDarkAge accordingly. Decompilation is truncated. plumbing ✓ — 0x1e34d0
DoTurn GameEras:DoTurn() Per-turn era processing: only runs if a capability is present; initialises the current era to the start or first era if unset, recalculates threshold shifts, and checks whether an era transition is ready, sending events. Decompilation is truncated. plumbing ✓ — 0x1e4ca0
GetCurrentEraMaximumEndTurn GameEras:GetCurrentEraMaximumEndTurn() → number Returns max turn of the current era: game-speed-adjusted Era_XP1 maximum plus era start turn when enabled, else the game end turn, or INT_MAX if no game. plumbing ✓ — 0x1e54c0
GetCurrentEraMinimumEndTurn GameEras:GetCurrentEraMinimumEndTurn() → number Returns min turn of the current era: game-speed-adjusted Era_XP1 minimum plus era start turn when enabled, else 0. plumbing ✓ — 0x1e5570
GetCurrentEraNumPlayersAsOrLessAdvanced GameEras:GetCurrentEraNumPlayersAsOrLessAdvanced() → number Returns total player count minus number of players more advanced than the current era. plumbing ✓ — 0x1e5600
GetCurrentEraNumPlayersMoreAdvanced GameEras:GetCurrentEraNumPlayersMoreAdvanced() → number Counts players whose era is later than the current era (via GetMaxEra comparison). plumbing ✓ — 0x1e5640
GetExtraScorePerPrideMoment GameEras:GetExtraScorePerPrideMoment(ePlayer: integer) → number Returns the extra era score per pride moment stored for the player in an int array at +0x1f0. plumbing ✓ — 0x1e57d0
GetMinScoreForExtraEraScore GameEras:GetMinScoreForExtraEraScore(ePlayer: integer) → number Returns the minimum score for extra era score stored for the player in an int array at +0x220. plumbing ✓ — 0x1e59e0
GetPlayerCurrentScore GameEras:GetPlayerCurrentScore(ePlayer: integer) → number Returns the player total era score via PlayerScores::GetTotalScore. plumbing ✓ — 0x1e5a70
GetPlayerEraScorePerAerodromeBuildingConstructed GameEras:GetPlayerEraScorePerAerodromeBuildingConstructed(ePlayer: integer) → number Returns the per-player era score value for aerodrome building constructed from the player score record (offset 0x5c in a 0x78-byte entry). plumbing ✓ — 0x1e5ac0
GetPlayerEraScorePerArtifactExtracted GameEras:GetPlayerEraScorePerArtifactExtracted(ePlayer: integer) → number Returns the per-player era score value for artifact extracted from the player score record (offset 0x68 in a 0x78-byte entry). plumbing ✓ — 0x1e5b10
GetPlayerEraScorePerCityReligionConversion GameEras:GetPlayerEraScorePerCityReligionConversion(ePlayer: integer) → number Returns the per-player era score value for city religion conversion from the player score record (offset 0x30 in a 0x78-byte entry). plumbing ✓ — 0x1e5b60
GetPlayerEraScorePerCivicBoost GameEras:GetPlayerEraScorePerCivicBoost(ePlayer: integer) → number Returns the per-player era score value for civic boost from the player score record (offset 0x24 in a 0x78-byte entry). plumbing ✓ — 0x1e5bb0
GetPlayerEraScorePerContinentDiscovered GameEras:GetPlayerEraScorePerContinentDiscovered(ePlayer: integer) → number Returns the per-player era score value for continent discovered from the player score record (offset 0x48 in a 0x78-byte entry). plumbing ✓ — 0x1e5c00
GetPlayerEraScorePerCultureBuildingConstructed GameEras:GetPlayerEraScorePerCultureBuildingConstructed(ePlayer: integer) → number Returns the per-player era score value for culture building constructed from the player score record (offset 0x54 in a 0x78-byte entry). plumbing ✓ — 0x1e5c50
GetPlayerEraScorePerCurrentCivic GameEras:GetPlayerEraScorePerCurrentCivic(ePlayer: integer) → number Returns the per-player era score value for current civic from the player score record (offset 0x2c in a 0x78-byte entry). plumbing ✓ — 0x1e5ca0
GetPlayerEraScorePerCurrentTech GameEras:GetPlayerEraScorePerCurrentTech(ePlayer: integer) → number Returns the era score the player gets for each tech researched in the current era, read from the per-player era data (entry offset 0x28). plumbing ✓ — 0x1e5cf0
GetPlayerEraScorePerDistrictConstructed GameEras:GetPlayerEraScorePerDistrictConstructed(ePlayer: integer) → number Returns the era score the player gets for each district constructed, read from the per-player era data (entry offset 0x34). plumbing ✓ — 0x1e5d40
GetPlayerEraScorePerGreatPersonEarned GameEras:GetPlayerEraScorePerGreatPersonEarned(ePlayer: integer) → number Returns the era score the player gets for each great person earned, read from the per-player era data (entry offset 0x6c). plumbing ✓ — 0x1e5d90
GetPlayerEraScorePerIndustrialBuildingConstructed GameEras:GetPlayerEraScorePerIndustrialBuildingConstructed(ePlayer: integer) → number Returns the era score the player gets for each industrial-zone building constructed, read from the per-player era data (entry offset 0x60). plumbing ✓ — 0x1e5de0
GetPlayerEraScorePerNaturalWonderDiscovered GameEras:GetPlayerEraScorePerNaturalWonderDiscovered(ePlayer: integer) → number Returns the era score the player gets for each natural wonder discovered, read from the per-player era data (entry offset 0x4c). plumbing ✓ — 0x1e5e30
GetPlayerEraScorePerScienceBuildingConstructed GameEras:GetPlayerEraScorePerScienceBuildingConstructed(ePlayer: integer) → number Returns the era score the player gets for each science building constructed, read from the per-player era data (entry offset 0x58). plumbing ✓ — 0x1e5e80
GetPlayerEraScorePerSpySuccessfulMission GameEras:GetPlayerEraScorePerSpySuccessfulMission(ePlayer: integer) → number Returns the era score the player gets for each successful spy mission, read from the per-player era data (entry offset 0x64). plumbing ✓ — 0x1e5ed0
GetPlayerEraScorePerTechBoost GameEras:GetPlayerEraScorePerTechBoost(ePlayer: integer) → number Returns the era score the player gets for each tech boost (Eureka) triggered, read from the per-player era data (entry offset 0x20). plumbing ✓ — 0x1e5f20
GetPlayerEraScorePerTradeRouteCompleted GameEras:GetPlayerEraScorePerTradeRouteCompleted(ePlayer: integer) → number Returns the era score the player gets for each trade route completed, read from the per-player era data (entry offset 0x44). plumbing ✓ — 0x1e5f70
GetPlayerGoldenAgeThreshold GameEras:GetPlayerGoldenAgeThreshold(ePlayer: integer) → number Returns the player's golden age era score threshold from the per-player thresholds array, or the global default parameter when the player is out of range. plumbing ✓ — 0x1e5fc0
GetPlayerNumAllowedCommemorations GameEras:GetPlayerNumAllowedCommemorations(ePlayer: integer) → number Returns the number of commemorations the player is allowed, read from the per-player commemoration record (0x68-byte entries, offset 0x60). plumbing ✓ — 0x1e6020
HandleDarkAgeCityLoss GameEras:HandleDarkAgeCityLoss(ePlayer: integer) No decompilation available; from the name it handles city loss for a player in a Dark Age. Behaviour not verified. plumbing ✓ — 0x1e6120
HasActiveCommemoration GameEras:HasActiveCommemoration(ePlayer: integer, eCommemoration: integer) → boolean Checks whether the player has the given commemoration in their active commemoration list. plumbing ✓ — 0x1e63a0
HasDarkAge GameEras:HasDarkAge(ePlayer: integer) → boolean Returns whether the player is currently flagged as in a Dark Age (byte array lookup). plumbing ✓ — 0x1e6410
HasGoldenAge GameEras:HasGoldenAge(ePlayer: integer) → boolean Returns whether the player is currently flagged as in a Golden Age (byte array lookup). plumbing ✓ — 0x1e6440
HasHeroicGoldenAge GameEras:HasHeroicGoldenAge(ePlayer: integer) → boolean Returns true if the player has a golden age and their commemoration record shows more than one commemoration (active list length plus the counter at 0x60 exceeds 1). plumbing ✓ — 0x1e6470
IsPlayerAlwaysAllowedCommemorationQuest GameEras:IsPlayerAlwaysAllowedCommemorationQuest(ePlayer: integer) → boolean Returns true if the per-player int in the array at 0x1c0 is greater than 0. plumbing ✓ — 0x1e65b0
IsReadyForTransition GameEras:IsReadyForTransition() → boolean Decides whether the game should move to the next era: false before the era minimum end turn, true at or after the maximum end turn, otherwise true when enough players are more advanced than the current era. plumbing ✓ — 0x1e65f0
RecalculateThresholdShifts GameEras:RecalculateThresholdShifts(ePlayer: integer, eCurrentEra: integer) Recomputes, for one player, the era-score threshold shift values from amenity deficits, unresearched techs and civics of the current and later eras, and a government/era bonus, then fires the era-score changed event. plumbing ✓ Game::Eras::RecalculateThresholdShifts 0x1e6e00
SetCurrentEra GameEras:SetCurrentEra(eEra: integer) Private setter that changes the game's current era and records the turn the era began, then notifies listeners. plumbing ✓ Game::Eras::SetCurrentEra 0x1e7eb0
SetDarkAge GameEras:SetDarkAge(ePlayer: integer, bIsDarkAge: boolean) Sets whether a player is in a Dark Age and signals listeners when it changes. plumbing ✓ Game::Eras::SetDarkAge 0x1e7fa0
SetGoldenAge GameEras:SetGoldenAge(ePlayer: integer, bIsGoldenAge: boolean) Sets whether a player is in a Golden Age and signals listeners when it changes. plumbing ✓ Game::Eras::SetGoldenAge 0x1e8040
SetMinScoreForExtraEraScore GameEras:SetMinScoreForExtraEraScore(ePlayer: integer, iNewValue: integer) Sets, for one player, the minimum score threshold used for granting extra era score. plumbing ✓ Game::Eras::SetMinScoreForExtraEraScore 0x1e80e0
UncommemorateAll GameEras:UncommemorateAll(ePlayer: integer) No decompilation available; from the name it removes all commemorations of the player. Behaviour not verified. plumbing ✓ — 0x1e8c20

Details

ChangeEraScore

Arguments: ePlayer — player (inferred); iAmount — amount to add (inferred); eScoreType — era score category (inferred)

Observed in the game: Adds the amount to scores[player][scoreType] of the current era and sends a reporting event; an out-of-range player or score type is ignored. Confirmed in the game: +1 then -1 changed the era score exactly (score type 0).

Input checks: Unknown (no decompilation).

Multiplayer: unknown, no code available; likely changes game state. Risk: medium (body not analysed). Confidence of the reading: low.

ChangeExtraScorePerPrideMoment

Arguments: ePlayer — player index; iDelta — amount to add

Writes - per-player int array in auto variable at this+0x1e0

Input checks: Silent no-op if player is -1 or beyond the size of the per-player array.

Preconditions - game thread

Multiplayer: safe-deterministic. Risk: low (Bounds checked.). Confidence of the reading: high.

Verified from the code - Player range check against a vector size at this+0x1f0/0x1f8 - Adds iDelta to int[ePlayer] in the auto variable at this+0x1e0

Inferred - Value feeds into era score computed per moment

Open questions - Whether the extra score applies to all moment types

ChangePlayerAlwaysAllowedCommemorationQuestCount

Arguments: ePlayer — player index; iAmount — amount to add

Writes - per-player int array in auto variable at this+0x1b0

Input checks: Silent no-op if player is -1 or beyond array size.

Preconditions - game thread

Multiplayer: safe-deterministic. Risk: low (Bounds checked.). Confidence of the reading: high.

Verified from the code - Range checks player - Adds iAmount to the per-player int

Inferred - Counter is read when deciding which commemoration quests are available

ChangePlayerEraScorePerAerodromeBuildingConstructed

Arguments: ePlayer — player; iAmount — amount to add

Writes - field at offset 0x5c inside a 0x78-byte per-player record in the array at this+0x240

Side effects - sends Reporting::Event 0x788b7534 with player and amount

Input checks: Silent no-op if ePlayer is -1 or >= number of per-player records. No check on iAmount.

Preconditions - gameplay state

Multiplayer: safe-deterministic. Risk: low (Bounds-checked additive change). Confidence of the reading: high.

Verified from the code - bounds check against record count - adds to field +0x5c of the record - event 0x788b7534 shared with the sibling setters

Inferred - the field is a per-event era score value

Open questions - whether the value is a per-event score or an accumulated total

ChangePlayerEraScorePerArmyKilled

Arguments: ePlayer — player; iAmount — amount to add

Writes - field at offset 0x40 inside a 0x78-byte per-player record in the array at this+0x240

Side effects - sends Reporting::Event 0x788b7534 with player and amount

Input checks: Silent no-op if ePlayer is -1 or out of range.

Preconditions - gameplay state

Multiplayer: safe-deterministic. Risk: low (Bounds-checked additive change). Confidence of the reading: high.

Verified from the code - bounds check - field +0x40 of record - same event as siblings

Inferred - siblings differ only by field offset

Open questions - whether the value is accumulated or a per-event score

ChangePlayerEraScorePerArtifactExtracted

Arguments: ePlayer — player; iAmount — amount to add

Writes - field at offset 0x68 inside a 0x78-byte per-player record in the array at this+0x240

Side effects - sends Reporting::Event 0x788b7534 with player and amount

Input checks: Silent no-op if ePlayer is -1 or out of range.

Preconditions - gameplay state

Multiplayer: safe-deterministic. Risk: low (Bounds-checked additive change). Confidence of the reading: high.

Verified from the code - bounds check - field +0x68 of record - same event as siblings

Inferred - siblings differ only by field offset

Open questions - whether the value is accumulated or a per-event score

ChangePlayerEraScorePerCityReligionConversion

Arguments: ePlayer — player; iAmount — amount to add

Writes - field at offset 0x30 inside a 0x78-byte per-player record in the array at this+0x240

Side effects - sends Reporting::Event 0x788b7534 with player and amount

Input checks: Silent no-op if ePlayer is -1 or out of range.

Preconditions - gameplay state

Multiplayer: safe-deterministic. Risk: low (Bounds-checked additive change). Confidence of the reading: high.

Verified from the code - bounds check - field +0x30 of record - same event as siblings

Inferred - siblings differ only by field offset

Open questions - whether the value is accumulated or a per-event score

ChangePlayerEraScorePerCivicBoost

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x24 (counter for civic boosts earned)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x24 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerContinentDiscovered

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x48 (counter for continents discovered)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x48 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerCorpsKilled

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x3c (counter for corps units killed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x3c - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerCultureBuildingConstructed

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x58 (counter for culture buildings constructed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x58 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerCurrentCivic

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x2c (counter for currently known civics)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x2c - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerCurrentTech

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x28 (counter for currently known techs)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x28 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerDistrictConstructed

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x34 (counter for districts constructed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x34 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerGreatPersonEarned

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x6c (counter for great people earned)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x6c - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerIndustrialBuildingConstructed

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x60 (counter for industrial buildings constructed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x60 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerNaturalWonderDiscovered

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x4c (counter for natural wonders discovered)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x4c - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerNonBarbarianUnitKilledByGDR

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x70 (counter for non-barbarian units killed by GDR (exact meaning of GDR unclear))

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x70 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerNonBarbarianUnitSeaKilled

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x50 (counter for non-barbarian sea units killed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x50 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerScienceBuildingConstructed

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x54 (counter for science buildings constructed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x54 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerSpySuccessfulMission

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x64 (counter for successful spy missions)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x64 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerTechBoost

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x20 (counter for tech boosts earned)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x20 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerTradeRouteCompleted

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x44 (counter for trade routes completed)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x44 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

ChangePlayerEraScorePerUnitPromotionEarned

Arguments: ePlayer — player id; iAmount — signed amount added to the counter (negative allowed)

Writes - per-player era-score record (stride 0x78, VariantMap at this+0x240), int at record offset 0x74 (counter for unit promotions earned)

Side effects - sends reporting event 0x788b7534 with player and amount - calls FAutoVariable::edit on this+0x240 (marks game variable dirty)

Input checks: Silently does nothing if ePlayer is -1 or >= number of per-player records; amount is not range-checked and there is no overflow check.

Preconditions - gameplay Lua state only - game thread - era tracking initialised for all players

Multiplayer: may-desync: mutates synchronised game state; safe only if executed identically on all clients. Risk: medium (Direct counter write bypassing the normal gameplay trigger; player is bounds-checked but value is not.). Confidence of the reading: high.

Verified from the code - Early-out when ePlayer == -1 or index >= element count (element size 0x78) - Adds iAmount at record offset 0x74 - Always sends event 0x788b7534 after adding when player is valid

Inferred - Counter meaning taken from the function name; it is one of the per-player era-score tallies - Same shape as sibling ChangePlayerEraScorePer* functions, differing only by offset

Open questions - What the event listeners do with the amount (UI refresh vs score recalculation) was not examined

Commemorate

Arguments: ePlayer — player (inferred); eCommemoration — commemoration type (inferred)

Observed in the game (inferred): Needs a valid player, a valid commemoration type and at least one pick still allowed; then decrements the allowed picks, appends the type to the player's active commemorations (dedications), dispatches the "commemoration added" signal and logs it. It does NOT check that the type is among the choices offered this era. The effects come from subscribers of that signal and from modifiers that test for an active commemoration.

Input checks: Unknown (no decompilation).

Multiplayer: unknown, no code available; likely changes game state. Risk: medium (body not analysed). Confidence of the reading: low.

ComplimentPrideMoment

Arguments: ePlayer — player (inferred); iMomentID — pride moment id (inferred)

Observed in the game (inferred): If the moment id is in the player's pending pride-moment list, clears the whole list and dispatches the "moment complimented" signal. Otherwise nothing happens.

Input checks: Unknown (no decompilation).

Multiplayer: unknown, no code available; likely changes game state. Risk: medium (body not analysed). Confidence of the reading: low.

DoGoldenAgesAndDarkAges

Arguments: eOldEra — era being left; eNewEra — era being entered

Observed in the game (inferred): For each player, compares the finished era's score with the player's thresholds: at or above the golden threshold sets a golden age (a heroic golden age, with more commemoration picks, if the previous age was a dark age); below the dark threshold sets a dark age and runs HandleDarkAgeCityLoss; otherwise a normal age. Thresholds are then re-based and shifted for past golden/dark ages.

Writes - per-player golden age and dark age flag vectors - era score related VariantMaps

Side effects - age change signal (PlayerTypes,bool) - Reporting event sent

Input checks: Requires both era definitions to exist; otherwise does nothing.

Multiplayer: may-desync, changes player ages at era change. Risk: high (drives age assignment for all players). Confidence of the reading: medium.

DoTurn

Observed in the game (inferred): Once per turn: starts the era-end countdown (NEXT_ERA_TURN_COUNTDOWN) when IsReadyForTransition is true; when the countdown runs out, finishes the era: copies the era scores, clears every player's commemorations, computes the new era's commemoration choices and picks allowed, runs DoGoldenAgesAndDarkAges and sets the new current era. Does nothing in the last era.

Writes - current era (via SetCurrentEra) - era transition fields at 0xd8/0xe8 - initialised flag at 0x108

Side effects - Reporting event per player when transition is ready - notifications (seen in callees)

Input checks: Returns early when capability missing or already at last era.

Multiplayer: may-desync, advances era state each turn. Risk: high (drives era transitions). Confidence of the reading: low.

GetCurrentEraMaximumEndTurn

Input checks: Checks game pointer and enable flags.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: medium.

GetCurrentEraMinimumEndTurn

Input checks: Checks index and definition null.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: medium.

GetCurrentEraNumPlayersAsOrLessAdvanced

Input checks: None.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: medium.

GetCurrentEraNumPlayersMoreAdvanced

Input checks: Returns 0 if current era is -1; skips null players.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: medium.

GetExtraScorePerPrideMoment

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetMinScoreForExtraEraScore

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerCurrentScore

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerAerodromeBuildingConstructed

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerArtifactExtracted

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerCityReligionConversion

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerCivicBoost

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerContinentDiscovered

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerCultureBuildingConstructed

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerCurrentCivic

Arguments: ePlayer — player index

Input checks: Returns 0 for -1 or out-of-range player.

Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerCurrentTech

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerDistrictConstructed

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerGreatPersonEarned

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerIndustrialBuildingConstructed

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerNaturalWonderDiscovered

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerScienceBuildingConstructed

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerSpySuccessfulMission

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerTechBoost

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerEraScorePerTradeRouteCompleted

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or >= per-player entry count (0x78-byte entries); no other checks.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerGoldenAgeThreshold

Arguments: ePlayer — player index used to index the per-player array

Input checks: Falls back to global parameter (offset 0x3a0) if ePlayer is -1 or out of range.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

GetPlayerNumAllowedCommemorations

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns 0 if ePlayer is -1 or out of range.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

HandleDarkAgeCityLoss

Arguments: ePlayer — player affected, inferred from name (inferred)

Observed in the game (inferred): For a living major player: a difficulty-dependent percentage of its cities (at least one) is transferred to the first player of the player manager list (probably the free cities player) by cultural identity.

Writes - unknown (presumably city ownership)

Side effects - unknown

Input checks: unknown

Multiplayer: may-desync, name suggests changing cities. Risk: medium (cannot be verified without decompilation). Confidence of the reading: low.

HasActiveCommemoration

Arguments: ePlayer — player index used to index the per-player array; eCommemoration — commemoration type searched in the player's active list

Input checks: Returns false if either argument is -1 or player is out of range; no check that the type is valid.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

HasDarkAge

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns false if ePlayer is -1 or beyond array size.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

HasGoldenAge

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns false if ePlayer is -1 or beyond array size.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: high.

HasHeroicGoldenAge

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns false if ePlayer is -1 or out of range of either array.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: medium.

IsPlayerAlwaysAllowedCommemorationQuest

Arguments: ePlayer — player index used to index the per-player array

Input checks: Returns false if ePlayer is -1 or out of range.

Multiplayer: read-only, pure getter. Risk: low (pure getter). Confidence of the reading: medium.

IsReadyForTransition

Observed in the game (inferred): False before the era's minimum end turn minus the countdown length; true at or after the maximum end turn minus the countdown length; in between true when enough players are more advanced than the rest.

Input checks: Returns false if the game pointer at offset 0x8 is null; no other checks.

Multiplayer: read-only, reads turn and player manager only. Risk: low (pure getter). Confidence of the reading: medium.

RecalculateThresholdShifts

Arguments: ePlayer — player to recalculate; eCurrentEra — era the shifts are computed relative to

Writes - per-player threshold record (stride 0x30, VariantMap at this+0x300): int slots +0x00 (game parameter * (num-1 items)), +0x04 (amenity penalty), +0x08, +0x0c, +0x10, +0x14, +0x18 (tech/civic shifts), +0x28 (era-specific bonus)

Side effects - sends reporting event 0x788b7534 with player - many VariantMap edit calls on this+0x300 - calls Context::Globals::EditPlayer

Input checks: Checks player index in range and that the per-player record has exactly 11 int slots; otherwise does nothing silently. Null definition pointers skipped. EditPlayer is called before the range check, so an invalid player id is not guarded there.

Preconditions - gameplay Lua state only - game thread - valid player id

Multiplayer: may-desync: rewrites synchronised state; deterministic only if run identically everywhere. Risk: medium (Large recomputation touching many fields; private method normally called by the era system.). Confidence of the reading: medium.

Verified from the code - Calls EditPlayer(ePlayer) first, then range check and slot-count==11 check - Iterates player cities calling GetAmenitiesNeeded and GetAmenities and adds a penalty on deficit - Loops tech and civic definition lists using HasTech/HasCivic and GetMaxEra - Sends event 0x788b7534 at the end

Inferred - Slots +0x0c/+0x14 are tech shifts and +0x10/+0x18 civic shifts (guess from the loops) - The shifts relate to golden/dark age thresholds

Open questions - Exact semantics of each slot unknown - Era pointers in definitions interpreted only as era links - Ghidra labels the era-definition lookups with a Government type, probably mislabelled

SetCurrentEra

Arguments: eEra — new current era

Writes - current era at this+0xb8 (auto-variable at this+0xa8) - era-start turn at this+0xc0 (start turn if era equals the configured start era, else current game turn)

Side effects - dispatches a game signal (+0x6c0) with old and new era - sends Reporting::Event 0xf50673b7 with old and new era

Input checks: No-op if the era is unchanged or if the current game or configuration pointer is null. No range check on the era id.

Preconditions - game and configuration must exist - gameplay state

Multiplayer: may-desync: global game state. Risk: medium (Global era change drives many systems; no era range check). Confidence of the reading: medium.

Verified from the code - early-out on same era - signal and event fire only if game and configuration are non-null - the stored era-start value depends on whether the era equals the start era

Inferred - offset +0xc0 is the era start turn - the signal parameter types in the symbol (PlayerTypes, BeliefTypes) look mis-resolved; actually old and new era

Open questions - whether the signal is dispatched on the same call path as other era-change handlers

SetDarkAge

Arguments: ePlayer — player id; bIsDarkAge — new state

Writes - dark age byte array at this+0x150

Side effects - signal (PlayerTypes,bool) at game signal table +0xa08

Input checks: Silent return if id out of range or value unchanged.

Preconditions - game thread

Multiplayer: may-desync: synced era state. Risk: low (bounds-checked flag). Confidence of the reading: high.

Verified from the code - range check against array size - only acts on change - dispatches signal with id and value

Inferred - private method, normally reached via era score evaluation

SetGoldenAge

Arguments: ePlayer — player id; bIsGoldenAge — new state

Writes - golden age byte array at this+0x120

Side effects - signal (PlayerTypes,bool) at game signal table +0xa20

Input checks: Silent return if id out of range or value unchanged.

Preconditions - game thread

Multiplayer: may-desync: synced era state. Risk: low (bounds-checked flag). Confidence of the reading: high.

Verified from the code - range check against array size - only acts on change - dispatches signal with id and value

Inferred - private method

SetMinScoreForExtraEraScore

Arguments: ePlayer — player index; iNewValue — new threshold

Writes - per-player int in auto variable at this+0x210

Input checks: Silent no-op if player is -1 or beyond array size.

Preconditions - game thread

Multiplayer: safe-deterministic. Risk: low (Bounds checked overwrite.). Confidence of the reading: high.

Verified from the code - Range check then direct assignment (not add) of iNewValue

Inferred - Value is a threshold compared against the player's era score

Open questions - Exact comparison used

UncommemorateAll

Arguments: ePlayer — player whose commemorations are cleared, inferred from name (inferred)

Writes - unknown (presumably player commemoration list)

Side effects - unknown

Input checks: unknown

Multiplayer: may-desync, name suggests changing player state. Risk: medium (cannot be verified without decompilation). Confidence of the reading: low.