Home › Dev CE (experimental) › Unit

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.

Unit

46 methods (Dev CE test build). this is found with the game's own IUnit instance resolver (plain).

Method Signature Purpose (AI-written, inferred) Tested Engine function Current
AddBypassWallsPromotionClass Unit:AddBypassWallsPromotionClass(ePromotionClass: integer) Adds a promotion class to a counted set of classes that let the unit bypass walls. plumbing ✓
this ✓ (oracle)
Unit::Instance::AddBypassWallsPromotionClass 0x3a1f30
AddEnableWallAttackPromotionClass Unit:AddEnableWallAttackPromotionClass(ePromotionClass: integer) Adds a promotion class to a counted set of classes that enable attacking walls. plumbing ✓
this ✓ (oracle)
Unit::Instance::AddEnableWallAttackPromotionClass 0x3a2060
AddEspionageBonus Unit:AddEspionageBonus(eOperation: integer, bOffensive: boolean, iAmount: integer) Adds iAmount to the bonus entry for (operation, offensive flag) in the unit's espionage bonus list, creating an entry if none exists. plumbing ✓
this ✓ (oracle)
— 0x395cb0
AddEspionageTimeReduction Unit:AddEspionageTimeReduction(eOperation: integer, iReductionPercent: integer) Adds a percentage reduction to the mission time of a given spy operation type, merging into an existing entry or appending a new one. plumbing ✓
this ✓ (oracle)
Unit::Espionage::AddEspionageTimeReduction 0x395d70
AddInitialAbilities Unit:AddInitialAbilities() For each ability definition the unit can have and which is not flagged, increments the unit's ability count and dispatches a signal if the ability active state changed. plumbing ✓
this ✓ (oracle)
— 0x3a2190
CanBeLevied Unit:CanBeLevied(subjectPlayer: integer) → boolean Checks whether the unit can be levied by the given player: it must be owned by that player, not flagged at +0x2e8, and be a combat unit (melee, ranged or bombard strength > 0) or have formation class 1. plumbing ✓
this ✓ (oracle)
— 0x3a22e0
ChangeAttackRange Unit:ChangeAttackRange(iDelta: integer) Adds a delta to the unit attack range stored in an auto-variable map at +0x870. plumbing ✓
this ✓ (oracle)
— 0x3a2840
ChangeAttacksRemaining Unit:ChangeAttacksRemaining(iDelta: integer) → boolean Adds a delta to the unit attacks remaining (+0x508), clamped at 0, and fires a reporting event when the value changes. plumbing ✓
this ✓ (oracle)
— 0x3a2860
ChangeBonusPointsPerKill Unit:ChangeBonusPointsPerKill(eClass: integer, iChange: integer) Adds a delta to the great-person points a unit earns per kill for a given great person class. plumbing ✓
ran ±1, reversible ✓, no visible effect
this ✓ (oracle)
Unit::Instance::ChangeBonusPointsPerKill 0x3a2900
ChangeBonusPointsPerKillStrength Unit:ChangeBonusPointsPerKillStrength(eClass: integer, iChange: integer) Adds a delta to the strength-based great-person points per kill for a class. plumbing ✓
ran ±1, reversible ✓, no visible effect
this ✓ (oracle)
Unit::Instance::ChangeBonusPointsPerKillStrength 0x3a2940
ChangeBuildCharges ✓ Unit:ChangeBuildCharges(iChange: integer) Adds a delta to a builder unit's remaining build charges, clamped at zero, and sends an event when the delta is nonzero. plumbing ✓
effect ✓ (GetBuildCharges)
this ✓ (oracle)
Unit::Instance::ChangeBuildCharges 0x3a2980
ChangeDisasterCharges ✓ Unit:ChangeDisasterCharges(iChange: integer) Adds a delta to a unit's disaster-related charges, clamped at zero, and sends an event. plumbing ✓
effect ✓ (GetDisasterCharges)
this ✓ (oracle)
Unit::Instance::ChangeDisasterCharges 0x3a2a40
ChangeParkCharges Unit:ChangeParkCharges(iChange: integer) Adds a delta to the unit park charges (+0x550), clamped at 0, and fires a reporting event if the delta is nonzero. plumbing ✓
this ✓ (oracle)
— 0x3a2bf0
ChangeSightRange Unit:ChangeSightRange(iRangeDelta: integer) Changes the unit's sight range by a delta and refreshes the fog-of-war visibility if the unit is on the map. plumbing ✓
⚠ ran ±1, not fully reversible (lasting side effects): GetScienceYield, GetTurnsLeft
this ✓ (oracle)
Unit::Instance::ChangeSightRange 0x3a2ca0
ChangeTerritoryHealing Unit:ChangeTerritoryHealing(eTerritory: integer, iChange: integer) Adds a healing amount to the unit's per-territory healing values (three slots), selected by territory type; type 0 adds to all three. plumbing ✓
ran ±1, reversible ✓, no visible effect
this ✓ (oracle)
Unit::Instance::ChangeTerritoryHealing 0x3a2d30
ChangeTerritoryHealingReligion Unit:ChangeTerritoryHealingReligion(eTerritory: integer, iChange: integer) Same as ChangeTerritoryHealing but for the religion-based healing values. plumbing ✓
ran ±1, reversible ✓, no visible effect
this ✓ (oracle)
Unit::Instance::ChangeTerritoryHealingReligion 0x3a2db0
GetBaseMoves Unit:GetBaseMoves(eMovementDomain: integer) → number Returns the unit base movement for a domain: zero if the unit type is missing or domain mismatches, an embarked-movement value (global parameter plus owner player bonus) when embarked or able to embark on land, else the unit type movement field (+0x38). plumbing ✓
this ✓ (oracle)
— 0x3a33d0
GetBonusPointsPerKill Unit:GetBonusPointsPerKill(eClass: integer) → number Returns the great-person points per kill granted for a given great person class from an array at +0x3e8. plumbing ✓
this ✓ (oracle)
— 0x3a3500
GetBonusPointsPerKillStrength Unit:GetBonusPointsPerKillStrength(eClass: integer) → number Returns the great-person points per kill-strength for a given class from an array at +0x410. plumbing ✓
this ✓ (oracle)
— 0x3a3520
GetEra Unit:GetEra() → number Returns the era of the unit: the era of its unit type definition (from prereq tech/civic, taking the later), or the owner era if tagged CLASS_ALL_ERAS, else the earliest era; -1 if no unit type. plumbing ✓
this ✓ (oracle)
— 0x3a3720
GetEspionageBonus Unit:GetEspionageBonus(eOperation: integer, bOffensive: boolean) → number Returns the espionage bonus stored for (operation, offensive flag), or 0 if none. plumbing ✓
this ✓ (oracle)
— 0x395e00
GetEspionageTimeReduction Unit:GetEspionageTimeReduction(eOperation: integer) → number Returns the time reduction stored for the operation in the list at +0x28, or 0 if none. plumbing ✓
this ✓ (oracle)
— 0x395e60
GetIgnoreFeature Unit:GetIgnoreFeature(eFeature: integer) → boolean Returns whether the unit ignores the movement effects of a feature type, from a byte array at +0x3c0. plumbing ✓
this ✓ (oracle)
— 0x3a3940
GetIgnoreTerrain Unit:GetIgnoreTerrain(eTerrain: integer) → boolean Returns whether the unit ignores the movement effects of a terrain type, from a byte array at +0x398. plumbing ✓
this ✓ (oracle)
— 0x3a3960
GetMaxNumAttacks Unit:GetMaxNumAttacks() → number Returns maximum attacks per turn: unit bonus (+0x7a0) plus a global parameter (default 1 if zero). plumbing ✓
this ✓ (oracle)
— 0x3a3b20
HasAdjacentMove Unit:HasAdjacentMove() → boolean Checks the six neighbouring plots and returns true if the unit could be placed on one and has enough movement left (or the move costs no more than remaining movement). plumbing ✓
this ✓ (oracle)
— 0x3a3da0
HasAttacked Unit:HasAttacked() → boolean Returns true if attacks remaining (+0x508) is below the max number of attacks (global parameter default 1 plus unit bonus). plumbing ✓
this ✓ (oracle)
— 0x3a3f30
HasBypassWallsPromotionClass Unit:HasBypassWallsPromotionClass(ePromotionClass: integer) → boolean Checks whether the unit has a bypass-walls effect registered for a promotion class, via a hash table at +0x438 keyed by the class definition hash. plumbing ✓
this ✓ (oracle)
— 0x3a3f60
HasEnableWallAttackPromotionClass Unit:HasEnableWallAttackPromotionClass(ePromotionClass: integer) → boolean Checks whether the unit has an enable-wall-attack effect registered for a promotion class, via a hash table at +0x470. plumbing ✓
this ✓ (oracle)
— 0x3a3fb0
IsFortifyable Unit:IsFortifyable() → boolean Returns true if the unit has melee, ranged or bombard strength and its domain field (+0x2a0) is 2 or 3. plumbing ✓
this ✓ (oracle)
— 0x3a47e0
IsOperationDisabled Unit:IsOperationDisabled(eOperation: integer) → boolean Returns whether a unit operation type is disabled for this unit, by indexing a byte array at +0xbd8 with the operation definition index; out of range falls back to a default flag. plumbing ✓
this ✓ (oracle)
— 0x3a4830
RemoveBypassWallsPromotionClass Unit:RemoveBypassWallsPromotionClass(ePromotionClass: integer) Decrements the reference count of a promotion class in the bypass-walls hash table (+0x428) and erases the entry when it reaches zero. plumbing ✓
this ✓ (oracle)
— 0x3a4b40
RemoveEnableWallAttackPromotionClass Unit:RemoveEnableWallAttackPromotionClass(ePromotionClass: integer) Decrements the reference count of a promotion class in the enable-wall-attack hash table (+0x460) and erases the entry at zero. plumbing ✓
this ✓ (oracle)
— 0x3a4c00
RemoveEspionageBonus Unit:RemoveEspionageBonus(eOperation: integer, bOffensive: boolean, iAmount: integer) Rebuilds the espionage bonus list, subtracting iAmount from the matching (operation, offensive) entry and dropping it if the result is 0. plumbing ✓
this ✓ (oracle)
— 0x3960c0
RemoveEspionageTimeReduction Unit:RemoveEspionageTimeReduction(eOperation: integer, iReductionPercent: integer) Subtracts a percentage reduction from a spy operation's time-reduction entry, dropping the entry when it reaches exactly zero. plumbing ✓
this ✓ (oracle)
Unit::Espionage::RemoveEspionageTimeReduction 0x396210
RemoveInvalidTerrain Unit:RemoveInvalidTerrain(eTerrain: integer) Clears the flag that marks a terrain type as invalid for this unit. plumbing ✓
this ✓ (oracle)
Unit::Instance::RemoveInvalidTerrain 0x3a4cc0
SetAttacksRemaining Unit:SetAttacksRemaining(iNewAttacksRemaining: integer) Sets the unit attacks remaining (+0x508) to the given value and fires a reporting event if it changed. plumbing ✓
this ✓ (oracle)
— 0x3a5860
SetCanMoveAfterAttacking Unit:SetCanMoveAfterAttacking(delta: integer) Adjusts a counter that allows the unit to move after attacking, clamping it at zero. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetCanMoveAfterAttacking 0x3a58d0
SetCanSeeThroughFeatures Unit:SetCanSeeThroughFeatures(bCanSee: boolean) Sets whether the unit can see through terrain features and refreshes visibility when the value changes and the unit is on the map. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetCanSeeThroughFeatures 0x3a5940
SetCanSeeThroughTerrain Unit:SetCanSeeThroughTerrain(bCanSee: boolean) Sets whether the unit can see through terrain (such as hills) and refreshes visibility when changed and on the map. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetCanSeeThroughTerrain 0x3a59d0
SetHomeCityCallback Unit:SetHomeCityCallback() Unsubscribes any existing message handle and subscribes OnHomeCityDestroyed to a game signal, storing the new handle on the archaeology object. plumbing ✓
this ✓ (oracle)
Unit::Archaeology::SetHomeCityCallback 0x394fe0
SetLevied Unit:SetLevied(bLevied: boolean) Sets the unit's 'levied' flag (unit borrowed from a city-state) and notifies listeners via a game signal. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetLevied 0x3a5c50
SetOperation Unit:SetOperation(eOperation: integer) Stores the operation type index in the espionage object (+0x48). plumbing ✓
this ✓ (oracle)
— 0x396380
SetOperationDisabled Unit:SetOperationDisabled(eOperation: integer, newValue: boolean) Enables or disables a unit operation by setting a per-operation flag. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetOperationDisabled 0x3a5e50
SetProcessedTurn Unit:SetProcessedTurn(bNewValue: boolean) Sets the unit's processed-this-turn flag and sends an event when it becomes true. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetProcessedTurn 0x3a5ee0
SetSeeHiddenType Unit:SetSeeHiddenType(eHiddenVisibilityType: integer) Sets the hidden-visibility level the unit can see and refreshes visibility if the unit is on the map. plumbing ✓
this ✓ (oracle)
Unit::Instance::SetSeeHiddenType 0x3a5f60

Details

AddBypassWallsPromotionClass

Arguments: ePromotionClass — promotion class to add

Writes - hash table of class id to byte count at this+0x428

Side effects - may resize the hash table

Input checks: Looks up class definition; if not found silently returns.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (validated by definition lookup). Confidence of the reading: medium.

Verified from the code - definition lookup, return if null - resizes hash table if needed - sets entry to 1 if missing, otherwise increments the byte count

Inferred - count is a reference count so repeated adds stack

Open questions - a matching Remove is not in this batch; byte counter overflow beyond 255 unhandled

AddEnableWallAttackPromotionClass

Arguments: ePromotionClass — promotion class to add

Writes - hash table of class id to byte count at this+0x460

Side effects - may resize the hash table

Input checks: Silently returns if the class definition is not found.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (validated by definition lookup). Confidence of the reading: medium.

Verified from the code - identical logic to AddBypassWallsPromotionClass but on the table at this+0x460 - increments byte count if present else inserts 1

Inferred - counter acts as a stack count

Open questions - byte counter overflow unhandled

AddEspionageBonus

Arguments: eOperation — Unit operation type; bOffensive — True for offensive bonus, false for defensive; iAmount — Amount added to the bonus

Writes - Espionage bonus vector at Espionage+0x8

Input checks: No validation of operation or amount.

Multiplayer: may-desync, changes unit state. Risk: medium (Unchecked write.). Confidence of the reading: high.

AddEspionageTimeReduction

Arguments: eOperation — spy operation type (converted to an index via Types::GetIndex); iReductionPercent — percent to add to the reduction for that operation

Writes - vector of (operation index, reduction percent) pairs at this+0x28..0x38 (existing entry incremented or new pair appended)

Side effects - may reallocate the vector

Input checks: No range checks on operation or percent; any value is stored.

Preconditions - valid Espionage component of a spy unit

Multiplayer: safe-deterministic. Risk: low (simple list update; not synced via edit() visible here). Confidence of the reading: high.

Verified from the code - linear search for matching operation, adds param to its value - appends new 8-byte pair if not found

Inferred - entries are shown as DistrictCreateUnit type only because of shared template instantiation

Open questions - whether negative totals are clamped elsewhere

AddInitialAbilities

Writes - Unit ability count array at Instance+0x338

Side effects - Dispatches game signal at game+0x280 +0x1560 (unit, ability) when active state changes

Input checks: Uses CanHaveAbility and a definition flag; null definitions guarded loosely.

Multiplayer: may-desync, changes unit abilities. Risk: medium (Increments counts, calling twice doubles them.). Confidence of the reading: medium.

CanBeLevied

Arguments: subjectPlayer — Player compared with the unit owner (+0x140)

Input checks: Owner must equal subjectPlayer; no range check on the player id.

Multiplayer: read-only; pure check on unit state. Risk: low (pure getter). Confidence of the reading: medium.

ChangeAttackRange

Arguments: iDelta — Amount added to the attack range value

Writes - Unit attack range value in FAutoVariable at +0x870

Input checks: None; no clamping, negative results possible.

Multiplayer: may-desync; writes synchronised unit state. Risk: medium (unclamped change to unit stat). Confidence of the reading: medium.

ChangeAttacksRemaining

Arguments: iDelta — Amount added to attacks remaining

Writes - Unit attacks remaining at +0x508

Side effects - Sends reporting event 0x35597c21 with unit component id and new value

Input checks: Clamps result to >= 0; no upper bound check against max attacks.

Multiplayer: may-desync; writes synchronised unit state. Risk: medium (no upper clamp). Confidence of the reading: high.

ChangeBonusPointsPerKill

Arguments: eClass — great person class; iChange — amount to add

Writes - per-class int array at this+0x3d8

Side effects - marks the variable as edited

Input checks: Silently ignores class ids outside 0..size-1.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (bounds checked add). Confidence of the reading: high.

Verified from the code - range check -1 < id < size - adds iChange to array element

Inferred - points are awarded per kill by other combat code

ChangeBonusPointsPerKillStrength

Arguments: eClass — great person class; iChange — amount to add

Writes - per-class int array at this+0x400

Side effects - marks the variable as edited

Input checks: Silently ignores class ids outside 0..size-1.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (bounds checked add). Confidence of the reading: high.

Verified from the code - range check against size at +0x420 - adds iChange to the element

Inferred - Strength variant scales with enemy strength (from name)

ChangeBuildCharges

Arguments: iChange — delta to charges

Writes - build charges at this+0x538 (auto-variable at this+0x528), clamped to >= 0

Side effects - sends Reporting::Event 0xb2176dc4 with unit id, new charges and old charges when iChange != 0

Input checks: Result below 0 is clamped to 0. No upper bound.

Preconditions - unit with builder charges

Multiplayer: safe-deterministic. Risk: low (Clamped integer change). Confidence of the reading: high.

Verified from the code - clamps at 0 - event only when iChange != 0 - event carries new then old value

Inferred - offset +0x538 is the build charges field

Open questions - whether charge reaching zero destroys the unit here (not in this function)

ChangeDisasterCharges

Arguments: iChange — delta to charges

Writes - disaster charges at this+0x5c8 (auto-variable at this+0x5b8), clamped to >= 0

Side effects - sends Reporting::Event 0xb2176dc4 (same id as ChangeBuildCharges) with unit id, new and old value when iChange != 0

Input checks: Negative result clamped to 0.

Preconditions - gameplay state

Multiplayer: safe-deterministic. Risk: low (Clamped integer change). Confidence of the reading: medium.

Verified from the code - same shape as ChangeBuildCharges at a different offset - clamps at 0 - event only when iChange != 0

Inferred - meaning of the field comes from the name only - event id shared with build charges suggests a generic charge-changed event

Open questions - which event id distinguishes disaster from build charges

ChangeParkCharges

Arguments: iChange — Amount added to park charges

Writes - Unit park charges at +0x550

Side effects - Sends reporting event 0xb2176dc4 with unit id, new and old value

Input checks: Clamps result to >= 0; no upper bound.

Multiplayer: may-desync; writes synchronised unit state. Risk: medium (changes unit charge counter). Confidence of the reading: medium.

ChangeSightRange

Arguments: iRangeDelta — change to sight range

Observed in the game: Not undone by a -1 call: increasing the sight range reveals map tiles immediately, and if a revealed tile belongs to a city-state the game meets it at once (user-observed: a scientific city-state was met, which gives a free envoy and raised the science yield 3.5 -> 4.5 and shortened the research turns left 7 -> 6). The meeting and the revealed tiles stay when the range is lowered again.

Writes - sight range int in game variable at this+0x858

Side effects - calls Sight::Manager::UpdateMap for the unit's plot when it has a valid position, updating visibility

Input checks: Ignores zero delta and any result that would be negative; position check (> -9999) decides whether to refresh sight.

Preconditions - gameplay state

Multiplayer: may-desync: visibility updates should be identical on all clients. Risk: low (guarded against negative range). Confidence of the reading: high.

Verified from the code - returns early if delta == 0 or new range < 0 - stores new range via edit() on this+0x858 - calls Sight::Manager::UpdateMap(this, plot, true) only when both coords > -9999

Inferred - -9999 coords mean off-map

ChangeTerritoryHealing

Arguments: eTerritory — territory type 0..3; iChange — healing delta

Writes - three ints in game variable at this+0x750

Side effects - marks variable edited

Input checks: Territory values other than 0 to 3 are silently ignored.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (fixed small switch). Confidence of the reading: medium.

Verified from the code - 0 adds to slots 0,1,2 - 1 adds to slot 2 (offset +8) - 2 adds to slot 1 (+4) - 3 adds to slot 0

Inferred - type 0 is probably all territories; 1..3 map to individual territory kinds (names unknown)

Open questions - which TerritoryTypes enum values map to which slot by name

ChangeTerritoryHealingReligion

Arguments: eTerritory — territory type 0..3; iChange — healing delta

Writes - three ints in game variable at this+0x770

Side effects - marks variable edited

Input checks: Territory values other than 0 to 3 are silently ignored.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (fixed small switch). Confidence of the reading: medium.

Verified from the code - same slot mapping as ChangeTerritoryHealing but on this+0x770

Inferred - religion variant applies when the religious source applies (from name)

Open questions - exact slot-to-territory naming

GetBaseMoves

Arguments: eMovementDomain — Domain for which movement is queried (-1 means any/current) (inferred)

Input checks: Returns 0 if unit type pointer is null; domain not otherwise range checked.

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

GetBonusPointsPerKill

Arguments: eClass — Great person class index

Input checks: Bounds checked against array size (0..size-1); returns 0 otherwise.

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

GetBonusPointsPerKillStrength

Arguments: eClass — Great person class index

Input checks: Bounds checked against array size; returns 0 otherwise.

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

GetEra

Input checks: Null checks on unit type and linked definitions.

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

GetEspionageBonus

Arguments: eOperation — Unit operation type; bOffensive — Offensive or defensive bonus

Input checks: None.

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

GetEspionageTimeReduction

Arguments: eOperation — Unit operation type

Input checks: None; note the loop matches the first entry with the same index.

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

GetIgnoreFeature

Arguments: eFeature — Feature type index

Input checks: Rejects -1 and indexes beyond array size; other negative values are not checked.

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

GetIgnoreTerrain

Arguments: eTerrain — Terrain type index

Input checks: Rejects -1 and indexes beyond array size; other negative values are not checked.

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

GetMaxNumAttacks

Input checks: None needed.

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

HasAdjacentMove

Input checks: Skips null plots and invalid coordinates; uses placement validity check.

Multiplayer: read-only; evaluates map and unit state. Risk: low (pure check). Confidence of the reading: medium.

HasAttacked

Input checks: None.

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

HasBypassWallsPromotionClass

Arguments: ePromotionClass — Unit promotion class type

Input checks: Returns false if class definition not found.

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

HasEnableWallAttackPromotionClass

Arguments: ePromotionClass — Unit promotion class type

Input checks: Returns false if class definition not found.

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

IsFortifyable

Input checks: None.

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

IsOperationDisabled

Arguments: eOperation — Unit operation type

Input checks: Unknown operation gives index -1 and returns false; range checked against array size.

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

RemoveBypassWallsPromotionClass

Arguments: ePromotionClass — Unit promotion class type

Writes - Bypass-walls promotion class table at +0x428

Input checks: Does nothing if class unknown or not in table.

Multiplayer: may-desync; writes synchronised unit state. Risk: medium (changes unit combat ability). Confidence of the reading: medium.

RemoveEnableWallAttackPromotionClass

Arguments: ePromotionClass — Unit promotion class type

Writes - Enable-wall-attack promotion class table at +0x460

Input checks: Does nothing if class unknown or not in table.

Multiplayer: may-desync; writes synchronised unit state. Risk: medium (changes unit combat ability). Confidence of the reading: medium.

RemoveEspionageBonus

Arguments: eOperation — Unit operation type; bOffensive — Offensive or defensive bonus; iAmount — Amount to subtract

Writes - Espionage bonus vector at Espionage+0x8 (rebuilt)

Input checks: No check that the entry exists or amount is positive; negative remainders are kept.

Multiplayer: may-desync, changes unit state. Risk: medium (Rebuilds list, unchecked.). Confidence of the reading: medium.

RemoveEspionageTimeReduction

Arguments: eOperation — spy operation type; iReductionPercent — percent to subtract

Writes - rebuilds the (operation, percent) vector at this+0x28..0x38

Side effects - allocates and frees a temporary copy of the vector

Input checks: No checks; if operation not found nothing changes (list is rebuilt identically). Entry only removed when result is exactly 0; negative results stay.

Preconditions - valid Espionage component

Multiplayer: safe-deterministic. Risk: low (list maintenance only). Confidence of the reading: high.

Verified from the code - copies vector, clears the live one, re-inserts every entry - matching entry value reduced by param and omitted if zero

Inferred - counterpart of AddEspionageTimeReduction

RemoveInvalidTerrain

Arguments: eTerrain — terrain type whose invalid flag is cleared

Writes - byte flag array at this+0x360 (index set to 0)

Side effects - marks variable edited

Input checks: Ignores -1 and ids at or above size. Large negative values other than -1 are not rejected by the first check (signed compare only against size), so a negative id would index before the array (crash risk).

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: medium (negative ids other than -1 not rejected). Confidence of the reading: high.

Verified from the code - checks id != -1 and id < size - sets byte at index to 0

Inferred - flag 1 means terrain is invalid for the unit

Open questions - signed or unsigned comparison for negatives is only inferred from the decompile

SetAttacksRemaining

Arguments: iNewAttacksRemaining — New attacks remaining value

Writes - Unit attacks remaining at +0x508

Side effects - Sends reporting event 0x35597c21 with unit component id and value

Input checks: None; negative or above-max values accepted.

Multiplayer: may-desync; writes synchronised unit state. Risk: medium (unvalidated value). Confidence of the reading: high.

SetCanMoveAfterAttacking

Arguments: delta — amount added to the counter

Writes - counter at this+0x640 (tracked variable at this+0x630)

Side effects - tracked variable assignment

Input checks: Negative totals are clamped to 0.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (clamped counter). Confidence of the reading: high.

Verified from the code - adds delta to existing value - resets to 0 if result is negative

Inferred - nonzero means unit can move after attacking

SetCanSeeThroughFeatures

Arguments: bCanSee — new value

Writes - bool at this+0x690 (value byte at +0x6a0)

Side effects - calls Sight::Manager::UpdateMap when on the map

Input checks: No-op if unchanged.

Preconditions - gameplay state

Multiplayer: may-desync: visibility change must match on all clients. Risk: low (simple flag). Confidence of the reading: high.

Verified from the code - only acts if value differs - updates sight map only when both coords > -9999

Inferred - feature means map features like forest

SetCanSeeThroughTerrain

Arguments: bCanSee — new value

Writes - bool at this+0x6a8 (value byte at +0x6b8)

Side effects - calls Sight::Manager::UpdateMap when on the map

Input checks: No-op if unchanged.

Preconditions - gameplay state

Multiplayer: may-desync: visibility change must match on all clients. Risk: low (simple flag). Confidence of the reading: high.

Verified from the code - mirrors SetCanSeeThroughFeatures with different offsets

Inferred - terrain means hills or mountains blocking line of sight

SetHomeCityCallback

Writes - message handle at this+0x20 - signal link ring and a counter in game signal object (current game +0x280)

Side effects - subscribes a callback bound to this object to a game-wide signal

Input checks: None; assumes the current game exists.

Preconditions - current game exists - must be called on the game thread

Multiplayer: safe-deterministic. Risk: low (subscription bookkeeping only). Confidence of the reading: medium.

Verified from the code - calls Handle::Unsubscribe on this+0x20 - adds a std::function wrapper of OnHomeCityDestroyed to a signal in the game's signal block at +0x210/+0x218 - stores new handle into this+0x20 - increments a counter at signal object +0x220

Inferred - signal is probably a city-destroyed type event (lambda signature mentions City, BuildingTypes, int, bool)

Open questions - exact signal identity (symbol mismatched)

SetLevied

Arguments: bLevied — new levied state

Writes - levied bool auto-variable at unit this+800

Side effects - dispatches unit-levied-changed signal on the current game's signal table (+0x16c8)

Input checks: None; signal dispatch uses current game pointer unchecked.

Preconditions - game thread - current game must exist

Multiplayer: may-desync: sets synced unit state. Risk: low (single flag plus signal). Confidence of the reading: high.

Verified from the code - writes bool at this+800 - dispatches signal with the unit pointer

Inferred - flag drives levy return logic

SetOperation

Arguments: eOperation — Operation type to set

Writes - Current operation field at Espionage+0x48

Input checks: None.

Multiplayer: may-desync, writes unit field. Risk: low (Single field write.). Confidence of the reading: high.

SetOperationDisabled

Arguments: eOperation — operation to disable or enable; newValue — true disables the operation (inferred)

Writes - byte flag array at this+0xbc8 indexed by operation index

Side effects - marks variable edited

Input checks: Unknown operation maps to index -1 which fails the size check and nothing happens. A fallback path writes a default byte in the container if the index is outside the edited container's own size.

Preconditions - gameplay state

Multiplayer: may-desync: direct state change. Risk: low (validated index). Confidence of the reading: medium.

Verified from the code - looks up the operation definition and reads its index at +0x14 - checks index < size at this+0xbe8 - stores the bool at that index

Inferred - flag true means disabled

Open questions - purpose of the fallback byte write at offset 0x18 of the container

SetProcessedTurn

Arguments: bNewValue — new processed flag

Writes - bool at this+0x258 (auto-variable at this+0x248)

Side effects - sends Reporting::Event 0xd70ba51f with unit id only when the flag becomes true

Input checks: No-op if unchanged. No other checks.

Preconditions - gameplay state

Multiplayer: safe-deterministic. Risk: low (Simple flag set with one event). Confidence of the reading: medium.

Verified from the code - early-out on equal value - event sent only when new value is nonzero

Inferred - the flag means the unit has finished its turn processing

Open questions - what code reads this flag to skip units

SetSeeHiddenType

Arguments: eHiddenVisibilityType — new see-hidden level

Writes - see-hidden value in variable group at this+0x858 (second field, read at +0x86c)

Side effects - calls Sight::Manager::UpdateMap when on the map

Input checks: No-op if value is unchanged; no range check on the enum.

Preconditions - gameplay state

Multiplayer: may-desync: visibility change. Risk: low (simple value set). Confidence of the reading: high.

Verified from the code - only acts if different - updates sight map only when coords > -9999

Inferred - higher levels likely see more hidden unit types