Home › Dev CE (experimental) › PlayerInfluence
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.
PlayerInfluence
52 methods (Dev CE test build). this is found with the game's own IPlayerInfluence instance resolver (plain).
| Method |
Signature |
Purpose (AI-written, inferred) |
Tested |
Engine function |
Current |
| AddLevyDiscountPercent |
PlayerInfluence:AddLevyDiscountPercent(iNewValue: integer) |
Appends a discount value to the levy discount vector at offset 0x2b8. |
plumbing ✓ |
— |
0x2e8e70 |
| CanGiveTokensToAnyPlayer |
PlayerInfluence:CanGiveTokensToAnyPlayer() → boolean |
Returns true if the player's government allows giving tokens and any player in the manager list passes CanGiveTokensToPlayer. |
plumbing ✓ |
— |
0x2e8f70 |
| CanReceiveInfluenceFrom |
PlayerInfluence:CanReceiveInfluenceFrom(fromPlayer: integer) → boolean |
Returns true if government permits receiving influence and the per-player byte flag at 0x358 for that player is zero. |
plumbing ✓ |
— |
0x2e9260 |
| ChangeBasePointsPerTurn |
PlayerInfluence:ChangeBasePointsPerTurn(change: number (fixed point, 1/256 steps)) |
Adds a delta to the base influence points per turn, clamping at zero, and sends an event. |
plumbing ✓ |
Player::Influence::ChangeBasePointsPerTurn |
0x2e92e0 |
| ChangePointsThreshold |
PlayerInfluence:ChangePointsThreshold(change: integer) |
Adds a delta to the player influence points threshold (floored at zero) and fires an update event. |
plumbing ✓ |
Player::Influence::ChangePointsThreshold |
0x2e9350 |
| ChangeSuzerainUniqueBonusDisabledCount |
PlayerInfluence:ChangeSuzerainUniqueBonusDisabledCount(iChange: integer) |
Changes the counter that disables the city-state's unique suzerain bonus and signals whether it is now disabled. |
plumbing ✓ ran ±1, reversible ✓, no visible effect |
Player::Influence::ChangeSuzerainUniqueBonusDisabledCount |
0x2e93c0 |
| ChangeTokensPerThreshold |
PlayerInfluence:ChangeTokensPerThreshold(change: integer) |
Adds a signed delta to a player's influence tokens-per-threshold value, clamping at 0, then fires a reporting event for the owning player. |
plumbing ✓ |
Player::Influence::ChangeTokensPerThreshold |
0x2e9430 |
| ChangeTokensReceived |
PlayerInfluence:ChangeTokensReceived(fromPlayer: integer, iDelta: integer) |
Adds iDelta to the tokens received from a player by calling SetTokensReceived. |
plumbing ✓ |
— |
0x2e94a0 |
| ChangeTokensReceivedModifier |
PlayerInfluence:ChangeTokensReceivedModifier(fromPlayer: integer, iDelta: integer) |
Changes the token-received modifier from one player toward this (city-state) player, updates the suzerain, and notifies listeners of the effective token change. |
plumbing ✓ ran ±1, reversible ✓, no visible effect |
Player::Influence::ChangeTokensReceivedModifier |
0x2e94c0 |
| ChangeVirtualTokensReceived |
PlayerInfluence:ChangeVirtualTokensReceived(fromPlayer: integer, iDelta: integer) |
Adds iDelta to the virtual tokens received from a player by calling SetVirtualTokensReceived. |
plumbing ✓ |
— |
0x2e9610 |
| CheckForTokensEarned |
PlayerInfluence:CheckForTokensEarned() |
If government permits, converts accumulated points into tokens at a threshold and keeps the remainder. |
plumbing ✓ |
— |
0x2e9630 |
| CheckSendTokenNotification |
PlayerInfluence:CheckSendTokenNotification() |
Sends a fixed-type notification to the owning player. |
plumbing ✓ |
— |
0x2e9700 |
| ClearAllTokensReceived |
PlayerInfluence:ClearAllTokensReceived() |
Removes all tokens received from every other player (private cleanup), adjusting suzerain, religious pressure, diplomatic favor and firing signals per player. |
plumbing ✓ |
Player::Influence::ClearAllTokensReceived |
0x2e9730 |
| CountTokensGivenToAnyPlayer |
PlayerInfluence:CountTokensGivenToAnyPlayer() → number |
Sums across all players the tokens this player has given them, including bonus percent. |
plumbing ✓ |
— |
0x2e9a30 |
| CountTributaries |
PlayerInfluence:CountTributaries() → number |
Counts players whose influence field at 0x418 equals this player. |
plumbing ✓ |
— |
0x2e9b30 |
| DecrementCopyLuxuriesCount |
PlayerInfluence:DecrementCopyLuxuriesCount(toPlayer: integer) |
Decrements the luxury-copy count given to a player; when it drops to zero ends imports of all luxury resources for that player. |
plumbing ✓ |
— |
0x2e9bc0 |
| DecrementCopyStrategicsCount |
PlayerInfluence:DecrementCopyStrategicsCount(toPlayer: integer) |
Decrements the strategic-copy count for a player in the array at 0x318. |
plumbing ✓ |
— |
0x2e9ce0 |
| DecrementOpenBordersCount |
PlayerInfluence:DecrementOpenBordersCount(toPlayer: integer) |
Decrements the count of open-borders sources toward a given player; when that drops to zero it revokes the open-borders-from flag in the other player's diplomacy. |
plumbing ✓ |
Player::Influence::DecrementOpenBordersCount |
0x2e9d20 |
| DoTurn |
PlayerInfluence:DoTurn() |
Per-turn influence processing: restores visibility on the old capital plot, adds points per turn, converts tokens, sends a notification, manages levies and advances the levy counter. |
plumbing ✓ |
— |
0x2e9f90 |
| GetEnemyNonVirtualTokensReceived |
PlayerInfluence:GetEnemyNonVirtualTokensReceived(ePlayer: integer) → number |
Sums, over all other players in the manager list, the net non-virtual tokens received including bonus percent. |
plumbing ✓ |
— |
0x2ea1d0 |
| GetLevyTurnLimit |
PlayerInfluence:GetLevyTurnLimit() → number |
Returns the global levy turn limit parameter (offset 0x450 of the global parameters) scaled by game speed. |
plumbing ✓ |
— |
0x2ea4a0 |
| GetMaxTokensReceived |
PlayerInfluence:GetMaxTokensReceived(fromPlayer: integer) → number |
Returns the base token count stored for the given player, increased by a percentage bonus if that player has a positive bonus value. |
plumbing ✓ |
— |
0x2ea4d0 |
| GetTotalTokensReceived |
PlayerInfluence:GetTotalTokensReceived() → number |
Sums, over all players in the player manager list, the real plus virtual tokens received with the percent bonus applied. |
plumbing ✓ |
— |
0x2ea760 |
| GetVirtualTokensReceived |
PlayerInfluence:GetVirtualTokensReceived(fromPlayer: integer) → number |
Computes tokens for a player: array 0x208 value plus a percent bonus applied to the (0x1d8 + 0x208) sum when bonus at 0x238 is positive. |
plumbing ✓ |
— |
0x2ea830 |
| GetYieldFromGivenTokens |
PlayerInfluence:GetYieldFromGivenTokens(yield: integer) → number |
Returns a FixedPoint: the per-unit value from the vector at 0x388 (per-given-token yield) for the yield, multiplied by CountTokensGivenToAnyPlayer, or 0 if not positive/out of range. |
plumbing ✓ |
— |
0x2ea890 |
| GetYieldFromTributaries |
PlayerInfluence:GetYieldFromTributaries(yield: integer) → number |
Returns a FixedPoint: the per-unit value from the vector at 0x3b8 (per-tributary yield) for the yield, multiplied by CountTributaries, or 0 if not positive/out of range. |
plumbing ✓ |
— |
0x2ea900 |
| GetYieldModifierFromTributaries |
PlayerInfluence:GetYieldModifierFromTributaries(yield: integer) → number |
Returns a FixedPoint: the per-unit value from the vector at 0x3e8 (per-tributary modifier) for the yield, multiplied by CountTributaries, or 0 if not positive/out of range. |
plumbing ✓ |
— |
0x2ea970 |
| GetYieldModifierPerTributary |
PlayerInfluence:GetYieldModifierPerTributary(yield: integer) → number |
Returns the stored FixedPoint value at the yield index of the vector at offset 0x3e8, or 0 if the index is out of range. |
plumbing ✓ |
— |
0x2ea9e0 |
| GetYieldPerGivenToken |
PlayerInfluence:GetYieldPerGivenToken(yield: integer) → number |
Returns the stored FixedPoint value at the yield index of the vector at offset 0x388, or 0 if the index is out of range. |
plumbing ✓ |
— |
0x2eaa20 |
| GetYieldPerTributary |
PlayerInfluence:GetYieldPerTributary(yield: integer) → number |
Returns the stored FixedPoint value at the yield index of the vector at offset 0x3b8, or 0 if the index is out of range. |
plumbing ✓ |
— |
0x2eaa60 |
| GiveTokenToPlayer |
PlayerInfluence:GiveTokenToPlayer(toPlayer: integer) → boolean |
Gives one of the player's stored influence tokens to another player and decreases the number of tokens left to give. |
plumbing ✓ |
Player::Influence::GiveTokenToPlayer |
0x2ead90 |
| GrantPlayerSuzerainship |
PlayerInfluence:GrantPlayerSuzerainship(fromPlayer: integer) |
Makes peace between the owner and the given player, then (for a qualifying government/level) sets the player's token count to at least the current maximum plus one so they become suzerain. |
plumbing ✓ |
— |
0x2eade0 |
| IncrementCopyLuxuriesCount |
PlayerInfluence:IncrementCopyLuxuriesCount(toPlayer: integer) |
Increments the per-player copy-luxuries counter; when it goes from 0 to positive, imports all luxury resources the owner has into the target player. |
plumbing ✓ |
— |
0x2eaee0 |
| IncrementCopyStrategicsCount |
PlayerInfluence:IncrementCopyStrategicsCount(toPlayer: integer) |
Increments the per-player copy-strategic-resources counter (offset 0x318) for the given player. |
plumbing ✓ |
— |
0x2eb000 |
| IncrementLevyTurnCounter |
PlayerInfluence:IncrementLevyTurnCounter() |
Advances the levy turn counter for a player's suzerain levy relationship and, once it reaches the game-speed-adjusted limit, returns the levied military to its owner. Fires a reporting event afterwards. |
plumbing ✓ |
Player::Influence::IncrementLevyTurnCounter |
0x2eb040 |
| IncrementOpenBordersCount |
PlayerInfluence:IncrementOpenBordersCount(toPlayer: integer) |
Increments the open-borders counter for the given player and, if influence can be received and the counter is positive, grants that player open borders from the owner. |
plumbing ✓ |
— |
0x2eb220 |
| RemoveLevyDiscountPercent |
PlayerInfluence:RemoveLevyDiscountPercent(iRemoveValue: integer) |
Removes the first occurrence of the given value from the levy discount percent list (offset 0x2b8). |
plumbing ✓ |
— |
0x2ec640 |
| RemoveNonSuzerainTokens |
PlayerInfluence:RemoveNonSuzerainTokens() |
For every other player (not owner or current suzerain) zeroes their tokens, updates suzerain, adds religious pressure, adjusts diplomatic favor, and dispatches signals. Decompilation is truncated near the end. |
plumbing ✓ |
— |
0x2ec6b0 |
| ResetLevyTurnCounter |
PlayerInfluence:ResetLevyTurnCounter() |
Resets the levy turn counter field (offset 0x450) to -1 if the owner meets a government/level condition, and sends a reporting event. |
plumbing ✓ |
— |
0x2ed110 |
| SetBasePointsPerTurn |
PlayerInfluence:SetBasePointsPerTurn(value: number (fixed point, 1/256 steps)) |
Sets the base influence points per turn (negatives clamped to zero) and sends an event. |
plumbing ✓ |
Player::Influence::SetBasePointsPerTurn |
0x2ed390 |
| SetDuplicateFirstTokens |
PlayerInfluence:SetDuplicateFirstTokens(value: integer) |
Sets how many extra tokens are given on the first token placement, only when the owner's government meets a required flag. |
plumbing ✓ |
Player::Influence::SetDuplicateFirstTokens |
0x2ed3f0 |
| SetDuplicateTokensWhenRivalGovernment |
PlayerInfluence:SetDuplicateTokensWhenRivalGovernment(value: integer) |
Sets the number of duplicate tokens granted when the other party has a rival government, only if the owner's government meets a required flag. |
plumbing ✓ |
Player::Influence::SetDuplicateTokensWhenRivalGovernment |
0x2ed480 |
| SetDuplicateTokensWhenSameReligion |
PlayerInfluence:SetDuplicateTokensWhenSameReligion(value: integer) |
Sets the number of duplicate tokens granted when the other party shares the owner's religion, only if the owner's government meets a required flag. |
plumbing ✓ |
Player::Influence::SetDuplicateTokensWhenSameReligion |
0x2ed510 |
| SetDuplicateTokensWhenTradeRouteTo |
PlayerInfluence:SetDuplicateTokensWhenTradeRouteTo(value: integer) |
Sets the number of duplicate tokens granted when the owner has a trade route to the other party, only if the owner's government meets a required flag. |
plumbing ✓ |
Player::Influence::SetDuplicateTokensWhenTradeRouteTo |
0x2ed5a0 |
| SetPointsEarned |
PlayerInfluence:SetPointsEarned(value: number (fixed point, 1/256 steps)) |
Sets influence points earned (clamped at zero) if the owning player is alive and its civilization level allows it, then sends an event. |
plumbing ✓ |
Player::Influence::SetPointsEarned |
0x2ed690 |
| SetTokensOnFirstToMeet |
PlayerInfluence:SetTokensOnFirstToMeet(value: integer) |
Sets how many tokens the owner receives for being the first to meet a player, only if the owner's government meets a required flag. |
plumbing ✓ |
Player::Influence::SetTokensOnFirstToMeet |
0x2ed730 |
| SetTokensOnTradeRouteStarted |
PlayerInfluence:SetTokensOnTradeRouteStarted(value: integer) |
Sets how many tokens the owner receives when a trade route is started, only if the owner's government meets a required flag. |
plumbing ✓ |
Player::Influence::SetTokensOnTradeRouteStarted |
0x2ed7c0 |
| SetVirtualTokensReceived |
PlayerInfluence:SetVirtualTokensReceived(fromPlayer: integer, value: integer) |
Sets the virtual token count for a player; if the effective change is nonzero updates suzerain and dispatches signals and a reporting event. |
plumbing ✓ |
— |
0x2edbd0 |
| SetYieldModifierPerTributary |
PlayerInfluence:SetYieldModifierPerTributary(yield: integer, value: number (fixed point, 1/256 steps)) |
Sets the yield modifier per tributary city state for a yield type. |
plumbing ✓ |
Player::Influence::SetYieldModifierPerTributary |
0x2edd40 |
| SetYieldPerGivenToken |
PlayerInfluence:SetYieldPerGivenToken(yield: integer, value: number (fixed point, 1/256 steps)) |
Sets the yield granted per envoy token given, for a yield type. |
plumbing ✓ |
Player::Influence::SetYieldPerGivenToken |
0x2edd90 |
| SetYieldPerTributary |
PlayerInfluence:SetYieldPerTributary(yield: integer, value: number (fixed point, 1/256 steps)) |
Sets the flat yield gained per tributary for a yield type. |
plumbing ✓ |
Player::Influence::SetYieldPerTributary |
0x2edde0 |
| UpdateSuzerain |
PlayerInfluence:UpdateSuzerain() |
Recomputes which major player is the suzerain of a city-state from per-player influence values and, on change, makes peace with the old suzerain's enemies, removes visibility/open borders, returns levied military and notifies. |
plumbing ✓ |
Player::Influence::UpdateSuzerain |
0x2edf10 |
Details
AddLevyDiscountPercent
Arguments: iNewValue — discount percent to add
Writes
- levy discount vector at this+0x2b8 grows
Input checks: None.
Multiplayer: may-desync, writes synced vector. Risk: medium (unchecked). Confidence of the reading: medium.
CanGiveTokensToAnyPlayer
Input checks: Checks owner alive and government flag.
Multiplayer: read-only, getter. Risk: low (getter). Confidence of the reading: high.
CanReceiveInfluenceFrom
Arguments: fromPlayer — player sending influence
Input checks: Requires fromPlayer < 0x40 and owner alive.
Multiplayer: read-only, getter. Risk: low (getter). Confidence of the reading: medium.
ChangeBasePointsPerTurn
Arguments: change — delta (raw/256)
Writes
- base points per turn at this+0xc0
Side effects
- Reporting::Event 0xd35e571d with player id
Input checks: Clamps negative total to 0.
Preconditions
- gameplay state
Multiplayer: may-desync: must be applied everywhere. Risk: low (clamped). Confidence of the reading: high.
Verified from the code
- clamp at zero
- sends event
Inferred
- 0xd0 read vs 0xc0 write may be same value tracked
Open questions
- reads at +0xd0 but writes at +0xc0
ChangePointsThreshold
Arguments: change — signed delta
Writes
- tracked int at this+0xf0 (influence points threshold)
Side effects
- sends event 0xd35e571d with owner id
Input checks: Clamps result to 0 minimum; no other validation.
Preconditions
- gameplay Lua state
- private method normally called internally
Multiplayer: may-desync: mutates synchronised state. Risk: medium (Private method; clamped but a direct write.). Confidence of the reading: medium.
Verified from the code
- Result clamped to >= 0
- Event 0xd35e571d sent after assignment
Inferred
- Threshold is points needed for the next envoy
Open questions
- The DistrictTypes template name is likely identical-code-folding noise
ChangeSuzerainUniqueBonusDisabledCount
Arguments: iChange — delta to counter
Writes
- disabled count auto-variable at this+0x438 (value read at +0x448)
Side effects
- signal (City const*, bool) at game signal +0xca8 with owner pointer and (count>0)
Input checks: Zero change is a no-op; no lower bound clamp on the count.
Preconditions
- game thread
Multiplayer: may-desync: synced counter. Risk: low (counter plus signal). Confidence of the reading: medium.
Verified from the code
- no-op when change is 0
- signal arg is whether count > 0
- no clamp on count
Inferred
- signal arg type is mislabeled (owner is a Player, not City)
ChangeTokensPerThreshold
Arguments: change — signed amount added to the current value
Writes
- tokens-per-threshold auto-variable at this+0x108 (new value = old at this+0x118 + change, min 0)
Side effects
- Reporting::Event::Send with hash 0xd35e571d and owner player id
Input checks: No input checks; negative result is clamped to 0.
Preconditions
- owner player pointer at this+0x498 must be valid (dereferenced unchecked)
- game thread
Multiplayer: may-desync: writes synced auto-variable; safe only if called identically on all clients. Risk: low (simple counter with clamp). Confidence of the reading: medium.
Verified from the code
- clamps result at 0
- assigns via CopyAssignmentDo to this+0x108
- sends event 0xd35e571d with owner id
- owner pointer dereferenced without null check
Inferred
- field is the tokens-per-threshold counter, name taken from function name
- the auto-variable type shown in the template (DistrictTypes) is a Ghidra mislabel
Open questions
- exact meaning of event hash 0xd35e571d
ChangeTokensReceived
Arguments: fromPlayer — source player; iDelta — amount to add
Writes
- tokens received via SetTokensReceived
Input checks: Skips -1; no upper bound check here.
Multiplayer: may-desync, changes influence tokens. Risk: medium (synced state). Confidence of the reading: high.
ChangeTokensReceivedModifier
Arguments: fromPlayer — player sending tokens; iDelta — amount to add to the modifier
Writes
- per-player modifier array at this+0x228 (element += iDelta)
- suzerain via UpdateSuzerain
Side effects
- dispatches game signal (+0xc90) with players, effective delta and a flag derived from bit 31 of this+0x460
- dispatches two per-player signals on the player's object at +0x798 (+0x120 and +0x138)
- sends Reporting::Event 0x65c1d0a2 with owner id
Input checks: Silent no-op if fromPlayer >= 64 or iDelta is 0. Negative fromPlayer is not explicitly checked in signature terms (unsigned compare in code).
Preconditions
- gameplay state
Multiplayer: may-desync: changes influence/suzerain. Risk: medium (Can flip suzerain and fire several signals). Confidence of the reading: medium.
Verified from the code
- bounds check < 0x40 and delta != 0
- UpdateSuzerain called after write
- events and signals fire only if effective token count changed
Inferred
- the modifier acts like bonus envoys
- signal types shown are mis-resolved
Open questions
- meaning of bit 31 of this+0x460
ChangeVirtualTokensReceived
Arguments: fromPlayer — source player; iDelta — amount to add
Writes
- virtual tokens via SetVirtualTokensReceived
Input checks: Skips -1; no upper bound check here.
Multiplayer: may-desync, changes influence tokens. Risk: medium (synced state). Confidence of the reading: high.
CheckForTokensEarned
Writes
- tokens to give
- points earned remainder
Input checks: Requires owner alive, government flag and positive threshold.
Multiplayer: may-desync, changes tokens and points. Risk: medium (synced state). Confidence of the reading: high.
CheckSendTokenNotification
Side effects
- Reporting notification sent to owner
Input checks: None.
Multiplayer: may-desync, sends a notification. Risk: low (only a notification). Confidence of the reading: medium.
ClearAllTokensReceived
Writes
- tokens-received array at this+0x1c8 zeroed per player
- array at this+0x258 zeroed where negative
- suzerain via UpdateSuzerain
- capital city religion pressure
- diplomatic favor of the other player
Side effects
- adds religious pressure to the owner's capital for players that founded a religion
- changes diplomatic favor via Congress for a minor civ bonus
- dispatches the same signals as ChangeTokensReceivedModifier per player
- sends Reporting::Event 0x65c1d0a2 per cleared player
Input checks: Skips the owner itself and ids >= 0x40. Per-player handling only if the computed delta is nonzero.
Preconditions
- gameplay state
- valid owner
Multiplayer: may-desync: mutates many replicated values. Risk: high (Wide mutation of influence, religion and favor). Confidence of the reading: low.
Verified from the code
- iterates the player manager's list
- skips self
- computes a negative delta from arrays
- calls UpdateSuzerain, Congress favor and religion pressure
Inferred
- delta formula looks like (x/100+1)*count; meaning unclear
- applies only to minor civs for the favor part
Open questions
- meaning of arrays at +0x1d8, +0x238, +0x268
- exact semantic of the religion pressure amount
CountTokensGivenToAnyPlayer
Input checks: Skips null players.
Multiplayer: read-only, getter. Risk: low (getter). Confidence of the reading: medium.
CountTributaries
Input checks: Skips null players.
Multiplayer: read-only, getter. Risk: low (getter). Confidence of the reading: medium.
DecrementCopyLuxuriesCount
Arguments: toPlayer — recipient player
Writes
- luxury copy count at this+0x2e8
- recipient resource imports ended
Side effects
- Resources::EndImportResource called
Input checks: Requires owner, toPlayer < 0x40 and not self.
Multiplayer: may-desync, changes resources. Risk: medium (ends imports). Confidence of the reading: medium.
DecrementCopyStrategicsCount
Arguments: toPlayer — recipient player
Writes
- strategic copy count at this+0x318
Input checks: Requires owner, toPlayer < 0x40, not self.
Multiplayer: may-desync, writes synced array. Risk: medium (synced write). Confidence of the reading: high.
DecrementOpenBordersCount
Arguments: toPlayer — player id whose open-borders count is lowered
Writes
- per-player int array in the variant map at this+0x288 (open borders count, entry decremented)
- other player's Diplomacy open-borders-from flag toward the owner (cleared)
Side effects
- calls Diplomacy::SetHasOpenBordersFrom(false) on the target player's diplomacy (owner id read at owner+0xd8)
- fetches an editable target player via Context::Globals::EditPlayer
Input checks: Silently returns if the owner pointer is null or the player id is >= 0x40. The count can go negative: no lower-bound check on the decrement. Diplomacy side only runs if CanReceiveInfluence is true and the count is below 1.
Preconditions
- gameplay Lua state only
- owner player must be set
- player id < 64
Multiplayer: may-desync: mutates replicated state and another player's diplomacy; must be called identically everywhere. Risk: medium (unchecked negative count and cross-player diplomacy mutation). Confidence of the reading: medium.
Verified from the code
- bails if this+0x498 is null or id >= 0x40
- decrements an int in the map at this+0x288 indexed by player
- clears HasOpenBordersFrom on target diplomacy only when count (this+0x298 array) < 1 and flag set and CanReceiveInfluence
Inferred
- this+0x288 and this+0x298 are the editable and read views of the same counts array
- semantics are open-borders reference counting
Open questions
- whether the two offsets are really the same array
- why the counter can be driven negative
DoTurn
Writes
- points earned
- visibility counts
- levy turn counter
Side effects
- visibility changes
- notification sent
Input checks: Checks owner alive and government flag.
Multiplayer: may-desync, changes state. Risk: high (many state writes). Confidence of the reading: medium.
GetEnemyNonVirtualTokensReceived
Arguments: ePlayer — player excluded from the sum
Input checks: Skips ePlayer and bounds each player below 0x40.
Multiplayer: read-only, getter. Risk: low (getter). Confidence of the reading: low.
GetLevyTurnLimit
Input checks: No inputs to validate.
Multiplayer: read-only: pure getter of rules data. Risk: low (pure getter). Confidence of the reading: high.
GetMaxTokensReceived
Arguments: fromPlayer — Player whose tokens are queried (index into per-player arrays)
Input checks: Checks fromPlayer < 64 (returns 0 otherwise); no check for null arrays.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetTotalTokensReceived
Input checks: Skips player ids >= 64; no null checks.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetVirtualTokensReceived
Arguments: fromPlayer — Player whose tokens are queried
Input checks: Checks fromPlayer < 64; array bounds not checked.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetYieldFromGivenTokens
Arguments: yield — Yield type index into the per-yield vector
Input checks: Bounds-checks yield against vector size; no null check on this.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetYieldFromTributaries
Arguments: yield — Yield type index into the per-yield vector
Input checks: Bounds-checks yield against vector size; no null check on this.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetYieldModifierFromTributaries
Arguments: yield — Yield type index into the per-yield vector
Input checks: Bounds-checks yield against vector size; no null check on this.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetYieldModifierPerTributary
Arguments: yield — Yield type index into the vector
Input checks: Bounds-checks yield against vector size.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetYieldPerGivenToken
Arguments: yield — Yield type index into the vector
Input checks: Bounds-checks yield against vector size.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GetYieldPerTributary
Arguments: yield — Yield type index into the vector
Input checks: Bounds-checks yield against vector size.
Multiplayer: read-only: pure getter. Risk: low (pure getter). Confidence of the reading: medium.
GiveTokenToPlayer
Arguments: toPlayer — recipient player id
Writes
- tokens-to-give counter at this+0x130 (decremented by 1 via SetTokensToGive on success)
Side effects
- calls GiveFreeTokenToPlayer, which grants the token to the recipient (effects not visible here)
Input checks: Returns false when tokens-to-give is below 1. Validation of the player id is delegated to GiveFreeTokenToPlayer.
Preconditions
- gameplay Lua state only
- must run on the game thread
Multiplayer: may-desync: state change must be applied identically on all clients. Risk: medium (grants influence to another player; recipient id validation not visible). Confidence of the reading: high.
Verified from the code
- returns false if this+0x130 < 1
- calls GiveFreeTokenToPlayer then SetTokensToGive(count-1) only if that returned true
- returns the result of GiveFreeTokenToPlayer
Inferred
- tokens are envoys given to city-states
Open questions
- what GiveFreeTokenToPlayer validates
GrantPlayerSuzerainship
Arguments: fromPlayer — Player to be granted suzerainship
Writes
- Player diplomacy state (peace)
- Tokens received for fromPlayer (via SetTokensReceived)
Side effects
- MakePeaceWith call; SetTokensReceived fires its own signals
Input checks: Checks player index <= 0x40, lookup entry not -1 and player object non-null; silently returns otherwise.
Multiplayer: may-desync. Risk: high (changes diplomacy and token ownership of synced game state). Confidence of the reading: medium.
IncrementCopyLuxuriesCount
Arguments: toPlayer — Player receiving copies of luxuries
Writes
- Copy-luxuries count array (offset 0x2e8) for toPlayer
- Target player's imported resources
Side effects
- Calls BeginImportResource on target player for each owned luxury
Input checks: Checks owner non-null, toPlayer < 64 and not the owner itself.
Multiplayer: may-desync. Risk: high (modifies resource imports of another player). Confidence of the reading: medium.
IncrementCopyStrategicsCount
Arguments: toPlayer — Player to receive strategic copies
Writes
- Copy-strategics count array (offset 0x318)
Input checks: Checks owner non-null, toPlayer < 64 and toPlayer != owner.
Multiplayer: may-desync. Risk: medium (writes synced per-player counter). Confidence of the reading: medium.
IncrementLevyTurnCounter
Writes
- levy turn counter at this+0x460 (incremented by 1)
- registers the variable at this+0x450 in a std::set held at this+0x458 (change-tracking set, if not already present)
Side effects
- calls ReturnLeviedMilitary on the suzerain's influence object when counter >= limit
- Reporting::Event::Send hash 0xf2f69b23 with owner id (skipped if suzerain id is -1 at the return branch)
Input checks: Silent return if owner null, owner flag at +600 is 0, level definition missing, or definition flag (bit 7 at +0x28) not set. If counter reaches limit and suzerain is -1 it returns silently without event.
Preconditions
- game thread
- owner player valid
Multiplayer: may-desync: mutates synced counter; must run identically on all clients. Risk: medium (returning levied units has wide effects). Confidence of the reading: medium.
Verified from the code
- increments this+0x460 by one
- compares against AdjustForGameSpeed of a global parameter
- calls ReturnLeviedMilitary with suzerain's influence object
- sends event 0xf2f69b23
Inferred
- the +0x450 tree insert is the usual auto-variable dirty-set registration
- definition flag likely means 'is city-state' type level
Open questions
- exact meaning of the level/definition flag at +0x28 bit 7
- which game parameter is at ms_pkParameters+0x450
IncrementOpenBordersCount
Arguments: toPlayer — Player gaining open borders
Writes
- Open-borders count array (offset 0x288)
- Target player's diplomacy open-borders flag
Side effects
- Calls SetHasOpenBordersFrom on target player diplomacy
Input checks: Checks owner non-null and toPlayer < 64.
Multiplayer: may-desync. Risk: medium (changes diplomacy state). Confidence of the reading: medium.
RemoveLevyDiscountPercent
Arguments: iRemoveValue — Discount percent value to remove from the list
Writes
- Levy discount percent vector (offset 0x2b8)
Input checks: No check; if value is not found nothing happens.
Multiplayer: may-desync. Risk: medium (edits synced game variable list). Confidence of the reading: medium.
RemoveNonSuzerainTokens
Writes
- Tokens received array (offset 0x1c8)
- Suzerain state
- Capital city religious pressure
- Congress diplomatic favor
Side effects
- Dispatches token-change signals and likely a reporting event
Input checks: Skips players >= 64 and the owner/suzerain; no null checks on pointers.
Multiplayer: may-desync. Risk: high (bulk change to influence, religion and favor state). Confidence of the reading: low.
ResetLevyTurnCounter
Writes
- Levy turn counter (offset 0x450)
Side effects
- Reporting::Event::Send
Input checks: Checks owner flag at 600 and government definition lookup for null.
Multiplayer: may-desync. Risk: medium (writes synced AI control variable). Confidence of the reading: low.
SetBasePointsPerTurn
Arguments: value — new value (raw/256)
Writes
- base points per turn at this+0xc0
Side effects
- Reporting::Event 0xd35e571d
Input checks: Negative input clamped to zero (input itself is modified).
Preconditions
- gameplay state
Multiplayer: may-desync: must be applied everywhere. Risk: low (clamped). Confidence of the reading: high.
Verified from the code
- clamp and write
- event
SetDuplicateFirstTokens
Arguments: value — number of duplicate first tokens; negatives are clamped to 0
Writes
- int auto-variable at this+0x138
Side effects
- auto-variable assign likely marks state dirty
Input checks: Silently does nothing if the owner is null, the owner flag at +0x258 is zero, the definition lookup fails, or definition flag bit 6 is clear. Negative values are clamped to 0.
Preconditions
- gameplay Lua state only
- owner player must be set and active
Multiplayer: may-desync: direct state write. Risk: low (clamped value with silent gating). Confidence of the reading: medium.
Verified from the code
- gated by owner non null and owner+0x258 nonzero
- looks up a definition via GetLevel and the civilization level definitions, and requires bit 6 of byte +0x28
- clamps negative to 0 and stores at this+0x138
Inferred
- gating flag is a government property enabling token bonuses; exact meaning unknown
- the semantic name comes from the function name
Open questions
- what definition flag bit 6 means
- whether the Find call really targets the Government collection (symbol is confusing)
SetDuplicateTokensWhenRivalGovernment
Arguments: value — duplicate token count; negatives clamped to 0
Writes
- int auto-variable at this+0x180
Side effects
- auto-variable assign likely marks state dirty
Input checks: Silently does nothing if owner null, owner flag at +0x258 zero, definition not found, or flag bit 6 clear. Negatives clamped to 0.
Preconditions
- gameplay Lua state only
- owner player must be set and active
Multiplayer: may-desync: direct state write. Risk: low (clamped value with silent gating). Confidence of the reading: medium.
Verified from the code
- same gating and clamp as the other Influence token setters
- stores at this+0x180
Inferred
- meaning of the field follows the function name
Open questions
- meaning of definition flag bit 6
- where the field is consumed
SetDuplicateTokensWhenSameReligion
Arguments: value — duplicate token count; negatives clamped to 0
Writes
- int auto-variable at this+0x1b0
Side effects
- auto-variable assign likely marks state dirty
Input checks: Silently does nothing if owner null, owner flag at +0x258 zero, definition not found, or flag bit 6 clear. Negatives clamped to 0.
Preconditions
- gameplay Lua state only
- owner player must be set and active
Multiplayer: may-desync: direct state write. Risk: low (clamped value with silent gating). Confidence of the reading: medium.
Verified from the code
- same gating and clamp as the other Influence token setters
- stores at this+0x1b0
Inferred
- meaning follows the function name
Open questions
- meaning of definition flag bit 6
- where the field is consumed
SetDuplicateTokensWhenTradeRouteTo
Arguments: value — duplicate token count; negatives clamped to 0
Writes
- int auto-variable at this+0x198
Side effects
- auto-variable assign likely marks state dirty
Input checks: Silently does nothing if owner null, owner flag at +0x258 zero, definition not found, or flag bit 6 clear. Negatives clamped to 0.
Preconditions
- gameplay Lua state only
- owner player must be set and active
Multiplayer: may-desync: direct state write. Risk: low (clamped value with silent gating). Confidence of the reading: medium.
Verified from the code
- same gating and clamp as the other Influence token setters
- stores at this+0x198
Inferred
- meaning follows the function name
Open questions
- meaning of definition flag bit 6
- where the field is consumed
SetPointsEarned
Arguments: value — new value (raw/256)
Writes
- points earned at this+0xa8
Side effects
- Reporting::Event 0xd35e571d
Input checks: Silently does nothing if no owner, owner not alive, or level lacks the flag.
Preconditions
- gameplay state
Multiplayer: may-desync: must be applied everywhere. Risk: low (guarded). Confidence of the reading: high.
Verified from the code
- guard on alive and level flag
- clamp
Inferred
- flag likely means level has influence
SetTokensOnFirstToMeet
Arguments: value — token count; negatives clamped to 0
Writes
- int auto-variable at this+0x150
Side effects
- auto-variable assign likely marks state dirty
Input checks: Silently does nothing if owner null, owner flag at +0x258 zero, definition not found, or flag bit 6 clear. Negatives clamped to 0.
Preconditions
- gameplay Lua state only
- owner player must be set and active
Multiplayer: may-desync: direct state write. Risk: low (clamped value with silent gating). Confidence of the reading: medium.
Verified from the code
- same gating and clamp as the other Influence token setters
- stores at this+0x150
Inferred
- meaning follows the function name
Open questions
- meaning of definition flag bit 6
- where the field is consumed
SetTokensOnTradeRouteStarted
Arguments: value — token count; negatives clamped to 0
Writes
- int auto-variable at this+0x168
Side effects
- auto-variable assign likely marks state dirty
Input checks: Silently does nothing if owner null, owner flag at +0x258 zero, definition not found, or flag bit 6 clear. Negatives clamped to 0.
Preconditions
- gameplay Lua state only
- owner player must be set and active
Multiplayer: may-desync: direct state write. Risk: low (clamped value with silent gating). Confidence of the reading: medium.
Verified from the code
- same gating and clamp as the other Influence token setters
- stores at this+0x168
Inferred
- meaning follows the function name
Open questions
- meaning of definition flag bit 6
- where the field is consumed
SetVirtualTokensReceived
Arguments: fromPlayer — Player whose virtual tokens are set; value — New virtual token count
Writes
- Virtual tokens array (offset 0x1f8) for fromPlayer
- Suzerain state
Side effects
- Dispatches influence-change and belief-type signals; Reporting::Event::Send
Input checks: Checks fromPlayer < 64; value not range-checked.
Multiplayer: may-desync. Risk: high (changes synced token and suzerain state). Confidence of the reading: medium.
SetYieldModifierPerTributary
Arguments: yield — yield type index; value — new value raw/256
Writes
- array element in VariantMap at this+0x3d8
Input checks: Unsigned bound check; invalid silently ignored.
Preconditions
- gameplay state only
Multiplayer: may-desync: direct state write. Risk: low (bounds checked). Confidence of the reading: high.
Verified from the code
- bounds check
- stores *param in element
SetYieldPerGivenToken
Arguments: yield — yield type index; value — new value raw/256
Writes
- array element in VariantMap at this+0x378
Input checks: Unsigned bound check; invalid silently ignored.
Preconditions
- gameplay state only
Multiplayer: may-desync: direct state write. Risk: low (bounds checked). Confidence of the reading: high.
Verified from the code
- bounds check
- stores *param in element
Inferred
- token means envoy/influence token from name
SetYieldPerTributary
Arguments: yield — yield type index; value — new value raw/256
Writes
- array element in VariantMap at this+0x3a8
Input checks: Unsigned bound check; invalid silently ignored.
Preconditions
- gameplay state only
Multiplayer: may-desync: direct state write. Risk: low (bounds checked). Confidence of the reading: high.
Verified from the code
- bounds check
- stores *param in element
UpdateSuzerain
Writes
- suzerain player id at this+0x408 (assigned from result)
- registers change in set at this+0x420/0x428
- war-changed turn for pairs set to -1 via DiplomaticRelations
- peace made on owner's Diplomacy
Side effects
- Diplomacy::MakePeaceWith for players at war with owner
- removes outgoing visibility for old suzerain
- DecrementOpenBordersCount
- ReturnLeviedMilitary if levy counter >= 0
- Reporting::Notification::Send with localized text and capital location
Input checks: Returns silently when owner is invalid/not a city-state level, or old/new suzerain id is out of range (>0x40) or not an active player.
Preconditions
- game thread
- owner must be a city-state-like player
Multiplayer: may-desync: large diplomatic state mutation; must be deterministic across clients. Risk: high (changes diplomacy, visibility, units and sends notifications). Confidence of the reading: low.
Verified from the code
- suzerain is the player with the highest influence value that is at least a global threshold; a tie yields -1
- early returns when old equals new suzerain
- calls MakePeaceWith and sets war-changed turn to -1
- sends a notification via Reporting::Notification::Send
Inferred
- influence = (base + bonus) scaled by percent at +0x238
- the pieces after the truncation presumably assign the new suzerain and run new-suzerain effects
Open questions
- decompiled C is truncated, so the new-suzerain assignment/notification half is not seen
- exact roles of arrays at +0x1d8/+0x208/+0x238