aboutsummaryrefslogtreecommitdiff
path: root/docs/simulation/calculations.yaml
blob: b87e5f214384cf8f6ec60b519627ed85538470a1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
Diplomacy:
  Monthly diplomatic points gain: defines.country.BASE_MONTHLY_DIPLOPOINTS * (1 + sum of diplomatic_points + sum of diplomatic_points_modifier)
  Influence:
    Total base daily influence gain:  defines.country.BASE_GREATPOWER_DAILY_INFLUENCE * (1 + sum of influence) * (1 + sum of influence_modifier)
    Base daily influence gain per country:
      if total priority bars > 0: Total base influence gain * priority bars / total priority bars
      else: Total base influence gain / number of countries (excluding banned)
    Country influence gain modifier:
      note: 'our' and 'we' refers to the influencer. 'target' is the country being influenced.
      formula: 1 + score mod + relations mod + population mod + investment mod + puppet mod + neighbour mod + continent mod + discredit mod
      score mod: 1 - target score / our score
      relations mod: relations / defines.diplomacy.RELATION_INFLUENCE_MODIFIER
      population mod:
        if target population > LARGE_POPULATION_LIMIT:
          formula: floor((target population - LARGE_POPULATION_LIMIT) / LARGE_POPULATION_INFLUENCE_PENALTY_CHUNK) * LARGE_POPULATION_INFLUENCE_PENALTY
          target population: total of pop sizes
          LARGE_POPULATION_LIMIT: defines.pops.LARGE_POPULATION_LIMIT
          LARGE_POPULATION_INFLUENCE_PENALTY_CHUNK: defines.pops.LARGE_POPULATION_INFLUENCE_PENALTY_CHUNK
          LARGE_POPULATION_INFLUENCE_PENALTY: defines.diplomacy.LARGE_POPULATION_INFLUENCE_PENALTY
        else: 0
      investment mod:
        if value of total investments in target > 0: (1 - value of our investment / value of total investments in target) * - defines.diplomacy.INVESTMENT_INFLUENCE_DEFENSE
        else: 0
      puppet mod:
        if is our puppet: defines.diplomacy.PUPPET_BONUS_INFLUENCE_PERCENT
        else: 0
      neighbour mod:
        if target is direct neighbour: defines.diplomacy.NEIGHBOUR_BONUS_INFLUENCE_PERCENT
        else if target has a sphereling as neighbour: defines.diplomacy.SPHERE_NEIGHBOUR_BONUS_INFLUENCE_PERCENT
        else: 0
      continent mod:
        if target is on a different continent: defines.diplomacy.OTHER_CONTINENT_BONUS_INFLUENCE_PERCENT
        else: 0
      discredit mod:
        if we are discredited: defines.diplomacy.DISCREDIT_INFLUENCE_GAIN_FACTOR
        else: 0
    Daily influence gain per country: Base daily influence gain per country * Country influence gain modifier
  Colonisable life rating: defines.country.COLONIAL_LIFERATING + sum of colonial_life_rating
Economy:
  Budget:
    Loan interest per day:
      formula: (NBD + FBD * (1 + FIM)) * max(0.01, LBI+BIM)/30
      NBD: National bank debt = debt owed to your national bank.
      FBD: Foreign bank debt = debt owed to foreign national banks and private investors.
      1+FIM: Foreign interest modifier = sum of loan_interest modifiers from non-tech
      max(0.01: Hardcoded value. Reasoning unknown.
      LBI: defines.economy.LOAN_BASE_INTEREST
      BIM: Base interest modifier = sum of loan_interest modifiers from technology.
      /30: Hardcoded value to represent days in a month.
    Gold income daily:
      formula: MGQ * GOLD_TO_CASH_RATE
      MGQ: Money good quanity = total production of goods with money = yes
      GOLD_TO_CASH_RATE: defines.country.GOLD_TO_CASH_RATE
  Production:
    Human resource management:
      Vacancies: max employees - employees count
      Maximum employees hired per day:
        formula: max(employees available, relative maximum)
        employees available: unemployed employee pops in state
        relative maximum:
            if employees count = 0 & max employees >= 6667: 0.2775 * Vacancies
            else: ceil(0.15 * Vacancies) - 1
          0.15: Hardcoded value
          0.2775: 1 - (1 - 0.15)^2
          note: Rounding is unknown for the 0.2775 case. See https://discord.com/channels/1063392556160909312/1063416834650554398/1204520366643347476
      Minimum employees hired per day:
        formula: max(absolute minimum, relative minimum)
        absolute minimum: 50 (hardcoded value)
        relative minimum: floor(defines.economy.EMPLOYMENT_HIRE_LOWEST * employees count)
Military:
  Maximum units per soldier POP:
    if POP size < defines.military.POP_MIN_SIZE_FOR_REGIMENT: 0
    else:
      formula: ceil(POP size / (POP_SIZE_PER_REGIMENT * location factor))
      POP_SIZE_PER_REGIMENT: defines.military.POP_SIZE_PER_REGIMENT
      location factor:
        if is protectorate: defines.military.POP_MIN_SIZE_FOR_REGIMENT_PROTECTORATE_MULTIPLIER
        else if is colony: defines.military.POP_MIN_SIZE_FOR_REGIMENT_COLONY_MULTIPLIER
        else if location is core: 1
        else: defines.military.POP_MIN_SIZE_FOR_REGIMENT_NONCORE_MULTIPLIER
  Reinforcements per army:
    formula: 5 * round(supply factor * sum of unit reinforcements * REINFORCE_SPEED * local reinforce rate * (1 + reinforce_rate) * (1 + reinforce_speed) / 5)
    supply factor:
      if unit received all its supplies: 1
      else:
        formula: ((x^(n+1) - 1)/(x - 1) - 1) / n
        x: received supply
        n: number of units in the army
    unit reinforcements: 1000 * max_strength * unit reinforce rate
      max_strength: as defined in /units/<unit>.txt
      1000: (max_)strength is defined in thousands of soldiers. Reinforcements per army uses the number of soldiers.
      unit reinforce rate:
        if unit is mobilised: 0.5
        else if pop is too small for a single unit: 0.5
        else if pop supports too many units: Maximum units per soldier POP / number of supported units
        else: 1
    REINFORCE_SPEED: defines.military.REINFORCE_SPEED
    local reinforce rate:
      if location owner == army owner: 2
      else if army is exiled: 0
      else if location is uncolonised: 0
      else if location controller is hostile:
        if location neighbours a province controlled by an ally in this war: 0.5
        else if location is coastal & not blockaded: 0.25
        else: 0.1
      else: 1
    reinforce_rate: sum of reinforce_rate modifiers from tech
    reinforce_speed: sum of reinforce_speed modifiers on country
    5 * round(... /5): round to multiple of 5
  Regiment experience gain per day of combat:
    formula: d6 * defines.military.EXP_GAIN_DIV * (1 + sum of experience gain modifiers) + unexplained
    d6: random integer (inclusive) 1-6
    unexplained: see https://discord.com/channels/1062018115275325480/1062021872545447936/1278664121323356190 or https://media.discordapp.net/attachments/1062021872545447936/1278666211848228906/image.png?ex=66d1a235&is=66d050b5&hm=47bafd0f86451a25aebd7b728e96dda264bc0704a4e398ca59931390a902b968&=&format=webp&quality=lossless
Politics:
  Westernisation:
    Upper house reform support:
      formula: sum of (Ideology support factor * Ideology upper house share)
      Ideology support factor: common/ideologies.txt add_economic_reform or add_military_reform
    Economic reform cost modifier: defines.country.ECONOMIC_REFORM_UH_FACTOR * Upper house reform support + self_unciv_economic_modifier
    Military reform cost modifier: defines.country.MILITARY_REFORM_UH_FACTOR * Upper house reform support + self_unciv_military_modifier
POPs:
  Monthly pop growth:
    formula: BASE_POPGROWTH + (min(40, LR * (1 + LRM)) - MIN_LIFE_RATING_FOR_GROWTH) * LIFE_RATING_GROWTH_BONUS + population_growth + pop_growth + global_population_growth/10
    BASE_POPGROWTH: defines.pops.BASE_POPGROWTH
    min(40,: Hardcoded limit to life rating.Reasoning unknown.
    LR: Province life rating
    1+LRM: Life rating modifier = sum of life_rating modifiers
    MIN_LIFE_RATING_FOR_GROWTH: defines.pops.MIN_LIFE_RATING_FOR_GROWTH
    LIFE_RATING_GROWTH_BONUS: defines.pops.LIFE_RATING_GROWTH_BONUS
    population_growth: Sum of population_growth modifiers
    pop_growth: Sum of pop_growth modifiers
    global_population_growth/10: Sum of global_population_growth modifiers
  Attitudes:
    Consciousness from literacy: defines.pops.CON_LITERACY * Plurality * POP literacy * (1 + literacy_con_impact)
  Needs:
    Base needs scalar: (1 + Plurality) * (1 + 2 * Consciousness / defines.pops.PDEF_BASE_CON) * (1 + sum of goods_demand) * defines.pop.BASE_GOODS_DEMAND * POP size / 200000
    Life needs scalar: Base needs scalar * (1 + <strata>_life_needs modifier)
    Invention needs scalar: 1 + number of inventions * defines.pops.INVENTION_IMPACT_ON_DEMAND
    Everyday needs scalar: Base needs scalar * Invention needs scalar * (1 + <strata>_everyday_needs modifier)
    Luxury needs scalar: Base needs scalar * Invention needs scalar * (1 + <strata>_luxury_needs modifier)
  POP income:
    Base life needs costs: Base needs scalar * sum of (life need quantity * good price)
    Pensions: 2 * pension_level * administrative efficiency * social spending slider * Base life needs costs * (1 - effective tax) * POP size / 200000
    Unemployment subsidies: 2 * unemployment_benefit * administrative efficiency * social spending slider * Base life needs costs * (1 - effective tax) * POP size / 200000
    Wages:
      Minimum (worker) wage: 2 * minimum_wage * administrative efficiency * Base life needs costs * (1 - effective tax) * POP size / 200000
      RGO wages:
        Owners:
          if minimum worker wages > normal worker wage:
            formula: (RGO income - total worker income) * owner POP size / n_owners * (1 - effective tax) 
          else:
            formula: RGO income * min(0.5, 2 * n_owners / n_workers) * owner POP size / n_owners * (1 - effective tax) 
            n_owners: total size of owner POPs in state
            n_workers: number of employed workers in RGO
            min(0.5: Hardcoded maximum of half the RGO income.
            2*: Hardcoded value.
        Workers:
          if is_slave: 0
          else:
            if minimum wage > normal wage:
              formula: min(minimum wage, RGO income * employed workers in POP / total non-slave employed workers) * (1 - effective tax) 
            else:
              formula: RGO income * max(0.5, 1 - 2 * n_owners / n_workers) * employed workers in POP / total non-slave employed workers * (1 - effective tax) 
              n_owners: total size of owner POPs in state
              n_workers: number of employed workers in RGO
              max(0.5: Hardcoded minimum of half the RGO income.
              2*: Hardcoded value.