AGENT ABILITIES -> ACTION IMPLEMENTATIONS (FILTERED) ===================================================== This document maps each agent's abilities from agents.txt to how they can be implemented as subclasses of the Action class in main-2.py. SCOPE: Only agents affecting Steel, Electrum, Brass, or Capital production/consumption. The Action class framework provides: - declare_vars(model, i, t, ctx): Create decision variables for (city i, step t) - add_constraints(model, i, t, ctx): Add precondition/legality constraints - add_global_constraints(model, t, ctx): Add per-step global constraints - contributes_gains_costs(model, i, t, ctx): Modify resource gains/costs - transition_contrib(model, i, t, ctx): Handle state transitions - selector_var(i, t, ctx): The boolean variable indicating action is chosen - describe(solver, i, t, ctx): Return human-readable action description GOVERNOR CONSTRAINTS: - Each city can have at most 1 governor at a time: governor[i,t] ∈ {0,1} - Each governor can only apply their benefit to at most 1 city per turn (multiple unique governors can each apply benefits to different cities in the same turn) ═══════════════════════════════════════════════════════════════════════════════ INDUSTRIAL FOLLOWERS ═══════════════════════════════════════════════════════════════════════════════ CAPITALIST ────────── Ability: Infinite Growth (As Governor, increases Capital Collection by +2) Implementation: GovernorModifierAction("infinite_growth") - add_constraints: Checks if appointed as Governor of city - contributes_gains_costs: - When Governor, append +2 to Capital gains for Collect actions - Use OnlyEnforceIf(governor[i,t]) logic METALLURGIST ───────────── Ability: Metallurgy (As Governor of Foundry, grants Overflow Vats Upgrade effect) Implementation: GovernorSpecialAction("metallurgy") - add_constraints: - Must be Governor AND city must be Foundry - Precondition: isF[i,t] == 1 AND governor[i,t] == 1 - transition_contrib: - When triggered, vat values increase as if Overflow Vats upgrade active - Grant vat[i,t+1] = vat[i,t] + 2 (instead of +1 from upgrade_d) FOREMAN ─────── Ability: Restructure (As Governor, Renovating does not prevent other Industry Actions) Implementation: RenovationModifierAction("restructure") - add_constraints: Governor check + city is being renovated - transition_contrib: - Normally, renovating blocks other actions - With Restructure, allow simultaneous industry action - Create is_restructuring boolean, allow other actions when true ARTIFICER ────────── Ability: Wondrous Craft (As Governor, Collects extra Trade Good) Implementation: GovernorModifierAction("wondrous_craft") - add_constraints: Governor check - contributes_gains_costs: - When Governor does Collect, add +1 to trade goods count - Track trade_goods accumulator separately from base resources PLANNER ─────── Ability: Orchestrate Overwork (As Governor, allows the Overwork action on the city they govern) Implementation: GovernorModifierAction("planner") - add_constraints: - Governor check: must be Governor of city - Enables Overwork action when present - Modifies OverworkAction: - Remove global "at most 1 city overworks per step" constraint - Add constraint: city can only Overwork if Planner is Governor - Enables multiple cities to overwork simultaneously if they each have Planner ═══════════════════════════════════════════════════════════════════════════════ DIPLOMATIC FOLLOWERS (SPECIAL) - BIDDING/HIRING EFFECTS ═══════════════════════════════════════════════════════════════════════════════ FENCE ───── Ability: Customs Acquisitions (When hired, bonus of 2 Trade Goods) Implementation: InitializerAction("customs_acquisitions") - declare_vars: Create hired_this_turn boolean for city - add_constraints: Triggers exactly once at hiring step - contributes_gains_costs: - Add +2 Trade Goods to step of hiring ═══════════════════════════════════════════════════════════════════════════════ INDUSTRIAL FOLLOWERS (CONTINUED) ═══════════════════════════════════════════════════════════════════════════════ COURIER ─────── Ability: Supply Cache (When first appointed Governor, bonus of 3 Capital/Steel/Brass) Implementation: InitializerAction("supply_cache") - declare_vars: - Create governor_appointed[i,t] boolean (checks transition to governor) - Create supply_cache_triggered[i] boolean (one-time flag) - add_constraints: - Trigger only on first governorship - Mark supply_cache_triggered to prevent re-triggering - contributes_gains_costs: - Add +3 Capital, +3 Steel, +3 Brass to step of first appointment PROVISIONER ──────────── Ability: Credit Line (When appointed Governor of City with Base, gain 1.5 Electrum) Implementation: GovernorSpecialAction("credit_line") - declare_vars: Create governor[i,t] boolean - add_constraints: - Must be Governor AND city must have military Base - Check has_base[i,t] from military tracking - contributes_gains_costs: - Add +1.5 Electrum (represented as fractional or +1 with +0.5 flag) PRODIGY ─────── Ability: Steel Efficiency (As Governor, when Upgrading/Launching Airship, refund 2 Steel) Implementation: GovernorModifierAction("steel_efficiency") - add_constraints: - Governor check - Action must be upgrade or airship launch - contributes_gains_costs: - Find cost_S for upgrade actions - Append -2 (refund) when conditions met - Constraint: refund = max(0, cost_S - 2) or simply subtract 2 INDUSTRIALIST ────────────── Ability: Network (When appointed Governor, City + adjacent Cities gain Infrastructure) Implementation: GovernorSpecialAction("network") - declare_vars: Create infrastructure[i,t] boolean - add_constraints: - Triggers when city appointed as governor - Applies to all adjacent cities (within adjacency graph) - transition_contrib: - Mark target city and neighbors with infrastructure upgrade - Infrastructure persists through subsequent steps ECONOMIST ────────── Ability: Velocity of Money (Gain 1 Renown per 10 Capital Collected and Spent on Collection) Implementation: TriggerAction("velocity_of_money") - declare_vars: - Create capital_spent[i,t] accumulator (tracks collection costs) - Create capital_collected[i,t] accumulator (tracks collection gains) - add_constraints: - Track capital flow through Collect actions on this city - contributes_gains_costs: - Calculate velocity_renown = (capital_spent + capital_collected) // 10 - Append velocity_renown to Renown gains each step - transition_contrib: Reset accumulators each step ═══════════════════════════════════════════════════════════════════════════════ BROTHERHOOD STARTING FOLLOWERS ═══════════════════════════════════════════════════════════════════════════════ BARON ───── Ability: Barter (As Governor, Collecting generates +1 Trade Good per Bastion) Implementation: GovernorModifierAction("barter") - add_constraints: - Governor check - Action must be Collect - contributes_gains_costs: - Count bastions on map via bastion[*,t] - Add +1 Trade Good per bastion to Collect action - Use: trade_good_bonus = count(bastion[i,t] for all i) BUILDER ──────── Ability: Build Better (When appointed Governor of City, give City its type-specific Upgrade) Implementation: GovernorSpecialAction("build_better") - declare_vars: Create governor[i,t] and auto_upgrade[i,t] - add_constraints: - Trigger when appointed Governor - City type determines which upgrade (Hub → special, Foundry → vat, etc.) - transition_contrib: - Determine city type isH/isF/isM/isMon - Auto-apply corresponding type-specific upgrade (hasA/hasB/hasD based on type) - For Foundry: initialize vats or enhance them ═══════════════════════════════════════════════════════════════════════════════ SPECIALIZED ACTION CLASSES TO CREATE ═══════════════════════════════════════════════════════════════════════════════ To implement the above, create these base action classes: 1. ModifierAction(name) - Base for abilities that modify existing actions - Override contributes_gains_costs to append bonuses 2. GovernorModifierAction(name) - Base for abilities tied to Governor position - add_constraints checks governor status - Child classes override contributes_gains_costs - Used by: CAPITALIST, PRODIGY, BARON 3. GovernorSpecialAction(name) - Base for complex governor-tied effects - Combines modifier + transition logic - Used by: PROVISIONER, INDUSTRIALIST, BUILDER 4. InitializerAction(name) - One-time bonuses when agent hired/appointed - declare_vars creates hired_flag - contributes_gains_costs fires once - Used by: COURIER, PROVISIONER, FENCE 5. TriggerAction(name) - Abilities that fire when conditions met - add_constraints checks trigger condition - transition_contrib handles cooldown/flags - Used by: ECONOMIST 6. RenovationModifierAction(name) - Base for abilities modifying renovation mechanics - Used by: FOREMAN ═══════════════════════════════════════════════════════════════════════════════ PLANNER INTEGRATION WITH OVERWORKACTION ═══════════════════════════════════════════════════════════════════════════════ Current OverworkAction (main-2.py lines 327-493): - add_global_constraints (line 389-394): Enforces "at most 1 city overworks per step" globally With Planner Governor: 1. Remove the global "at most 1 city per step" constraint from add_global_constraints 2. Add to add_constraints: - Can only overwork if governor[i,t] is the Planner - Constraint: ow[i,t] <= governor[i,t] (where governor tracks Planner specifically) - This allows multiple cities to overwork simultaneously if each has Planner 3. If multiple Planners can exist across cities, each city's Planner can independently enable overwork Implication: Without Planner governor, city cannot overwork at all. OverworkAction becomes conditional on Planner presence rather than globally limited. ═══════════════════════════════════════════════════════════════════════════════ IMPLEMENTATION NOTES ═══════════════════════════════════════════════════════════════════════════════ Resource Tracking: - Core tracked resources: Capital, Steel, Brass, Electrum (these are actual resource accumulators) - Trade Goods are convertible: Each unit of Trade Good can be independently converted to 1 unit of any core resource (Capital, Steel, Brass, or Electrum) at decision time - When agents produce trade goods, they are accumulated as trade_good[i,t], then converted per-unit to core resources during optimization Boolean Context Variables: - Governor position: governor[i,t] - tracks who governs each city - Renown tracking: renown[i,t] - accumulate from various sources - Bastion tracking: bastion[i,t] - military structures - Alliance tracking: alliance[faction_a, faction_b, t] - faction pairings Shared State: - Some abilities affect global/faction state - Use ctx for faction-level data sharing - Example: ctx["faction_renown"][faction_id, t] for faction-wide renown Cooldown Mechanics: - Counter variables for cooldowns: cooldown[i,t] = cooldown[i,t-1] - 1 - Constraint: Can trigger if cooldown[i,t] <= 0 - On trigger: Set cooldown[i,t+1] = COOLDOWN_LENGTH Global Constraints: - Some abilities have "at most 1 per step" limits - Use add_global_constraints to enforce across all cities - Example: sum(action_var[i,t] for i in range(N)) <= 1