Home › Dev CE (experimental) › UnitExperience
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.
UnitExperience
7 methods (Dev CE test build). this is found with the game's own IUnitExperience instance resolver (plain).
| Method |
Signature |
Purpose (AI-written, inferred) |
Tested |
Engine function |
Current |
| CanEarnPromotion |
UnitExperience:CanEarnPromotion(ePromotion: integer, bIgnoreRandomPromotionCheck: boolean) → boolean |
Checks whether a unit can earn a promotion: promotion exists and not already owned, if the unit type requires proposed promotions it must be proposed, class must be valid for the unit type, and all or any prerequisite is owned. |
plumbing ✓ this ✓ (oracle) |
— |
0x3969a0 |
| ChangeGeneralExperienceModifier |
UnitExperience:ChangeGeneralExperienceModifier(iDelta: integer) |
Adds a percentage-like delta to the unit's general experience modifier, stored as 24.8 fixed point. |
plumbing ✓ ran ±1, reversible ✓, no visible effect this ✓ (oracle) |
Unit::Experience::ChangeGeneralExperienceModifier |
0x396d70 |
| CheckPromoteNotification |
UnitExperience:CheckPromoteNotification() |
If the experience flags at +8 and +9 are set, clears +9 and for human owners adds the unit to a PromoteUnit notification, creating one if needed. |
plumbing ✓ this ✓ (oracle) |
— |
0x396dc0 |
| GetExperienceModifier |
UnitExperience:GetExperienceModifier(bIsUnitAttacking: boolean) → number |
Returns a fixed-point combat modifier from unit experience: base value at +0x28 plus an optional attacker part from +0x2c plus a player bonus scaled by 0.01. |
plumbing ✓ this ✓ (oracle) |
— |
0x396f60 |
| GrantPromotion |
UnitExperience:GrantPromotion(ePromotion: integer, bIgnoreRandomPromotionCheck: boolean) |
Grants a promotion to a unit if it is allowed to earn it, marking it as selected in the owner's unit table and applying it. |
plumbing ✓ this ✓ (oracle) |
Unit::Experience::GrantPromotion |
0x3970f0 |
| SetLevel |
UnitExperience:SetLevel(iLevel: integer) |
Sets a unit's experience level directly and sends an event. |
plumbing ✓ this ✓ (oracle) |
Unit::Experience::SetLevel |
0x3974a0 |
| SetLevelAndExperience |
UnitExperience:SetLevelAndExperience(iLevel: integer, iExperience: integer) |
Sets the experience level (+0x10), clears experience flags and counter (+8,+0xa,+0xc), then calls ChangeExperience with the given amount. |
plumbing ✓ this ✓ (oracle) |
— |
0x397500 |
Details
CanEarnPromotion
Arguments: ePromotion — Promotion type to test; bIgnoreRandomPromotionCheck — If true skips the proposed-promotion (random choice) check
Input checks: Checks promotion index validity and ownership; unit type pointer used without null check.
Multiplayer: read-only; evaluates unit state. Risk: low (pure check). Confidence of the reading: medium.
ChangeGeneralExperienceModifier
Arguments: iDelta — change in percent
Writes
- fixed-point modifier at this+0x28
Side effects
- none
Input checks: none needed
Preconditions
- valid Experience object
Multiplayer: safe-deterministic. Risk: low (simple arithmetic; uses floorf but deterministic). Confidence of the reading: high.
Verified from the code
- multiplies iDelta by a float constant (likely 0.01)
- splits into integer and fractional (x256) parts and adds to +0x28 as (int<<8)/frac
Inferred
- constant is 1/100 so iDelta is a percent
- stored as 8-bit fixed point
Open questions
- float constants not read directly (symbol names only)
CheckPromoteNotification
Writes
- Experience flag at +9 cleared
Side effects
- Creates or updates the promote-unit notification for the owner
Input checks: Only acts for human players; returns if notification creation fails.
Multiplayer: may-desync; notifications and unit flag, human only. Risk: low (notification only). Confidence of the reading: medium.
GetExperienceModifier
Arguments: bIsUnitAttacking — If true, adds the attacking experience component (inferred)
Input checks: None.
Multiplayer: read-only; computes from state. Risk: low (pure getter). Confidence of the reading: low.
GrantPromotion
Arguments: ePromotion — promotion type; bIgnoreRandomPromotionCheck — skip the random-promotion restriction in CanEarnPromotion (inferred)
Writes
- owner player's Units promotion-selected state via SetPromotionSelected
- unit promotion list via SetPromotion
Side effects
- Player::Units::SetPromotionSelected(unit type, promotion, false)
- Experience::SetPromotion
Input checks: silently does nothing when CanEarnPromotion returns false; owner index not bounds checked
Preconditions
- unit belongs to a valid player
- gameplay thread
Multiplayer: safe-deterministic. Risk: low (guarded by CanEarnPromotion). Confidence of the reading: high.
Verified from the code
- calls CanEarnPromotion with both args first
- on success updates owner's Units via SetPromotionSelected then SetPromotion
Inferred
- bool name from Linux debug info implies it bypasses random promotion gating
Open questions
- what exactly CanEarnPromotion checks
SetLevel
Arguments: iLevel — new level
Writes
- level at this+0x10
Side effects
- sends Reporting::Event 0xa038d885 with unit id and new level (always, even if unchanged)
Input checks: No validation of level range or unchanged value.
Preconditions
- gameplay state
Multiplayer: safe-deterministic. Risk: medium (Unvalidated level could break promotion logic). Confidence of the reading: high.
Verified from the code
- writes level unconditionally
- always sends event
- does not touch XP or promotions
Inferred
- promotion availability may depend on level vs promotions taken
Open questions
- whether other code expects level to match XP
SetLevelAndExperience
Arguments: iLevel — New experience level; iExperience — Experience points passed to ChangeExperience
Writes
- Experience level at +0x10
- Experience fields at +8,+0xa,+0xc reset
- Experience points via ChangeExperience
Side effects
- Whatever ChangeExperience triggers (possible promotion notification)
Input checks: None; level not range checked.
Multiplayer: may-desync; writes synchronised unit experience. Risk: medium (unvalidated level and xp). Confidence of the reading: medium.