Home › Dev CE (experimental) › PlayerTechs
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.
PlayerTechs
11 methods (Dev CE test build). this is found with the game's own IPlayerTechs instance resolver (plain).
| Method |
Signature |
Purpose (AI-written, inferred) |
Tested |
Engine function |
Current |
| CanTriggerBoost |
PlayerTechs:CanTriggerBoost(eTech: integer) → boolean |
Checks whether the boost attached to the given tech can currently be triggered for this player; first requires Game::Culture::HasCivic to be true for the id. |
plumbing ✓ this ✓ (oracle) |
— |
0x333530 |
| DoResearch |
PlayerTechs:DoResearch() |
Per-turn research step: computes science yield, adds it to an accumulated amount and applies it to the current research (first queue entry) or stores it if nothing is being researched. |
plumbing ✓ this ✓ (oracle) |
— |
0x3337a0 |
| FindBestTechtoStealFromPlayer |
PlayerTechs:FindBestTechtoStealFromPlayer(targetPlayer: integer) → number |
Picks a tech to steal from the target player by scanning tech definitions and building candidate lists; decompilation is truncated so the final selection logic is not visible. |
plumbing ✓ this ✓ (oracle) |
— |
0x333a00 |
| GetNumTechsResearched |
PlayerTechs:GetNumTechsResearched(bIncludeRepeatedTechs: boolean) → number |
Counts the techs flagged as researched, optionally adding the repeated-tech count. |
plumbing ✓ this ✓ (oracle) |
— |
0x333cd0 |
| GrantAllBoostsByEra |
PlayerTechs:GrantAllBoostsByEra(eStartEra: integer, eEndEra: integer) |
Triggers the eureka boost for every tech in the eras between eStartEra and eEndEra that has a boost, is not researched and has not yet been boosted. |
plumbing ✓ this ✓ (oracle) |
— |
0x3340a0 |
| GrantRandomBoostGoodyHut |
PlayerTechs:GrantRandomBoostGoodyHut(iNumFreeBoosts: integer, eSource: integer) |
Grants a number of random tech boosts (from the era of the cheapest not-yet-owned tech) to a player, used by goody huts. |
plumbing ✓ this ✓ (oracle) |
Player::Techs::GrantRandomBoostGoodyHut |
0x3342e0 |
| GrantRandomBoostsByEra |
PlayerTechs:GrantRandomBoostsByEra(iNumFreeBoosts: integer, eStartEra: integer, eEndEra: integer) |
Collects boostable techs from eras in a range, then randomly triggers a number of their eurekas for the player using the game RNG. |
plumbing ✓ this ✓ (oracle) |
Player::Techs::GrantRandomBoostsByEra |
0x3346d0 |
| GrantRandomTechs |
PlayerTechs:GrantRandomTechs(iNumTechs: integer) |
Builds the list of researchable techs, then randomly picks iNumTechs of them and sets their research progress to full cost; decompilation is truncated at the end of the loop. |
plumbing ✓ this ✓ (oracle) |
— |
0x334a00 |
| SetAllTechsByPreviousEra |
PlayerTechs:SetAllTechsByPreviousEra(eEraType: integer) |
Grants every technology whose era is earlier than the given era (index >1), recomputing unit/district costs and signalling each grant. |
plumbing ✓ this ✓ (oracle) |
Player::Techs::SetAllTechsByPreviousEra |
0x335a30 |
| SetNumFreeTechBoostOnNewEra |
PlayerTechs:SetNumFreeTechBoostOnNewEra(numBoosts: integer, applyImmediately: boolean) |
Adds to the number of free tech boosts granted on entering a new era and optionally grants boosts immediately. |
plumbing ✓ this ✓ (oracle) |
Player::Techs::SetNumFreeTechBoostOnNewEra |
0x335b80 |
| SetScienceRateChange |
PlayerTechs:SetScienceRateChange(xNewValue: number (fixed point, 1/256 steps)) |
Sets the science rate change value if it differs from the current one and sends an event. |
plumbing ✓ this ✓ (oracle) |
— |
0x336590 |
Details
CanTriggerBoost
Arguments: eTech — Tech type whose boost is tested
Input checks: Returns false when HasCivic fails or no boost matches; index not otherwise checked.
Multiplayer: read-only, only reads player/map state. Risk: low (pure getter). Confidence of the reading: medium.
DoResearch
Writes
- Research progress of the current tech (via ChangeResearchProgress)
- Stored leftover science value at +0xf8
Side effects
- Sends a research notification (hash 0x592df4c8) to the player
Input checks: No validation except an empty queue or -1 head, which stores science instead.
Multiplayer: may-desync, changes research progress. Risk: high (Advances research and sends a notification). Confidence of the reading: medium.
FindBestTechtoStealFromPlayer
Arguments: targetPlayer — Player to steal from
Input checks: Returns -1 for an invalid target player; target is not otherwise checked.
Multiplayer: read-only, only builds temporary candidate lists. Risk: low (Looks like a selector, but the body is cut off). Confidence of the reading: low.
GetNumTechsResearched
Arguments: bIncludeRepeatedTechs — If true adds the repeatable-tech counter (+0x1c8)
Input checks: No validation.
Multiplayer: read-only, only reads player/map state. Risk: low (pure getter). Confidence of the reading: high.
GrantAllBoostsByEra
Arguments: eStartEra — First era (inclusive); eEndEra — Last era (inclusive)
Writes
- Boost-triggered state for each qualifying tech (via TriggerBoost)
Side effects
- TriggerBoost may raise events/notifications for each tech
Input checks: Era indices are bounds checked; if either era is invalid nothing is boosted.
Multiplayer: may-desync, triggers boosts changing research. Risk: medium (Mass-triggers boosts, but only for unresearched techs). Confidence of the reading: medium.
GrantRandomBoostGoodyHut
Arguments: iNumFreeBoosts — how many boosts to grant; eSource — source of the boost, passed to TriggerBoost
Writes
- triggers tech boosts through Techs::TriggerBoost
- consumes random numbers
Side effects
- calls Techs::TriggerBoost per selected tech
- advances game RNG (label: Choosing random tech boost to grant based on era)
- heap-allocates candidate list on overflow
Input checks: Does nothing if count <= 0 or no candidates; tech ids of -1 or out of range skip the already-boosted checks.
Preconditions
- valid player
- game thread
Multiplayer: safe-deterministic. Risk: low (normal gameplay path using game RNG). Confidence of the reading: medium.
Verified from the code
- structure mirrors the Culture version: find lowest-era unowned tech, collect its era's available boosts, pick randomly without repeats
- uses GetRandNum with the label 'Choosing random tech boost to grant based on era'
- calls TriggerBoost for chosen techs not already boosted
Inferred
- decompiler mislabels Government/Culture types; actual types are technologies
Open questions
- exact era selection due to decompiler type confusion
GrantRandomBoostsByEra
Arguments: iNumFreeBoosts — number of boosts to grant; eStartEra — first era of range; eEndEra — last era of range
Writes
- tech boost state via TriggerBoost(tech, 3)
Side effects
- TriggerBoost per chosen tech with source 3
- consumes game RNG draws (named 'Choosing random tech boost...')
Input checks: Silent no-op if either era is not found; stops when no candidates remain.
Preconditions
- game thread
- valid eras
Multiplayer: safe-deterministic: uses the synced game RNG with a log string. Risk: medium (triggers boosts, RNG consumption). Confidence of the reading: medium.
Verified from the code
- filters by era range, HasBoost, HasCivic, not HasTech, not already triggered
- picks via Game::Instance::GetRandNum and removes chosen from list
- calls TriggerBoost with 3
Inferred
- HasCivic on the tech id is likely a mislabeled check
- candidate weights are all 1
Open questions
- meaning of TriggerBoost source value 3
- oddity of HasCivic check on a tech id
GrantRandomTechs
Arguments: iNumTechs — How many random techs to grant
Writes
- Research progress of the chosen techs (SetResearchProgress)
Side effects
- Consumes game random numbers
- Likely completes techs and triggers their unlock events
Input checks: Stops when the candidate list is empty; iNumTechs <= 0 does nothing.
Multiplayer: may-desync, uses game RNG and changes techs. Risk: high (Gives free techs and uses synchronized RNG). Confidence of the reading: low.
SetAllTechsByPreviousEra
Arguments: eEraType — era; techs from earlier eras are granted
Writes
- tech-researched byte array at this+0x128
Side effects
- Units::RecomputeAllCosts and Districts::RecomputeAllCosts for each tech granted
- signal (Unit*,uint) at game signal +0x12f0 with player and tech id
Input checks: Era pointer used unchecked if index out of range (null deref risk); does nothing when era index <=1.
Preconditions
- game thread
- valid era
Multiplayer: may-desync: bulk grant. Risk: medium (bulk tech grant, expensive recompute per tech). Confidence of the reading: medium.
Verified from the code
- only techs with era value below target
- recomputes unit and district costs for each
- dispatches per-tech signal
Inferred
- does not grant eurekas or tech side effects beyond the signal
Open questions
- whether already known techs are re-signalled (no check seen)
SetNumFreeTechBoostOnNewEra
Arguments: numBoosts — amount added to the stored count (despite the Set name it is additive); applyImmediately — also grant random boosts now for the current era
Writes
- int auto-variable at this+0x1a0 (stored count at this+0x1b0 plus numBoosts)
Side effects
- when applyImmediately, current era valid and numBoosts > 0: calls GrantRandomBoostsByEra, which grants random tech boosts (uses random numbers)
Input checks: Immediate grant is skipped if the era is -1 or numBoosts is not positive. The stored count is updated regardless.
Preconditions
- gameplay Lua state only
- owner player must be set
Multiplayer: may-desync: random boost selection must use the synchronized game RNG. Risk: medium (additive despite Set name, plus random grant side effect). Confidence of the reading: medium.
Verified from the code
- stored value = old + numBoosts
- calls GrantRandomBoostsByEra only if applyImmediately, era != -1 and numBoosts > 0
Inferred
- GrantRandomBoostsByEra takes the era twice, probably a from/to range
- negative numBoosts reduces stored count
Open questions
- whether the era-change handler consumes the stored count
SetScienceRateChange
Arguments: xNewValue — New science rate change as a fixed point value
Writes
- Science rate change at +0x110/+0x120
Side effects
- Sends an event (hash 0xdca96e74) for the owning player
Input checks: No validation; skips when the value is unchanged.
Multiplayer: may-desync, writes player state. Risk: medium (Only modifies a rate and sends an event). Confidence of the reading: high.