Home › Dev CE (experimental) › GameDiplomacy
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.
GameDiplomacy
16 methods (Dev CE test build). this is found with the game's own IGameDiplomacy instance resolver (virtual).
| Method |
Signature |
Purpose (AI-written, inferred) |
Tested |
Engine function |
Current |
| ChangeGrievanceAndTension |
GameDiplomacy:ChangeGrievanceAndTension(a: integer, b: integer, iNumGrievances: integer) |
Changes the grievance score between two players by the amount and the tension score by its absolute value. |
plumbing ✓ |
— |
0x1ce9f0 |
| ChangeTensionScore |
GameDiplomacy:ChangeTensionScore(a: integer, b: integer, iChangeinTension: integer) |
Adds a delta to the tension score of an unordered player pair (stored in a triangular array), clamped at 0, and stamps the current game turn when the delta is positive. |
plumbing ✓ |
— |
0x1ceb50 |
| DoTurn |
GameDiplomacy:DoTurn() |
Per-turn processing: for each pair of players with an alliance it adds alliance points per turn to both and, if the alliance level changed, dispatches a signal and sends notifications to both players. Decompilation is truncated, so later behaviour is unseen. |
plumbing ✓ |
— |
0x1cf680 |
| GetAllianceType |
GameDiplomacy:GetAllianceType(a: integer, b: integer) → number |
Returns the alliance type stored for the unordered player pair, or -1 if both players are the same. |
plumbing ✓ |
— |
0x1d0900 |
| GetGrievanceScore |
GameDiplomacy:GetGrievanceScore(a: integer, b: integer) → number |
Returns the grievance score for the pair, signed by who holds the grievance: positive if the stored owner equals a, negative otherwise, 0 if a==b or no owner. |
plumbing ✓ |
— |
0x1d0cc0 |
| GetJointWarTarget |
GameDiplomacy:GetJointWarTarget(initiator: integer, partner: integer) → number |
Returns the joint war target stored for the unordered pair of players. |
plumbing ✓ |
— |
0x1d0d60 |
| GetLastTurnPlayerWasOfferedDeal |
GameDiplomacy:GetLastTurnPlayerWasOfferedDeal(ePlayer: integer) → number |
Loops over all players other than ePlayer calling Diplomacy::GetLastTurnOfferedDeal but discards the results and always returns 0 as decompiled. |
plumbing ✓ |
— |
0x1d0dc0 |
| GetResearchAgreementTech |
GameDiplomacy:GetResearchAgreementTech(a: integer, b: integer) → number |
Returns the tech of the research agreement between the pair, or -1 if same player. |
plumbing ✓ |
— |
0x1d0e80 |
| GetTensionScore |
GameDiplomacy:GetTensionScore(a: integer, b: integer) → number |
Returns the tension score of the unordered pair, 0 if same player. |
plumbing ✓ |
— |
0x1d0ee0 |
| ResetAllianceDuration |
GameDiplomacy:ResetAllianceDuration(a: integer, b: integer) |
If the pair has an alliance, sets its last-change turn field to the current game turn. |
plumbing ✓ |
— |
0x1d3120 |
| SetAtWar |
GameDiplomacy:SetAtWar(a: integer, b: integer, war: integer) |
Sets or clears the war state between two players with a given war type (war type -1 means peace). Logs the event, resets denouncements, expels units from territory, and updates visibility blockers. |
plumbing ✓ |
Game::DiplomaticRelations::SetAtWar |
0x1d31b0 |
| SetIsAllied |
GameDiplomacy:SetIsAllied(a: integer, b: integer, allied: integer) |
Sets or clears the alliance type between two players, stamps the turn, dispatches alliance start or end signals, sets the defensive pact flag, logs a diplomatic event and sends reporting events. Decompilation is truncated after visibility handling. |
plumbing ✓ |
— |
0x1d3920 |
| SetIsInDefensivePact |
GameDiplomacy:SetIsInDefensivePact(a: integer, b: integer, pact: boolean) |
Sets or clears a defensive pact between two players, stamps the current turn, dispatches a pact started/ended signal and logs a diplomatic event. |
plumbing ✓ |
Game::DiplomaticRelations::SetIsInDefensivePact |
0x1d3c30 |
| SetJointWarTarget |
GameDiplomacy:SetJointWarTarget(initiator: integer, partner: integer, target: integer) |
Records a joint war target between two players (initiator and partner) along with the current turn. |
plumbing ✓ |
Game::DiplomaticRelations::SetJointWarTarget |
0x1d3db0 |
| SetResearchAgreementTech |
GameDiplomacy:SetResearchAgreementTech(a: integer, b: integer, eTech: integer) |
Stores the research agreement tech and current turn for the pair, dispatches a start or end signal (end when tech is -1) and logs a diplomatic event. |
plumbing ✓ |
— |
0x1d4050 |
| SetSharesSuzerain |
GameDiplomacy:SetSharesSuzerain(a: integer, b: integer, c: boolean) |
Sets whether two players share the same suzerain (city-state overlord) and logs a diplomatic event for it. |
plumbing ✓ |
Game::DiplomaticRelations::SetSharesSuzerain |
0x1d41d0 |
Details
ChangeGrievanceAndTension
Arguments: a — first player; b — second player; iNumGrievances — signed grievance delta; absolute value added to tension
Writes
- grievance score for the pair (via ChangeGrievanceScore)
- tension score for the pair (via ChangeTensionScore)
Side effects
- last-change turn recorded for tension when delta positive
Input checks: No checks itself; delegates.
Multiplayer: may-desync, writes synchronised diplomacy state. Risk: medium (edits diplomacy state without validation). Confidence of the reading: high.
ChangeTensionScore
Arguments: a — first player; b — second player; iChangeinTension — tension delta
Writes
- tension VariantMap entry at +0x2c8 (value and last-change turn)
Input checks: Clamps result to >= 0; no check for a==b or invalid players.
Multiplayer: may-desync, writes game diplomacy VariantMap. Risk: medium (unchecked indexing; a==b or invalid player index would hit a wrong slot). Confidence of the reading: high.
DoTurn
Writes
- player Diplomacy alliance points (both players)
Side effects
- alliance level change signal
- localized notifications to both players
- callees show game speed adjustment and symmetric deal turn lookup
Input checks: Skips pairs with no alliance (-1); no other checks visible.
Multiplayer: may-desync, advances alliance state each turn. Risk: high (turn processing; calling it again double-counts alliance points). Confidence of the reading: low.
GetAllianceType
Arguments: a — first player; b — second player
Input checks: Only a==b checked; no range check.
Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.
GetGrievanceScore
Arguments: a — player whose perspective is used; b — other player
Input checks: a==b and owner -1 give 0; no range check.
Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.
GetJointWarTarget
Arguments: initiator — first player (inferred); partner — second player (inferred)
Input checks: No checks, even for equal players.
Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: medium.
GetLastTurnPlayerWasOfferedDeal
Arguments: ePlayer — player being queried
Input checks: None.
Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: medium.
GetResearchAgreementTech
Arguments: a — first player; b — second player
Input checks: Only a==b checked.
Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.
GetTensionScore
Arguments: a — first player; b — second player
Input checks: Only a==b checked.
Multiplayer: read-only, reads stored state only. Risk: low (pure getter). Confidence of the reading: high.
ResetAllianceDuration
Arguments: a — first player; b — second player
Writes
- alliance VariantMap entry turn stamp at +0x200
Input checks: Skips if alliance type is -1; no player range check.
Multiplayer: may-desync, writes alliance state. Risk: medium (synchronised alliance state). Confidence of the reading: high.
SetAtWar
Arguments: a — first player id; b — second player id; war — war type; -1 = peace
Writes
- war-state/turn pair for the player pair in a triangular matrix at this+0x188
- aggressor and turn pair for the player pair in matrix at this+0x1b0 (aggressor = a, or -1 on peace)
- current game turn stamp copied from game object +0xc0
Side effects
- if players differ, pair not yet met and war type != -1: Player::Manager::Meet is called (first meeting)
- LogDiplomaticEvent with At War (war type string) or Peace
- on war: ResetDenouncement on both players, ExpelFromTerritory(reason 3) both ways, AddOutgoingVisibilityBlocker three times
- on peace: ExpelFromTerritory(reason 4) both ways and RemoveOutgoingVisibilityBlocker three times
Input checks: no bounds check on player ids (unchecked triangular index); when a==b the first meet branch is skipped but state write still happens at a degenerate index; war-type not validated
Preconditions
- both ids valid active players
- gameplay Lua state, game thread
Multiplayer: may-desync: mutates global diplomatic state; must be executed identically on all clients. Risk: high (unchecked player index, changes global diplomacy, visibility and unit placement). Confidence of the reading: medium.
Verified from the code
- war type 0xffffffff selects the Peace branch
- tri-matrix index uses player count at +0xb8
- edit() called on two FAutoVariable maps
- Meet called only when pair not already met and war type != -1
- expel and visibility-blocker calls happen only if both players' flag at +600 is non-zero
Inferred
- flag at +600 likely means player is alive/major
- maps at +0x188 and +0x1b0 hold war state and aggressor
- the +0xd0 per-pair byte is a has-met flag
- war-type string is used purely for logging
Open questions
- exact meaning of ExpelFromTerritory reason codes 3 and 4
- why visibility blocker is added twice for the same ordered pair
SetIsAllied
Arguments: a — first player; b — second player; allied — alliance type to set, -1 ends the alliance
Writes
- alliance VariantMap entry (type and turn)
- defensive pact flag via SetIsInDefensivePact
- diplomatic event log
Side effects
- Alliance start/end message signals
- Reporting events sent
- visibility updates (seen in truncated tail)
Input checks: No-op if type and turn unchanged; no range check on players.
Multiplayer: may-desync, changes alliances and visibility. Risk: high (alliance change cascades to pacts and visibility). Confidence of the reading: medium.
SetIsInDefensivePact
Arguments: a — first player; b — second player; pact — true to create, false to end
Writes
- pair entry in triangular-indexed array at this+0x138: flag byte and turn (from game +0xc0)
Side effects
- signal dispatch (Unit, Plot) pact-start (+0xd98) or pact-end (+0xdb0) with the two players' player objects as args
- LogDiplomaticEvent 'Defensive Pact' or 'Defensive Pact Ends'
Input checks: No range or equality checks on ids; unchecked pair index and player-array lookups (crash risk).
Preconditions
- game thread
- two valid distinct player ids
Multiplayer: may-desync: diplomatic state. Risk: medium (unvalidated indices). Confidence of the reading: medium.
Verified from the code
- symmetric pair index computed from min/max of ids
- logs strings Defensive Pact / Defensive Pact Ends
- different signals for set vs clear
Inferred
- signal arg types shown in template (Unit, Plot) are probably Ghidra mislabels of player objects
Open questions
- real signal parameter types
SetJointWarTarget
Arguments: initiator — player starting the joint war; partner — allied partner; target — player the war is declared on
Writes
- pair table entry at this+0x1d8: target player and current turn
Input checks: No bounds check on ids; triangular pair index is unchecked (out-of-bounds risk).
Preconditions
- valid player ids
- game thread
Multiplayer: safe-deterministic. Risk: medium (Unchecked pair index.). Confidence of the reading: high.
Verified from the code
- Pair index is symmetric so initiator/partner order does not matter for storage
- Stores target in the first field and the current turn in the second
- Does not declare war itself
Inferred
- Passing -1 as target probably clears it
Open questions
- Whether callers use the stored turn for expiry
SetResearchAgreementTech
Arguments: a — first player; b — second player; eTech — tech under agreement, -1 ends it
Writes
- research agreement VariantMap entry (tech, turn) at +0x160
Side effects
- Research agreement start/end signal
- diplomatic event log entry
Input checks: No range or validity checks.
Multiplayer: may-desync, writes synchronised diplomacy state. Risk: medium (unvalidated indexes). Confidence of the reading: high.
SetSharesSuzerain
Arguments: a — first player; b — second player; c — true if they now share a suzerain
Writes
- pair table entry at this+0x228: bool flag and current turn
Side effects
- calls LogDiplomaticEvent with text 'Shares Suzerain' or 'No longer shares Suzerain' and an empty second string
Input checks: No bounds checks on player ids (unchecked triangular index). The log is written even if the value did not change.
Preconditions
- valid player ids
- game thread
Multiplayer: safe-deterministic. Risk: medium (Unchecked pair index.). Confidence of the reading: high.
Verified from the code
- Writes bool and turn into pair record
- Builds strings and calls LogDiplomaticEvent(this, a, b, text, empty)
- Text depends on the bool
Inferred
- Used by relationship (diplomatic visibility/modifier) scoring
Open questions
- Whether the log appears in UI or only the diplomatic log