- Joined
- Sep 21, 2024
While I've been busy coding national content for TNORA, I've also been brainstorming a way to partially emulate Vic2's POP and market system - ideally without destroying game performance. Still a work in progress but I thought I'd share what I have made so far.
Nearly finished the focus skeleton for the main Fuhrerdemocracy Germany tree. Including the Gang of Four intro tree, it's about 300 focuses large, which is larger then Heydrich's Europa focus tree. It's especially large considering most of the political content is handled by the Reichstag mechanic. Of course number of focuses doesn't really mean much. Goering has exactly 1000 focuses and he's broken. India has about 2300 focuses and much of it is barely coded or inaccessible without cheats.
Anyhow, much of the focus tree will be shared with Dengist Speer with some changes. Speer-Schwab will have their own political content revolving around the factions of the speerite-nsdap. The quickest way to describe it would be the affinity mechanic of Civ:BE, if anyone knows what that is.
Anyhow, at @Sooty Soot's suggestion, Schwab will always suceed dengist speer, but what kind of Schwab you get is dependent on which faction is dominant.
One more note for today; Cuba, Hati, and the Dominican Republic will, when they recieve their content, act as agents of change in the Americas. They'll be focused on punching above their weight, and turning proxy wars in their respective patrons favor.
Vic2 Pop System Ripoff
POPPs:
Pops calculated by groups
Each state has certain job proportion (POP proportion or POPP)
POPPs consume goods which is scaled by population size and proportion (more pops means more consumption)
Goods are broken into basic needs, consumer needs, and luxury needs
basic needs keep POPPs alive and satisfied, consumer needs keep them effective and can even let them promote
what POPP buys is decided by job type
POPPS buy goods with income and always prioritize basic needs
Income is proportional to POPP size as well as GDP , and scaled by job type, minus taxes
If POPP cannot afford a certain good then negatives will be applied.
If for example a POPP cannot afford food at all, which makes up 20% of basic needs, then a malus is applied though scaled to 20%
Likewise if POPP can only afford consumer good, you only get n% of the benefit where n is the percentage of how much the POPP can afford
Taxes are percentage based. If a tax is 50%, then 50% of income is sent to the government
POPPS buy goods nationally first, then from the sphere, then from the continent, then from the world.
Superpowers always get first pick, and spheres will not sell to each other unless there is a detente active.
If a POPP can afford luxary needs then generous buffs will be applied
POPPS are calculated by state but national population proportions are also shown to display total stats
POPP information shown in state menu
Economy types:
free market - doesn’t let you build civ factories directly. Instead factories are built automatically based on your GDP each month. You gdp/income bonuses and you get massive factory cap at the cost of base and growth. Research bonus?
Command - no malus to factory construction but no automatic factories. gdp/income maluses and massive factory line growth and base at the cost of a reduced cap
mixed market and corporatist - inbetween options. Mixed market is a moderate version of free market and corporatist is a moderate version of state controlled
warlord – gets a small boost to equipment scavenging and not much else. Warlord nations don’t use any of these mechanics. Warlords focus on, well, war, and cannot reap the benefits of modern economics.
Economy type info is displayed in the economy tab and each gets its own unique icon!
Militancy:
POPPs who cannot afford basic needs generate militancy
militancy kills stability, war support, pop growth, societal dev aspects, and causes pop demotion
in addition population will emigrate more or even straight out decrease
Goods:
Goods are produced by civ factories
Civ factories have to be allocated to production and when they are they behave like mils but produce goods
some goods just require foodstuffs or resources while others need other good to be produced
Goods can fluctuate in price, and buying foreign goods is more expensive than buying nationally. The more foreign, the more expensive.
If there is a surplus of goods at the end of a month, then the price will decrease. Likewise a shortage will cause an increase
Goods info shown in economy tab
Types of Goods:
**Tier 1 — Basic Goods (raw materials, produced by workers):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Grain | 1.0 | Farmers | None | None | Staple food, every nation produces some |
| Textiles | 1.2 | Farmers + Laborers | Laborers ≥ 5% | None | Raw fiber, cloth, leather |
| Coal & Fuel | 1.5 | Miners | Miners ≥ 3% | None | Heating, power, industrial fuel |
| Building Materials | 2.0 | Laborers + Miners | Miners ≥ 5% | None | Lumber, steel, cement, brick |
| Pharmaceuticals | 2.5 | Intellectuals + Laborers | Intellectuals ≥ 3%, Laborers ≥ 5% | None | Medicine, chemicals, medical equipment |
**Tier 2 — Consumer Goods (manufactured by capitalists and factories from basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Household Goods | 3.0 | Capitalists | Capitalists ≥ 1% | Textiles + Building Materials | Furniture, kitchenware, appliances |
| Schnaps (Spirits & Tobacco) | 2.5 | Capitalists | Capitalists ≥ 1% | Grain | Alcohol, cigarettes — morale goods |
| Volksempfänger (Media) | 3.5 | Capitalists | Capitalists ≥ 2%, Intellectuals ≥ 2% | Coal & Fuel | Radios, newspapers, records, propaganda |
| Tools & Equipment | 3.0 | Capitalists | Capitalists ≥ 1% | Coal & Fuel + Building Materials | Industrial tools, dual-use machinery, generators |
| Services | 2.0 | Bureaucrats + Capitalists | Bureaucrats ≥ 3% | None | Banking, insurance, legal, postal |
**Tier 3 — Luxury Goods (manufactured by capitalists and factories from consumer + basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Automobiles | 6.0 | Capitalists | Capitalists ≥ 3%, Factories ≥ 5 | Tools & Equipment + Coal & Fuel | Cars, trucks, motorcycles |
| Computers | 8.0 | Capitalists | Capitalists ≥ 3%, Intellectuals ≥ 5% | Volksempfänger + Tools & Equipment | Mainframes, calculators, precision instruments |
| Fine Clothing | 5.0 | Capitalists | Capitalists ≥ 2% | Textiles + Household Goods | High fashion, tailored suits, luxury textiles |
| Valuables | 10.0 | Capitalists | Capitalists ≥ 5% | None (pure capital) | Jewelry, art, gold, collectibles |
| Refined Petroleum | 7.0 | Capitalists | Capitalists ≥ 3%, Miners ≥ 5% | Coal & Fuel (×2) | Aviation fuel, synthetic rubber, petrochemicals |
Factories:
In a free market economy, the burden of buying, and selling goods for factories is solely on capitalists.
Money gained is deposited in their income. Money lost however will cut into their income.
In a command economy, the burden of buying and selling is on the state. Gains and losses directly cut into the players revenue. Buying without having the money to afford it causes debt.
Mixed market and corporatist economies share burdens, with mixed market leaning towards capitalists while corporatist leans towards state
Other modifiers also apply, so free market gets great gdp bonuses
Factories and capitalists buy goods after pops.
Military Production:
Military production will more or less remain unchanged. Military factories already count as an expense so using the goods/taxes system well will help you fund your military production
Maybe in the future equipment can become goods, or at least can be produced by capitalists but that’s not entirely necessary
Military industry generally involves heavy involvement of governments so it makes sense its entirely in the hands of the player
Also changing such a base mechanic may disrupt the ai too much and introduce more balance issues then can be handled
GDP:
GDP growth is scaled by total GDP as well as the amount of goods pops buy.
If POPPs can afford everything, including luxury goods, GDP will grow rapidly
Right now GDP only increases the economy score for superpower rank calculations, but I want to add a passive bonus from GDP where larger and larger GDP slightly boosts POPP income allowing POPPs to afford goods easier, which should help free market economies as they wont have to worry about feeding their POPPs as much
Jobs:
Miners: Produce resources! If their consumer needs are met they boost extraction in their state. Generally not found in states with no resources. They are proletariat class.
Farmers: Produce foodstuffs! Produce more when consumer needs are met. Generally not found in very urban states. They are proletariat class.
Laborers: Work in factories! Each factory needs a certain amount of workers other wise it will no work as well. Unemployed workers generate militancy or turn into miners/farmers if they can. Boosts production and construction when consumer needs are met. They are proletariat class.
Soldiers: Fight in wars! Serve as a buffer for other pops and generally consume less. Boosts military when consumer needs are met. Other pops die faster then soldiers so try to keep them alive. They are proletariat class.
Intellectuals: Do research! Research speed is based on them, and is boosted when their needs are met. They are burgher class.
Bureaucrats: Do politics! Helps keep militancy back down when consumer needs are met. Have a chance to make breakthroughs which give you small amount of prestige. They are burgher class.
Capitalists: Make money! Detailed above. If their income is high enough they’ll build free factories and other buildings. They are the bourgeoisie class
Slaves: Slaves provide a small bonus to state resources and state factory production but otherwise do little. Generally a negative to have slaves as they do not produce taxes, generate militancy very easily, and do nothing productive otherwise. They cannot exist if slavery is outlawed by a nation. Any state that has slaves that is either annexed by a non-slave nation, or the controlling nation bans slavery are automatically converted to farmers, or if the state is urban enough, into laborers. They are the lowest class.
War:
War kills pops, starting with soldiers and then moving onto lower classes. Keep wars quick to prevent mass death
Tech:
Goods production, tax rate, and income can be boosted by technologies. The techs will be under a new tech tab labeled economic technologies
Societal Development:
Industrial dev points boost laborer pops proportion and effectiveness
Agri dev increases foodstuff per farmer, freeing them up to be something else (mainly soldier/miner/laborer)
Research facilities and literacy boosts amount of intellectuals
Army professionalism boosts amount of soldiers and keeps them alive better
Trade:
As mentioned POPPS try to buy locally first, while factories will try to sell locally first
Goods sold overseas generate more income for factories!
Foodstuffs are not traded (unless used to produce some other good)
Extra mechanics
Migration:
Migration is controlled by an attraction modifier altered by a variety of effects including militancy and superpower rank.
Each month population will migrate internally and if attraction is negative some will migrate outwards
Migrating POPPs are split between nations nations with positive attraction. Total attraction score is calculated and then population is split up proportionally based on attraction of each nationally
Immigration is also effected by border control law
Warlord nations do not experience immigration or emigration
Culture:
Culture is decided on a state level and shows the majority culture.
If culture is not accepted then these POPPs generate more militancy than usual when basic needs are not met
Possible addition though likely too complicated with little benefit,
-The culture make up is tracked nationally (not by state as that’s computationally expensive). The greater the proportion of unaccepted cultures the more militancy generated
Immigration increases population, but also risks increasing emmigration from unaccepted cultures
Even having a small proportion of the population be unaccepted can be a large malus
For the sake of simplicity demographic shifts are only calculated once per year and all emigrants are assumed to come from the top 3 emigrating nations
-Or culture could be tracked by state like Vic2. This would make tracking demographic shifts (like after losing territory) easier but is more computationally expensive and would introduce more problems
-Best stick with majority culture by state as that’s much simpler, performance friendly, and reflects the fact that demographics do not naturally shift within even 2 decades. If there is a large shift it’s probably due to government machinations and we can simply represent that by changing the majority culture via effects which already is possible now and russia does it.
Implementation
on_actions and scripted_effects will be used heavily. on_monthly for calculations and on_startup to setup all the POPP numbers. Current economy variables would also be used though tax income and GDP calculations would have to be altered eventually to account for POPPs. Every month every_country will have POPP calcs via every_owned_state. Either first state in every_owned_state gets first pick of goods, but that’s unbalanced. I could do it so that total goods are divided by total owned states and each state gets equal goods allocation but that’s also not good since large states may have too little but small states have gluts that are wasted. Probably best way is too calculate total demand, and then subtract it from total goods and then any malus and/or benefit will be equally distributed among all POPPs. Remember, one POPPs are by state with one POPP for each job. I might also make it so that it’s total demand by job vs supply so that I can have higher class POPPs, stating with capitalists, get first pick on goods with slaves dead last. This is all assuming they can even afford said goods. After all goods are distributed, surplus is exported and sold to those who can afford it while unsold surplus remains to be sold the next round. Then any benefits from luxary usage are applied, or maluses from shortages. Taxes are automatically deducted from income before goods are bought and are added to national tax income.
POPPs:
Pops calculated by groups
Each state has certain job proportion (POP proportion or POPP)
POPPs consume goods which is scaled by population size and proportion (more pops means more consumption)
Goods are broken into basic needs, consumer needs, and luxury needs
basic needs keep POPPs alive and satisfied, consumer needs keep them effective and can even let them promote
what POPP buys is decided by job type
POPPS buy goods with income and always prioritize basic needs
Income is proportional to POPP size as well as GDP , and scaled by job type, minus taxes
If POPP cannot afford a certain good then negatives will be applied.
If for example a POPP cannot afford food at all, which makes up 20% of basic needs, then a malus is applied though scaled to 20%
Likewise if POPP can only afford consumer good, you only get n% of the benefit where n is the percentage of how much the POPP can afford
Taxes are percentage based. If a tax is 50%, then 50% of income is sent to the government
POPPS buy goods nationally first, then from the sphere, then from the continent, then from the world.
Superpowers always get first pick, and spheres will not sell to each other unless there is a detente active.
If a POPP can afford luxary needs then generous buffs will be applied
POPPS are calculated by state but national population proportions are also shown to display total stats
POPP information shown in state menu
Economy types:
free market - doesn’t let you build civ factories directly. Instead factories are built automatically based on your GDP each month. You gdp/income bonuses and you get massive factory cap at the cost of base and growth. Research bonus?
Command - no malus to factory construction but no automatic factories. gdp/income maluses and massive factory line growth and base at the cost of a reduced cap
mixed market and corporatist - inbetween options. Mixed market is a moderate version of free market and corporatist is a moderate version of state controlled
warlord – gets a small boost to equipment scavenging and not much else. Warlord nations don’t use any of these mechanics. Warlords focus on, well, war, and cannot reap the benefits of modern economics.
Economy type info is displayed in the economy tab and each gets its own unique icon!
Militancy:
POPPs who cannot afford basic needs generate militancy
militancy kills stability, war support, pop growth, societal dev aspects, and causes pop demotion
in addition population will emigrate more or even straight out decrease
Goods:
Goods are produced by civ factories
Civ factories have to be allocated to production and when they are they behave like mils but produce goods
some goods just require foodstuffs or resources while others need other good to be produced
Goods can fluctuate in price, and buying foreign goods is more expensive than buying nationally. The more foreign, the more expensive.
If there is a surplus of goods at the end of a month, then the price will decrease. Likewise a shortage will cause an increase
Goods info shown in economy tab
Types of Goods:
**Tier 1 — Basic Goods (raw materials, produced by workers):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Grain | 1.0 | Farmers | None | None | Staple food, every nation produces some |
| Textiles | 1.2 | Farmers + Laborers | Laborers ≥ 5% | None | Raw fiber, cloth, leather |
| Coal & Fuel | 1.5 | Miners | Miners ≥ 3% | None | Heating, power, industrial fuel |
| Building Materials | 2.0 | Laborers + Miners | Miners ≥ 5% | None | Lumber, steel, cement, brick |
| Pharmaceuticals | 2.5 | Intellectuals + Laborers | Intellectuals ≥ 3%, Laborers ≥ 5% | None | Medicine, chemicals, medical equipment |
**Tier 2 — Consumer Goods (manufactured by capitalists and factories from basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Household Goods | 3.0 | Capitalists | Capitalists ≥ 1% | Textiles + Building Materials | Furniture, kitchenware, appliances |
| Schnaps (Spirits & Tobacco) | 2.5 | Capitalists | Capitalists ≥ 1% | Grain | Alcohol, cigarettes — morale goods |
| Volksempfänger (Media) | 3.5 | Capitalists | Capitalists ≥ 2%, Intellectuals ≥ 2% | Coal & Fuel | Radios, newspapers, records, propaganda |
| Tools & Equipment | 3.0 | Capitalists | Capitalists ≥ 1% | Coal & Fuel + Building Materials | Industrial tools, dual-use machinery, generators |
| Services | 2.0 | Bureaucrats + Capitalists | Bureaucrats ≥ 3% | None | Banking, insurance, legal, postal |
**Tier 3 — Luxury Goods (manufactured by capitalists and factories from consumer + basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Automobiles | 6.0 | Capitalists | Capitalists ≥ 3%, Factories ≥ 5 | Tools & Equipment + Coal & Fuel | Cars, trucks, motorcycles |
| Computers | 8.0 | Capitalists | Capitalists ≥ 3%, Intellectuals ≥ 5% | Volksempfänger + Tools & Equipment | Mainframes, calculators, precision instruments |
| Fine Clothing | 5.0 | Capitalists | Capitalists ≥ 2% | Textiles + Household Goods | High fashion, tailored suits, luxury textiles |
| Valuables | 10.0 | Capitalists | Capitalists ≥ 5% | None (pure capital) | Jewelry, art, gold, collectibles |
| Refined Petroleum | 7.0 | Capitalists | Capitalists ≥ 3%, Miners ≥ 5% | Coal & Fuel (×2) | Aviation fuel, synthetic rubber, petrochemicals |
Factories:
In a free market economy, the burden of buying, and selling goods for factories is solely on capitalists.
Money gained is deposited in their income. Money lost however will cut into their income.
In a command economy, the burden of buying and selling is on the state. Gains and losses directly cut into the players revenue. Buying without having the money to afford it causes debt.
Mixed market and corporatist economies share burdens, with mixed market leaning towards capitalists while corporatist leans towards state
Other modifiers also apply, so free market gets great gdp bonuses
Factories and capitalists buy goods after pops.
Military Production:
Military production will more or less remain unchanged. Military factories already count as an expense so using the goods/taxes system well will help you fund your military production
Maybe in the future equipment can become goods, or at least can be produced by capitalists but that’s not entirely necessary
Military industry generally involves heavy involvement of governments so it makes sense its entirely in the hands of the player
Also changing such a base mechanic may disrupt the ai too much and introduce more balance issues then can be handled
GDP:
GDP growth is scaled by total GDP as well as the amount of goods pops buy.
If POPPs can afford everything, including luxury goods, GDP will grow rapidly
Right now GDP only increases the economy score for superpower rank calculations, but I want to add a passive bonus from GDP where larger and larger GDP slightly boosts POPP income allowing POPPs to afford goods easier, which should help free market economies as they wont have to worry about feeding their POPPs as much
Jobs:
Miners: Produce resources! If their consumer needs are met they boost extraction in their state. Generally not found in states with no resources. They are proletariat class.
Farmers: Produce foodstuffs! Produce more when consumer needs are met. Generally not found in very urban states. They are proletariat class.
Laborers: Work in factories! Each factory needs a certain amount of workers other wise it will no work as well. Unemployed workers generate militancy or turn into miners/farmers if they can. Boosts production and construction when consumer needs are met. They are proletariat class.
Soldiers: Fight in wars! Serve as a buffer for other pops and generally consume less. Boosts military when consumer needs are met. Other pops die faster then soldiers so try to keep them alive. They are proletariat class.
Intellectuals: Do research! Research speed is based on them, and is boosted when their needs are met. They are burgher class.
Bureaucrats: Do politics! Helps keep militancy back down when consumer needs are met. Have a chance to make breakthroughs which give you small amount of prestige. They are burgher class.
Capitalists: Make money! Detailed above. If their income is high enough they’ll build free factories and other buildings. They are the bourgeoisie class
Slaves: Slaves provide a small bonus to state resources and state factory production but otherwise do little. Generally a negative to have slaves as they do not produce taxes, generate militancy very easily, and do nothing productive otherwise. They cannot exist if slavery is outlawed by a nation. Any state that has slaves that is either annexed by a non-slave nation, or the controlling nation bans slavery are automatically converted to farmers, or if the state is urban enough, into laborers. They are the lowest class.
War:
War kills pops, starting with soldiers and then moving onto lower classes. Keep wars quick to prevent mass death
Tech:
Goods production, tax rate, and income can be boosted by technologies. The techs will be under a new tech tab labeled economic technologies
Societal Development:
Industrial dev points boost laborer pops proportion and effectiveness
Agri dev increases foodstuff per farmer, freeing them up to be something else (mainly soldier/miner/laborer)
Research facilities and literacy boosts amount of intellectuals
Army professionalism boosts amount of soldiers and keeps them alive better
Trade:
As mentioned POPPS try to buy locally first, while factories will try to sell locally first
Goods sold overseas generate more income for factories!
Foodstuffs are not traded (unless used to produce some other good)
Extra mechanics
Migration:
Migration is controlled by an attraction modifier altered by a variety of effects including militancy and superpower rank.
Each month population will migrate internally and if attraction is negative some will migrate outwards
Migrating POPPs are split between nations nations with positive attraction. Total attraction score is calculated and then population is split up proportionally based on attraction of each nationally
Immigration is also effected by border control law
Warlord nations do not experience immigration or emigration
Culture:
Culture is decided on a state level and shows the majority culture.
If culture is not accepted then these POPPs generate more militancy than usual when basic needs are not met
Possible addition though likely too complicated with little benefit,
-The culture make up is tracked nationally (not by state as that’s computationally expensive). The greater the proportion of unaccepted cultures the more militancy generated
Immigration increases population, but also risks increasing emmigration from unaccepted cultures
Even having a small proportion of the population be unaccepted can be a large malus
For the sake of simplicity demographic shifts are only calculated once per year and all emigrants are assumed to come from the top 3 emigrating nations
-Or culture could be tracked by state like Vic2. This would make tracking demographic shifts (like after losing territory) easier but is more computationally expensive and would introduce more problems
-Best stick with majority culture by state as that’s much simpler, performance friendly, and reflects the fact that demographics do not naturally shift within even 2 decades. If there is a large shift it’s probably due to government machinations and we can simply represent that by changing the majority culture via effects which already is possible now and russia does it.
Implementation
on_actions and scripted_effects will be used heavily. on_monthly for calculations and on_startup to setup all the POPP numbers. Current economy variables would also be used though tax income and GDP calculations would have to be altered eventually to account for POPPs. Every month every_country will have POPP calcs via every_owned_state. Either first state in every_owned_state gets first pick of goods, but that’s unbalanced. I could do it so that total goods are divided by total owned states and each state gets equal goods allocation but that’s also not good since large states may have too little but small states have gluts that are wasted. Probably best way is too calculate total demand, and then subtract it from total goods and then any malus and/or benefit will be equally distributed among all POPPs. Remember, one POPPs are by state with one POPP for each job. I might also make it so that it’s total demand by job vs supply so that I can have higher class POPPs, stating with capitalists, get first pick on goods with slaves dead last. This is all assuming they can even afford said goods. After all goods are distributed, surplus is exported and sold to those who can afford it while unsold surplus remains to be sold the next round. Then any benefits from luxary usage are applied, or maluses from shortages. Taxes are automatically deducted from income before goods are bought and are added to national tax income.
# POPP System (Vic2 Pop System) Implementation Plan
## Context
The user wants a Victoria 2-style population/economic simulation for TNORA. Each state has 8 "POPP" (POP Proportion) job types stored as ratios. These drive income, goods production/consumption, needs satisfaction, militancy, and feed back into the existing GDP/societal development systems. The system runs monthly on the existing `first_every_month_script` tick.
**Existing systems to integrate with:**
- Economy: `TNO_economy_scripted_effects.txt` (GDP, budget, tax, expenditures)
- Monthly tick: `TNO_pulse_effects.txt` → `first_every_month_script`
- Startup init: `TNO_on_startup_actions.txt`, `TNO_economy_definitions.txt`
- Societal dev: `TNO_societal_development.txt` (agriculture, industrial, academic levels)
- State variables: `state_population_k`, `state_value`, factory counts
---
## PHASE 1: Core POPPs — Variables, Initialization, Income/Tax
### 8 Job Types (state-level ratios, sum to 1.0)
| Type | Income Weight | Class |
|------|--------------|-------|
| Miners | 0.6 | Proletariat |
| Farmers | 0.5 | Proletariat |
| Laborers | 0.8 | Proletariat |
| Soldiers | 0.4 | Proletariat |
| Intellectuals | 1.2 | Burghers |
| Bureaucrats | 1.0 | Burghers |
| Capitalists | 2.5 | Bourgeoisie |
| Slaves | 0.0 | — |
### State Variables
- `popp_<type>_ratio` (0.0-1.0, 8 vars)
- `popp_<type>_k` = ratio × state_population_k (8 vars)
### Country Variables
- `total_<type>_k` — aggregated from all states
- `total_proletariat_k`, `total_burghers_k`, `total_bourgeoisie_k`
- `popp_tax_income`, `popp_total_income`
- `popp_income_weight_<type>` — set on startup, tunable
### Key Effects
- `popp_calculate_state_populations` — per-state: ratio × state_population_k
- `popp_calculate_national_totals` — sum all states
- `popp_calculate_income` — GDP share per POPP weighted by income weight × pop share, then apply tax rate
- `popp_initialize_country` — set default ratios per country based on societal dev level (agricultural nations get more farmers, industrial get more laborers, etc.)
### Initialization
Default ratio profiles based on `agriculture_development_level`:
- **Subsistence**: farmers=0.45, miners=0.10, laborers=0.10, soldiers=0.10, intellectuals=0.05, bureaucrats=0.05, capitalists=0.05, slaves=0.10
- **Early Industrial**: farmers=0.25, laborers=0.25, miners=0.12...
- **Industrial**: farmers=0.12, laborers=0.35, miners=0.10...
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **CREATE** |
| `common/scripted_triggers/TNO_POPP_scripted_triggers.txt` | **CREATE** — `popp_can_use_popp_system` |
| `common/on_actions/TNO_on_startup_actions.txt` | **MODIFY** — add init calls |
| `common/scripted_effects/TNO_pulse_effects.txt` | **MODIFY** — add `popp_monthly_update` |
---
## PHASE 2: Goods System — 15 Goods, Production, Pricing
### 15 Goods in 3 Tiers — Supply Chain
Goods flow through a **supply chain**: Basic goods are raw materials produced by workers. Consumer goods are manufactured by **capitalists** from basic goods. Luxury goods are produced by **capitalists** from consumer + basic goods. Factories (player-controlled) also produce consumer/luxury goods, but profit/loss falls on the player (the state).
**Tier 1 — Basic Goods (raw materials, produced by workers):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Grain | 1.0 | Farmers | None | None | Staple food, every nation produces some |
| Textiles | 1.2 | Farmers + Laborers | Laborers ≥ 5% | None | Raw fiber, cloth, leather |
| Coal & Fuel | 1.5 | Miners | Miners ≥ 3% | None | Heating, power, industrial fuel |
| Building Materials | 2.0 | Laborers + Miners | Miners ≥ 5% | None | Lumber, steel, cement, brick |
| Pharmaceuticals | 2.5 | Intellectuals + Laborers | Intellectuals ≥ 3%, Laborers ≥ 5% | None | Medicine, chemicals, medical equipment |
**Tier 2 — Consumer Goods (manufactured by capitalists from basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Household Goods | 3.0 | Capitalists | Capitalists ≥ 1% | Textiles + Building Materials | Furniture, kitchenware, appliances |
| Schnaps (Spirits & Tobacco) | 2.5 | Capitalists | Capitalists ≥ 1% | Grain | Alcohol, cigarettes — morale goods |
| Volksempfänger (Media) | 3.5 | Capitalists | Capitalists ≥ 2%, Intellectuals ≥ 2% | Coal & Fuel | Radios, newspapers, records, propaganda |
| Tools & Equipment | 3.0 | Capitalists | Capitalists ≥ 1% | Coal & Fuel + Building Materials | Industrial tools, dual-use machinery, generators |
| Services | 2.0 | Bureaucrats + Capitalists | Bureaucrats ≥ 3% | None | Banking, insurance, legal, postal |
**Tier 3 — Luxury Goods (manufactured by capitalists from consumer + basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Automobiles | 6.0 | Capitalists | Capitalists ≥ 3%, Factories ≥ 5 | Tools & Equipment + Coal & Fuel | Cars, trucks, motorcycles |
| Computers | 8.0 | Capitalists | Capitalists ≥ 3%, Intellectuals ≥ 5% | Volksempfänger + Tools & Equipment | Mainframes, calculators, precision instruments |
| Fine Clothing | 5.0 | Capitalists | Capitalists ≥ 2% | Textiles + Household Goods | High fashion, tailored suits, luxury textiles |
| Valuables | 10.0 | Capitalists | Capitalists ≥ 5% | None (pure capital) | Jewelry, art, gold, collectibles |
| Refined Petroleum | 7.0 | Capitalists | Capitalists ≥ 3%, Miners ≥ 5% | Coal & Fuel (×2) | Aviation fuel, synthetic rubber, petrochemicals |
### Supply Chain Mechanics
Consumer/luxury goods **require input goods to produce**. If inputs are unavailable (surplus ≤ 0), production is reduced proportionally:
```
input_availability = min(1.0, input_good_surplus / input_needed)
actual_production = base_production × input_availability
```
Input goods are **consumed** in production — they're subtracted from supply. This creates natural economic feedback: a coal shortage cascades into Tools & Equipment shortage, which cascades into Automobile shortage.
### Who Produces What
**Workers (Farmers, Miners, Laborers, Intellectuals)** produce **basic goods only**:
- Their output is determined by population, tech, societal dev, and law modifiers
- Basic goods are the raw material foundation — abundant workers = abundant raw materials
**Capitalists** produce **all consumer and luxury goods**:
- Production capacity scales with `popp_capitalists_k × capital_per_capitalist × tech_bonus`
- `capital_per_capitalist` grows with **retained profit** — more profit = more capital = more production capacity
- Capitalists allocate production dynamically based on **profit-seeking** (see below)
- They buy input goods at market price, so their costs fluctuate
**Factories (player-controlled)** also produce consumer/luxury goods:
- Each civilian factory can be assigned to produce a specific good via decision
- The **state** (player) pays input costs and receives sale revenue
- Profit or loss is on the player — risky but gives direct control
- Factory output = `factory_count × factory_productivity × tech_bonus`
### Capitalist Profit-Seeking (Country-Level Gimmick)
Capitalists chase the **most profitable goods** each month. Calculated cheaply at country level:
```
# For each consumer/luxury good, calculate profit margin:
margin_<good> = goods_<good>_price - (sum of input_good_prices × input_ratios) - production_cost_base
# Find the best margin among goods the country can produce
# Weight capitalist production toward highest-margin goods
```
**How it works:**
1. Each month, compute `margin` for all 10 consumer/luxury goods (10 subtractions — trivial)
2. Rank goods by margin. Top 3 get production weights: 50% / 30% / 20%
3. Capitalists shift production toward high-margin goods over ~3 months (smoothed, not instant)
4. If a good's price crashes (oversupply), capitalists naturally move away from it
**Free market bonus**: Under `tno_trade_laws_free_trade`, capitalists react faster (1-month shift instead of 3) and get +20% production efficiency. Under `closed_economy`, they react slower (6 months) and get -30% efficiency.
**Performance**: This is just 10 comparisons + 3 variable updates per country per month. Negligible.
### Goods Sale Profit
When goods are sold (domestically or via trade), the **seller earns profit**:
```
profit_per_good = (sale_price - input_costs - production_overhead) × quantity_sold
production_overhead = base_price × 0.3 (30% of base price covers labor/overhead)
```
**Capitalist profits:**
- Profit feeds back into `popp_capitalist_capital` — their retained capital for future production
- Higher capital = more production capacity next month (virtuous cycle)
- Under free market: capitalists keep 90% of profit. Under command economy: 40% (state takes rest)
- Capitalist capital decays slowly (-2%/month) representing maintenance/depreciation
**Factory (state) profits:**
- Factory profit/loss added to national `popp_factory_profit`, which feeds into GDP/budget
- Player bears the risk: if input prices spike, factories can lose money
- Player can reallocate factories to more profitable goods via decisions
**Export profits:**
- Surplus goods sold on trade pools earn `popp_trade_profit` added to GDP
- Import costs deducted from national budget
- Trade surplus/deficit = export profit - import costs
### Per-Good Country Variables
- `goods_<name>_supply` — total produced (capitalist + factory + imported)
- `goods_<name>_demand` — total needed by POPPs for consumption
- `goods_<name>_price` — current market price (adjusts by S/D ratio)
- `goods_<name>_surplus` — supply - demand (can be negative = shortage)
- `goods_<name>_profit` — profit earned from selling this good
- `goods_<name>_input_cost` — cost of inputs needed to produce 1 unit
### Production Formula (Basic Goods)
```
production = pop_k × productivity_per_k × tech_bonus × socdev_multiplier × law_modifier
```
### Production Formula (Consumer/Luxury Goods — Capitalists)
```
base_production = capitalists_k × capital_per_capitalist × tech_bonus × economy_type_modifier
actual_production = base_production × input_availability × profit_weight
```
Where `profit_weight` is the capitalist profit-seeking allocation (50%/30%/20% split).
### Pricing
```
price_ratio = demand / supply (clamped 0.5-2.0)
new_price = base_price × price_ratio
price smoothed: price = old_price × 0.7 + new_price × 0.3
```
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_goods_scripted_effects.txt` | **CREATE** |
---
## PHASE 3: Needs & Militancy
### Consumption
Each POPP type consumes goods based on its class:
- **Proletariat**: primarily basic needs, some consumer
- **Burghers**: basic + consumer needs
- **Bourgeoisie**: all three categories, heavy luxury
- **Slaves**: minimal basic only
### Affordability
```
affordability = (pop_income_after_tax) / (sum of good_price × quantity_needed)
actual_consumed = min(demanded, supply_available) × affordability
needs_met = actual_consumed / demanded (0.0-1.0)
```
### Militancy
Country-level `popp_militancy` (0.0-1.0), driven by:
- Unmet basic needs: `+0.05 × (1 - basic_needs_met)` per month
- Unmet consumer needs: `+0.02 × (1 - consumer_needs_met)`
- High tax rate: `+0.01` per level above moderate
- Natural decay: `-0.01` per month when needs are met
- Slaves always contribute `+0.01` per month
### Militancy Effects (via dynamic modifier)
- 0.0-0.2: No effect
- 0.2-0.5: Stability -5%, PP -0.1/day
- 0.5-0.8: Stability -15%, PP -0.3/day, war support -10%
- 0.8-1.0: Stability -30%, PP -0.5/day, war support -25%, consumer goods +5%
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/dynamic_modifiers/TNO_POPP_dynamic_modifiers.txt` | **CREATE** |
---
## PHASE 4: Economy Types
5 economy types as law ideas affecting POPP behavior:
| Type | Tax Mult | Trade Mult | Capitalist Profit Keep | Capitalist React Speed | Factory Control | Promotion Rate |
|------|----------|------------|----------------------|----------------------|----------------|----------------|
| Free Market | 0.7 | 1.3 | 90% | 1 month | Player choice | Fast |
| Mixed | 1.0 | 1.0 | 70% | 3 months | Semi-auto | Normal |
| Corporatist | 0.9 | 1.1 | 75% | 2 months | Guided | Normal |
| Command | 1.3 | 0.5 | 40% | 6 months | Auto-assigned | Slow |
| Warlord | 0.5 | 0.3 | 50% | 6 months | None | Very slow |
Free market strongly benefits capitalists: they keep most profits, react quickly to price signals, and get +20% production efficiency. Command economy suppresses capitalists but gives the state more revenue via taxation.
### Files
| File | Action |
|------|--------|
| `common/ideas/TNO_POPP_economy_type.txt` | **CREATE** |
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** — economy type effects |
---
## PHASE 5: Trade & Factories
### Trade Pools (abstracted, no O(n²))
4 tiers checked in order:
1. **National** — own production fills own demand first
2. **Sphere** — faction members share surplus
3. **Continental** — same continent, price markup ×1.2
4. **World** — global pool, markup ×1.5
Per good: `import_amount = min(deficit, pool_available) × trade_efficiency`
### Factory Goods Allocation (Player-Controlled)
Factories produce consumer/luxury goods via decisions — the player acts as factory owner:
- Each civ factory can be assigned to a specific good via decision
- `popp_factory_<good>_allocation` — number of factories assigned
- The state pays input goods costs and receives sale revenue — profit/loss is on the player
- Default: auto-distribute based on largest deficit goods
- Smart players can chase high-price goods just like capitalists do, but with direct control
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_goods_scripted_effects.txt` | **MODIFY** |
| `common/on_actions/TNO_POPP_on_actions.txt` | **CREATE** — trade pool processing |
| `common/decisions/TNO_POPP_economy_decisions.txt` | **CREATE** — factory allocation |
---
## PHASE 6: Jobs & Feedback
### Job-Specific Bonuses (via dynamic modifier)
- **High laborer ratio + needs met** → factory output bonus
- **High miner ratio + needs met** → resource output bonus
- **High intellectual ratio** → research speed bonus
- **High bureaucrat ratio** → PP generation bonus
- **High capitalist ratio** → GDP growth bonus
- **High soldier ratio** → army org/attack bonus
- **Unemployed laborers** → extra militancy
### Promotion/Demotion
Monthly per-state shifts between POPP types:
- **Promotion**: When consumer needs met > 0.7, slowly shift proletariat → burghers → bourgeoisie
- **Demotion**: When militancy > 0.5, reverse shift
- Rate: ~0.001-0.005 per month, modified by economy type
- Always run `popp_normalize_ratios` after shifts
### GDP Feedback
```
gdp_growth_bonus = (basic_needs_met × 0.3 + consumer_needs_met × 0.5 + luxury_needs_met × 0.2) - 0.5
```
Positive when needs well-met, negative when not. Applied as modifier to GDP growth.
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/dynamic_modifiers/TNO_POPP_dynamic_modifiers.txt` | **MODIFY** |
---
## PHASE 7: Migration & Culture
### Migration (Yearly Calculation)
Runs **once per year** (every 12th monthly tick) for performance. State-level attraction based on: factory density, GDP/capita, infrastructure, combat status.
- Negative attraction → people leave
- Positive attraction → people arrive proportionally
- Migrants shift farmers → laborers (urbanization pattern)
- `popp_border_control_factor` (from law) dampens migration
- Warlords have no migration
- Yearly batch means larger per-tick shifts (12× monthly rate) but far fewer iterations
### Culture
- `popp_state_culture_accepted` (0 or 1) per state
- Unaccepted cultures add +0.02/month to national militancy per state
- Simple system, no inter-culture dynamics
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/ideas/TNO_POPP_border_control.txt` | **CREATE** |
---
## PHASE 8: GUI & Display
### Economy Tab Additions
- **Economy type** display (Free Market / Mixed / Corporatist / Command / Warlord) with icon
- National POPP summary: population by class, per-job bars
- Needs satisfaction bars (Basic/Consumer/Luxury, 0-100%)
- Militancy gauge
- Goods overview: supply/demand/price per good, color-coded
- Trade balance summary
### Display Variables
Follow existing `_billion`/`_thousand` suffix pattern.
`popp_calculate_display_variables` converts internal values to GUI-friendly format.
### Files
| File | Action |
|------|--------|
| `interface/TNO_economyview.gui` | **MODIFY** |
| `interface/TNO_POPP_gfx.gfx` | **CREATE** |
| `gfx/interface/popp/` | **CREATE** — DDS sprites |
| `common/scripted_localisation/TNO_POPP_scripted_localisation.txt` | **CREATE** |
| `localisation/english/TNO_POPP_l_english.yml` | **CREATE** |
---
## PHASE 9: Tech & Integration
### Economic Technologies
5 categories: Production, Agricultural, Tax/Finance, Trade, Social
- Unlock via new tech folder `popp_economic_folder`
- Set bonus variables on research complete (e.g., `popp_factory_output_tech_bonus`)
### Societal Development Integration
POPP feeds back into existing socdev monthly changes:
- Industrial equip/expertise ← laborer ratio × consumer needs met
- Agriculture ← food surplus ratio
- Academic base ← intellectual ratio × consumer needs met
- Army professionalism ← soldier ratio × needs met
- Poverty ← inversely proportional to basic needs met
### War Casualties
- Combat states: soldiers lose ratio first, then civilians
- Always normalize after
### Files
| File | Action |
|------|--------|
| `common/technologies/TNO_POPP_technologies.txt` | **CREATE** |
| `common/technology_folders/TNO_POPP_technology_folders.txt` | **CREATE** |
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/scripted_effects/TNO_pulse_effects.txt` | **MODIFY** — integrate socdev |
---
## Monthly Execution Order (within `first_every_month_script`)
1. Existing economy calculations (GDP, budget, expenditures, deficit)
2. `popp_monthly_update`:
1. Per-state: `popp_calculate_state_populations`
2. Per-state: `popp_calculate_state_attraction` (Phase 7)
3. National: `popp_calculate_national_totals`
4. National: `popp_calculate_income`
5. National: `goods_monthly_update` (production, demand, prices)
6. National: `popp_trade_monthly` (Phase 5)
7. National: `popp_factory_goods_purchase` (Phase 5)
8. National: `popp_calculate_affordability`
9. National: `popp_apply_needs_effects`
10. National: `popp_calculate_militancy`
11. National: `popp_calculate_job_bonuses`
12. National: `popp_calculate_promotion_demotion` (per-state)
13. National: `popp_calculate_migration` (Phase 7, **yearly only** — every 12th tick)
14. National: `popp_apply_migration` (Phase 7, **yearly only**)
15. National: `popp_calculate_culture_militancy` (Phase 7)
16. National: `popp_gdp_feedback`
17. National: `popp_socdev_integration` (Phase 9)
18. National: `popp_war_casualties` (Phase 9)
19. National: `popp_apply_economy_type_effects` (Phase 4)
20. National: `popp_calculate_display_variables` (Phase
3. Existing `societal_development_monthly_check`
---
## Complete File Summary
### Files to CREATE
| File | Purpose |
|------|---------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | Core calculations: income, needs, jobs, migration, culture, socdev |
| `common/scripted_effects/TNO_POPP_goods_scripted_effects.txt` | Goods production, consumption, pricing, trade |
| `common/scripted_triggers/TNO_POPP_scripted_triggers.txt` | Trigger conditions |
| `common/dynamic_modifiers/TNO_POPP_dynamic_modifiers.txt` | Militancy/job bonus modifiers |
| `common/ideas/TNO_POPP_economy_type.txt` | Economy type laws |
| `common/ideas/TNO_POPP_border_control.txt` | Border control laws |
| `common/decisions/TNO_POPP_economy_decisions.txt` | Factory allocation decisions |
| `common/technologies/TNO_POPP_technologies.txt` | Economic tech tree |
| `common/technology_folders/TNO_POPP_technology_folders.txt` | Tech folder |
| `common/on_actions/TNO_POPP_on_actions.txt` | Trade pool processing |
| `common/scripted_localisation/TNO_POPP_scripted_localisation.txt` | Display text |
| `localisation/english/TNO_POPP_l_english.yml` | English strings |
| `interface/TNO_POPP_gfx.gfx` | GFX sprites |
### Files to MODIFY
| File | Change |
|------|--------|
| `common/on_actions/TNO_on_startup_actions.txt` | Add POPP init calls |
| `common/scripted_effects/TNO_pulse_effects.txt` | Add `popp_monthly_update` |
| `common/on_actions/TNO_economy_definitions.txt` | Add POPP variable init per country |
| `interface/TNO_economyview.gui` | Add POPP display sections |
## Performance Optimization Strategies
### Problem
The POPP system runs monthly for `every_country` that uses the economy system. Each country iterates `every_owned_state` multiple times. With 15 goods, 8 POPP types, and potentially 100+ countries × 50+ states, this can cause lag.
### Mitigation Strategies
1. **Minimize `every_owned_state` passes**: Combine multiple per-state calculations into a single pass. Instead of separate effects for population calc, attraction calc, and promotion/demotion, do them all in one `every_owned_state` loop.
- **Target**: Max 2 `every_owned_state` passes per country per month (down from 6+)
- Pass 1: Calculate state populations + attraction + culture
- Pass 2: Apply promotion/demotion + migration + normalize
2. **Batch goods calculations at country level**: All 15 goods' supply/demand/pricing is done with country-scope variables — no per-state goods iteration needed. Production is derived from national totals (`total_miners_k`, `total_laborers_k`) not per-state.
3. **Use `set_temp_variable` aggressively**: Temp variables are cheaper than persistent variables. Only persist what's needed between months (ratios, prices, needs_met). All intermediate calculations use temp vars.
4. **Skip trivial countries**: Add `popp_can_use_popp_system` trigger that excludes:
- Countries with < 5 states (too small to matter)
- Countries at war with no factories (warlords already excluded)
- Non-existent/annexed countries
5. **Stagger heavy calculations**: Migration runs **yearly** (every 12th tick). Trade runs every OTHER month:
```
# Trade: every other month
if = {
limit = { check_variable = { popp_trade_tick = 1 } }
popp_trade_monthly = yes
set_variable = { popp_trade_tick = 0 }
}
else = { add_to_variable = { popp_trade_tick = 1 } }
# Migration: yearly
add_to_variable = { popp_migration_tick = 1 }
if = {
limit = { check_variable = { popp_migration_tick > 11 } }
popp_calculate_migration = yes
popp_apply_migration = yes
set_variable = { popp_migration_tick = 0 }
}
```
6. **Cap trade pool iterations**: Trade pools (Phase 5) use a single global variable pool per good, not per-country bilateral trade. Each country just reads from and writes to the pool — O(n) not O(n²).
7. **Avoid `every_country` inside `every_country`**: Never nest country iterations. Trade pools are processed via `on_actions` with a single pass per good.
8. **Display variables only for player**: `popp_calculate_display_variables` only runs for `is_ai = no` countries, saving computation for all AI nations.
### Variable Count Budget
- Per state: 8 ratios + 8 _k values = 16 variables (acceptable)
- Per country: ~90 variables (8 totals + 15 goods × 4 + income/tax/needs/militancy)
- Global: 15 trade pool variables
- **Total**: ~106 per country + 16 per state — within HOI4's comfortable range
---
## National Law Interactions
The POPP system reads from existing national laws to modify its behavior. **No new law categories are created** (except economy type in Phase 4) — we hook into the existing law system.
### Economic Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_tax_rate** | Directly sets `popp_tax_rate_modifier`: no_tax=0.10, low=0.30, medium=0.50, high=0.60, exploitative=0.65 |
| **tno_income_taxation** | Shifts tax burden between classes: `elite_exemptions` → capitalists pay 50% less tax, `high_income_weighted` → capitalists pay 50% more |
| **tno_trade_laws** | Sets `popp_trade_efficiency`: free_trade=1.3, export_focus=1.0, limited=0.7, closed=0.3 |
| **tno_economic_focus** | Sets `popp_factory_output_modifier`: civilian_economy=+15% civ output, war_economy=+30% arms output but -40% civ |
| **tno_minimum_wage** | Sets floor on laborer/miner income: no_minimum=income×0.7, good_minimum=income×1.3. Also affects promotion rate |
| **tno_max_workhours** | Multiplies production output: unlimited=×1.15, 8_hour=×0.95, 6_hour=×0.85 |
| **tno_child_labor** | If legal: +10% farmer/laborer production, -10% intellectual promotion rate |
### Social Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_safety** | Modifies laborer/miner production: no_regulations=+15%, excellent=-15% |
| **tno_health_care** | Modifies needs satisfaction effectiveness: no_care=basic_needs_met×0.8, universal=basic_needs_met×1.1 |
| **tno_education** | Modifies intellectual promotion rate: elite_only=×0.3, free_education=×2.0. Also affects Wunderwaffe production |
| **tno_penal_system** | If penal_slavery: slaves contribute to production (mining/construction). If rehabilitation: slave ratio decreases faster |
| **tno_gender_rights** | traditional_roles: -12% effective workforce (women excluded). equality: +10% effective laborers/intellectuals |
### Political Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_trade_unions** | illegal: +5% laborer output, -15% laborer needs_met (exploitation). all_allowed: -5% output, +15% needs_met |
| **tno_immigration** | Sets `popp_border_control_factor` for migration: closed=0.1, open=0.8, encouraged=1.0 |
| **tno_slavery** | If allowed: slave ratio maintained/grows. If outlawed: slave ratio decays to 0 over ~24 months, converting to laborers |
| **tno_minorities** | oppression: unaccepted culture militancy ×1.5. affirmative_action: ×0.5 |
### Military Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_conscription** | Sets minimum soldier ratio: disarmed=0.01, volunteer=0.03, one_year=0.05, scraping_barrel=0.15. Excess conscription forcibly converts laborers/farmers → soldiers |
| **tno_women** | If combat_roles/total_equality: soldier pool draws from full population, higher soldier ratio ceiling |
| **tno_military_spending** | (Currently empty — POPP can fill this) Sets `popp_military_goods_demand`: how much Stahlhelm soldiers consume |
### Implementation
Each law interaction is implemented as a simple variable read in the monthly update:
```
# Example: Read tax rate law
if = {
limit = { has_idea = tno_tax_rate_no_taxation }
set_variable = { popp_tax_rate = 0.10 }
}
else_if = {
limit = { has_idea = tno_tax_rate_low_taxation }
set_variable = { popp_tax_rate = 0.30 }
}
# ... etc
```
This is done once per month per country — negligible performance cost. The variables are then used throughout the POPP calculations.
---
## Verification
- Run game with `tdebug`, verify POPP variables populate correctly on startup
- Observe monthly ticks: income, goods prices, needs satisfaction changing
- Verify militancy responds to unmet needs
- Verify promotion/demotion shifts ratios over 24+ months
- Verify normalization keeps ratios summing to ~1.0
- Performance test: 5+ year full-speed run, no lag
- Rich nations should naturally develop better socdev, less poverty
- War should cause soldier ratio loss and civilian casualties in combat states
## Context
The user wants a Victoria 2-style population/economic simulation for TNORA. Each state has 8 "POPP" (POP Proportion) job types stored as ratios. These drive income, goods production/consumption, needs satisfaction, militancy, and feed back into the existing GDP/societal development systems. The system runs monthly on the existing `first_every_month_script` tick.
**Existing systems to integrate with:**
- Economy: `TNO_economy_scripted_effects.txt` (GDP, budget, tax, expenditures)
- Monthly tick: `TNO_pulse_effects.txt` → `first_every_month_script`
- Startup init: `TNO_on_startup_actions.txt`, `TNO_economy_definitions.txt`
- Societal dev: `TNO_societal_development.txt` (agriculture, industrial, academic levels)
- State variables: `state_population_k`, `state_value`, factory counts
---
## PHASE 1: Core POPPs — Variables, Initialization, Income/Tax
### 8 Job Types (state-level ratios, sum to 1.0)
| Type | Income Weight | Class |
|------|--------------|-------|
| Miners | 0.6 | Proletariat |
| Farmers | 0.5 | Proletariat |
| Laborers | 0.8 | Proletariat |
| Soldiers | 0.4 | Proletariat |
| Intellectuals | 1.2 | Burghers |
| Bureaucrats | 1.0 | Burghers |
| Capitalists | 2.5 | Bourgeoisie |
| Slaves | 0.0 | — |
### State Variables
- `popp_<type>_ratio` (0.0-1.0, 8 vars)
- `popp_<type>_k` = ratio × state_population_k (8 vars)
### Country Variables
- `total_<type>_k` — aggregated from all states
- `total_proletariat_k`, `total_burghers_k`, `total_bourgeoisie_k`
- `popp_tax_income`, `popp_total_income`
- `popp_income_weight_<type>` — set on startup, tunable
### Key Effects
- `popp_calculate_state_populations` — per-state: ratio × state_population_k
- `popp_calculate_national_totals` — sum all states
- `popp_calculate_income` — GDP share per POPP weighted by income weight × pop share, then apply tax rate
- `popp_initialize_country` — set default ratios per country based on societal dev level (agricultural nations get more farmers, industrial get more laborers, etc.)
### Initialization
Default ratio profiles based on `agriculture_development_level`:
- **Subsistence**: farmers=0.45, miners=0.10, laborers=0.10, soldiers=0.10, intellectuals=0.05, bureaucrats=0.05, capitalists=0.05, slaves=0.10
- **Early Industrial**: farmers=0.25, laborers=0.25, miners=0.12...
- **Industrial**: farmers=0.12, laborers=0.35, miners=0.10...
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **CREATE** |
| `common/scripted_triggers/TNO_POPP_scripted_triggers.txt` | **CREATE** — `popp_can_use_popp_system` |
| `common/on_actions/TNO_on_startup_actions.txt` | **MODIFY** — add init calls |
| `common/scripted_effects/TNO_pulse_effects.txt` | **MODIFY** — add `popp_monthly_update` |
---
## PHASE 2: Goods System — 15 Goods, Production, Pricing
### 15 Goods in 3 Tiers — Supply Chain
Goods flow through a **supply chain**: Basic goods are raw materials produced by workers. Consumer goods are manufactured by **capitalists** from basic goods. Luxury goods are produced by **capitalists** from consumer + basic goods. Factories (player-controlled) also produce consumer/luxury goods, but profit/loss falls on the player (the state).
**Tier 1 — Basic Goods (raw materials, produced by workers):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Grain | 1.0 | Farmers | None | None | Staple food, every nation produces some |
| Textiles | 1.2 | Farmers + Laborers | Laborers ≥ 5% | None | Raw fiber, cloth, leather |
| Coal & Fuel | 1.5 | Miners | Miners ≥ 3% | None | Heating, power, industrial fuel |
| Building Materials | 2.0 | Laborers + Miners | Miners ≥ 5% | None | Lumber, steel, cement, brick |
| Pharmaceuticals | 2.5 | Intellectuals + Laborers | Intellectuals ≥ 3%, Laborers ≥ 5% | None | Medicine, chemicals, medical equipment |
**Tier 2 — Consumer Goods (manufactured by capitalists from basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Household Goods | 3.0 | Capitalists | Capitalists ≥ 1% | Textiles + Building Materials | Furniture, kitchenware, appliances |
| Schnaps (Spirits & Tobacco) | 2.5 | Capitalists | Capitalists ≥ 1% | Grain | Alcohol, cigarettes — morale goods |
| Volksempfänger (Media) | 3.5 | Capitalists | Capitalists ≥ 2%, Intellectuals ≥ 2% | Coal & Fuel | Radios, newspapers, records, propaganda |
| Tools & Equipment | 3.0 | Capitalists | Capitalists ≥ 1% | Coal & Fuel + Building Materials | Industrial tools, dual-use machinery, generators |
| Services | 2.0 | Bureaucrats + Capitalists | Bureaucrats ≥ 3% | None | Banking, insurance, legal, postal |
**Tier 3 — Luxury Goods (manufactured by capitalists from consumer + basic goods):**
| Good | Base Price | Producer | Requirements | Input Goods | Notes |
|------|-----------|----------|-------------|-------------|-------|
| Automobiles | 6.0 | Capitalists | Capitalists ≥ 3%, Factories ≥ 5 | Tools & Equipment + Coal & Fuel | Cars, trucks, motorcycles |
| Computers | 8.0 | Capitalists | Capitalists ≥ 3%, Intellectuals ≥ 5% | Volksempfänger + Tools & Equipment | Mainframes, calculators, precision instruments |
| Fine Clothing | 5.0 | Capitalists | Capitalists ≥ 2% | Textiles + Household Goods | High fashion, tailored suits, luxury textiles |
| Valuables | 10.0 | Capitalists | Capitalists ≥ 5% | None (pure capital) | Jewelry, art, gold, collectibles |
| Refined Petroleum | 7.0 | Capitalists | Capitalists ≥ 3%, Miners ≥ 5% | Coal & Fuel (×2) | Aviation fuel, synthetic rubber, petrochemicals |
### Supply Chain Mechanics
Consumer/luxury goods **require input goods to produce**. If inputs are unavailable (surplus ≤ 0), production is reduced proportionally:
```
input_availability = min(1.0, input_good_surplus / input_needed)
actual_production = base_production × input_availability
```
Input goods are **consumed** in production — they're subtracted from supply. This creates natural economic feedback: a coal shortage cascades into Tools & Equipment shortage, which cascades into Automobile shortage.
### Who Produces What
**Workers (Farmers, Miners, Laborers, Intellectuals)** produce **basic goods only**:
- Their output is determined by population, tech, societal dev, and law modifiers
- Basic goods are the raw material foundation — abundant workers = abundant raw materials
**Capitalists** produce **all consumer and luxury goods**:
- Production capacity scales with `popp_capitalists_k × capital_per_capitalist × tech_bonus`
- `capital_per_capitalist` grows with **retained profit** — more profit = more capital = more production capacity
- Capitalists allocate production dynamically based on **profit-seeking** (see below)
- They buy input goods at market price, so their costs fluctuate
**Factories (player-controlled)** also produce consumer/luxury goods:
- Each civilian factory can be assigned to produce a specific good via decision
- The **state** (player) pays input costs and receives sale revenue
- Profit or loss is on the player — risky but gives direct control
- Factory output = `factory_count × factory_productivity × tech_bonus`
### Capitalist Profit-Seeking (Country-Level Gimmick)
Capitalists chase the **most profitable goods** each month. Calculated cheaply at country level:
```
# For each consumer/luxury good, calculate profit margin:
margin_<good> = goods_<good>_price - (sum of input_good_prices × input_ratios) - production_cost_base
# Find the best margin among goods the country can produce
# Weight capitalist production toward highest-margin goods
```
**How it works:**
1. Each month, compute `margin` for all 10 consumer/luxury goods (10 subtractions — trivial)
2. Rank goods by margin. Top 3 get production weights: 50% / 30% / 20%
3. Capitalists shift production toward high-margin goods over ~3 months (smoothed, not instant)
4. If a good's price crashes (oversupply), capitalists naturally move away from it
**Free market bonus**: Under `tno_trade_laws_free_trade`, capitalists react faster (1-month shift instead of 3) and get +20% production efficiency. Under `closed_economy`, they react slower (6 months) and get -30% efficiency.
**Performance**: This is just 10 comparisons + 3 variable updates per country per month. Negligible.
### Goods Sale Profit
When goods are sold (domestically or via trade), the **seller earns profit**:
```
profit_per_good = (sale_price - input_costs - production_overhead) × quantity_sold
production_overhead = base_price × 0.3 (30% of base price covers labor/overhead)
```
**Capitalist profits:**
- Profit feeds back into `popp_capitalist_capital` — their retained capital for future production
- Higher capital = more production capacity next month (virtuous cycle)
- Under free market: capitalists keep 90% of profit. Under command economy: 40% (state takes rest)
- Capitalist capital decays slowly (-2%/month) representing maintenance/depreciation
**Factory (state) profits:**
- Factory profit/loss added to national `popp_factory_profit`, which feeds into GDP/budget
- Player bears the risk: if input prices spike, factories can lose money
- Player can reallocate factories to more profitable goods via decisions
**Export profits:**
- Surplus goods sold on trade pools earn `popp_trade_profit` added to GDP
- Import costs deducted from national budget
- Trade surplus/deficit = export profit - import costs
### Per-Good Country Variables
- `goods_<name>_supply` — total produced (capitalist + factory + imported)
- `goods_<name>_demand` — total needed by POPPs for consumption
- `goods_<name>_price` — current market price (adjusts by S/D ratio)
- `goods_<name>_surplus` — supply - demand (can be negative = shortage)
- `goods_<name>_profit` — profit earned from selling this good
- `goods_<name>_input_cost` — cost of inputs needed to produce 1 unit
### Production Formula (Basic Goods)
```
production = pop_k × productivity_per_k × tech_bonus × socdev_multiplier × law_modifier
```
### Production Formula (Consumer/Luxury Goods — Capitalists)
```
base_production = capitalists_k × capital_per_capitalist × tech_bonus × economy_type_modifier
actual_production = base_production × input_availability × profit_weight
```
Where `profit_weight` is the capitalist profit-seeking allocation (50%/30%/20% split).
### Pricing
```
price_ratio = demand / supply (clamped 0.5-2.0)
new_price = base_price × price_ratio
price smoothed: price = old_price × 0.7 + new_price × 0.3
```
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_goods_scripted_effects.txt` | **CREATE** |
---
## PHASE 3: Needs & Militancy
### Consumption
Each POPP type consumes goods based on its class:
- **Proletariat**: primarily basic needs, some consumer
- **Burghers**: basic + consumer needs
- **Bourgeoisie**: all three categories, heavy luxury
- **Slaves**: minimal basic only
### Affordability
```
affordability = (pop_income_after_tax) / (sum of good_price × quantity_needed)
actual_consumed = min(demanded, supply_available) × affordability
needs_met = actual_consumed / demanded (0.0-1.0)
```
### Militancy
Country-level `popp_militancy` (0.0-1.0), driven by:
- Unmet basic needs: `+0.05 × (1 - basic_needs_met)` per month
- Unmet consumer needs: `+0.02 × (1 - consumer_needs_met)`
- High tax rate: `+0.01` per level above moderate
- Natural decay: `-0.01` per month when needs are met
- Slaves always contribute `+0.01` per month
### Militancy Effects (via dynamic modifier)
- 0.0-0.2: No effect
- 0.2-0.5: Stability -5%, PP -0.1/day
- 0.5-0.8: Stability -15%, PP -0.3/day, war support -10%
- 0.8-1.0: Stability -30%, PP -0.5/day, war support -25%, consumer goods +5%
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/dynamic_modifiers/TNO_POPP_dynamic_modifiers.txt` | **CREATE** |
---
## PHASE 4: Economy Types
5 economy types as law ideas affecting POPP behavior:
| Type | Tax Mult | Trade Mult | Capitalist Profit Keep | Capitalist React Speed | Factory Control | Promotion Rate |
|------|----------|------------|----------------------|----------------------|----------------|----------------|
| Free Market | 0.7 | 1.3 | 90% | 1 month | Player choice | Fast |
| Mixed | 1.0 | 1.0 | 70% | 3 months | Semi-auto | Normal |
| Corporatist | 0.9 | 1.1 | 75% | 2 months | Guided | Normal |
| Command | 1.3 | 0.5 | 40% | 6 months | Auto-assigned | Slow |
| Warlord | 0.5 | 0.3 | 50% | 6 months | None | Very slow |
Free market strongly benefits capitalists: they keep most profits, react quickly to price signals, and get +20% production efficiency. Command economy suppresses capitalists but gives the state more revenue via taxation.
### Files
| File | Action |
|------|--------|
| `common/ideas/TNO_POPP_economy_type.txt` | **CREATE** |
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** — economy type effects |
---
## PHASE 5: Trade & Factories
### Trade Pools (abstracted, no O(n²))
4 tiers checked in order:
1. **National** — own production fills own demand first
2. **Sphere** — faction members share surplus
3. **Continental** — same continent, price markup ×1.2
4. **World** — global pool, markup ×1.5
Per good: `import_amount = min(deficit, pool_available) × trade_efficiency`
### Factory Goods Allocation (Player-Controlled)
Factories produce consumer/luxury goods via decisions — the player acts as factory owner:
- Each civ factory can be assigned to a specific good via decision
- `popp_factory_<good>_allocation` — number of factories assigned
- The state pays input goods costs and receives sale revenue — profit/loss is on the player
- Default: auto-distribute based on largest deficit goods
- Smart players can chase high-price goods just like capitalists do, but with direct control
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_goods_scripted_effects.txt` | **MODIFY** |
| `common/on_actions/TNO_POPP_on_actions.txt` | **CREATE** — trade pool processing |
| `common/decisions/TNO_POPP_economy_decisions.txt` | **CREATE** — factory allocation |
---
## PHASE 6: Jobs & Feedback
### Job-Specific Bonuses (via dynamic modifier)
- **High laborer ratio + needs met** → factory output bonus
- **High miner ratio + needs met** → resource output bonus
- **High intellectual ratio** → research speed bonus
- **High bureaucrat ratio** → PP generation bonus
- **High capitalist ratio** → GDP growth bonus
- **High soldier ratio** → army org/attack bonus
- **Unemployed laborers** → extra militancy
### Promotion/Demotion
Monthly per-state shifts between POPP types:
- **Promotion**: When consumer needs met > 0.7, slowly shift proletariat → burghers → bourgeoisie
- **Demotion**: When militancy > 0.5, reverse shift
- Rate: ~0.001-0.005 per month, modified by economy type
- Always run `popp_normalize_ratios` after shifts
### GDP Feedback
```
gdp_growth_bonus = (basic_needs_met × 0.3 + consumer_needs_met × 0.5 + luxury_needs_met × 0.2) - 0.5
```
Positive when needs well-met, negative when not. Applied as modifier to GDP growth.
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/dynamic_modifiers/TNO_POPP_dynamic_modifiers.txt` | **MODIFY** |
---
## PHASE 7: Migration & Culture
### Migration (Yearly Calculation)
Runs **once per year** (every 12th monthly tick) for performance. State-level attraction based on: factory density, GDP/capita, infrastructure, combat status.
- Negative attraction → people leave
- Positive attraction → people arrive proportionally
- Migrants shift farmers → laborers (urbanization pattern)
- `popp_border_control_factor` (from law) dampens migration
- Warlords have no migration
- Yearly batch means larger per-tick shifts (12× monthly rate) but far fewer iterations
### Culture
- `popp_state_culture_accepted` (0 or 1) per state
- Unaccepted cultures add +0.02/month to national militancy per state
- Simple system, no inter-culture dynamics
### Files
| File | Action |
|------|--------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/ideas/TNO_POPP_border_control.txt` | **CREATE** |
---
## PHASE 8: GUI & Display
### Economy Tab Additions
- **Economy type** display (Free Market / Mixed / Corporatist / Command / Warlord) with icon
- National POPP summary: population by class, per-job bars
- Needs satisfaction bars (Basic/Consumer/Luxury, 0-100%)
- Militancy gauge
- Goods overview: supply/demand/price per good, color-coded
- Trade balance summary
### Display Variables
Follow existing `_billion`/`_thousand` suffix pattern.
`popp_calculate_display_variables` converts internal values to GUI-friendly format.
### Files
| File | Action |
|------|--------|
| `interface/TNO_economyview.gui` | **MODIFY** |
| `interface/TNO_POPP_gfx.gfx` | **CREATE** |
| `gfx/interface/popp/` | **CREATE** — DDS sprites |
| `common/scripted_localisation/TNO_POPP_scripted_localisation.txt` | **CREATE** |
| `localisation/english/TNO_POPP_l_english.yml` | **CREATE** |
---
## PHASE 9: Tech & Integration
### Economic Technologies
5 categories: Production, Agricultural, Tax/Finance, Trade, Social
- Unlock via new tech folder `popp_economic_folder`
- Set bonus variables on research complete (e.g., `popp_factory_output_tech_bonus`)
### Societal Development Integration
POPP feeds back into existing socdev monthly changes:
- Industrial equip/expertise ← laborer ratio × consumer needs met
- Agriculture ← food surplus ratio
- Academic base ← intellectual ratio × consumer needs met
- Army professionalism ← soldier ratio × needs met
- Poverty ← inversely proportional to basic needs met
### War Casualties
- Combat states: soldiers lose ratio first, then civilians
- Always normalize after
### Files
| File | Action |
|------|--------|
| `common/technologies/TNO_POPP_technologies.txt` | **CREATE** |
| `common/technology_folders/TNO_POPP_technology_folders.txt` | **CREATE** |
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | **MODIFY** |
| `common/scripted_effects/TNO_pulse_effects.txt` | **MODIFY** — integrate socdev |
---
## Monthly Execution Order (within `first_every_month_script`)
1. Existing economy calculations (GDP, budget, expenditures, deficit)
2. `popp_monthly_update`:
1. Per-state: `popp_calculate_state_populations`
2. Per-state: `popp_calculate_state_attraction` (Phase 7)
3. National: `popp_calculate_national_totals`
4. National: `popp_calculate_income`
5. National: `goods_monthly_update` (production, demand, prices)
6. National: `popp_trade_monthly` (Phase 5)
7. National: `popp_factory_goods_purchase` (Phase 5)
8. National: `popp_calculate_affordability`
9. National: `popp_apply_needs_effects`
10. National: `popp_calculate_militancy`
11. National: `popp_calculate_job_bonuses`
12. National: `popp_calculate_promotion_demotion` (per-state)
13. National: `popp_calculate_migration` (Phase 7, **yearly only** — every 12th tick)
14. National: `popp_apply_migration` (Phase 7, **yearly only**)
15. National: `popp_calculate_culture_militancy` (Phase 7)
16. National: `popp_gdp_feedback`
17. National: `popp_socdev_integration` (Phase 9)
18. National: `popp_war_casualties` (Phase 9)
19. National: `popp_apply_economy_type_effects` (Phase 4)
20. National: `popp_calculate_display_variables` (Phase
3. Existing `societal_development_monthly_check`
---
## Complete File Summary
### Files to CREATE
| File | Purpose |
|------|---------|
| `common/scripted_effects/TNO_POPP_scripted_effects.txt` | Core calculations: income, needs, jobs, migration, culture, socdev |
| `common/scripted_effects/TNO_POPP_goods_scripted_effects.txt` | Goods production, consumption, pricing, trade |
| `common/scripted_triggers/TNO_POPP_scripted_triggers.txt` | Trigger conditions |
| `common/dynamic_modifiers/TNO_POPP_dynamic_modifiers.txt` | Militancy/job bonus modifiers |
| `common/ideas/TNO_POPP_economy_type.txt` | Economy type laws |
| `common/ideas/TNO_POPP_border_control.txt` | Border control laws |
| `common/decisions/TNO_POPP_economy_decisions.txt` | Factory allocation decisions |
| `common/technologies/TNO_POPP_technologies.txt` | Economic tech tree |
| `common/technology_folders/TNO_POPP_technology_folders.txt` | Tech folder |
| `common/on_actions/TNO_POPP_on_actions.txt` | Trade pool processing |
| `common/scripted_localisation/TNO_POPP_scripted_localisation.txt` | Display text |
| `localisation/english/TNO_POPP_l_english.yml` | English strings |
| `interface/TNO_POPP_gfx.gfx` | GFX sprites |
### Files to MODIFY
| File | Change |
|------|--------|
| `common/on_actions/TNO_on_startup_actions.txt` | Add POPP init calls |
| `common/scripted_effects/TNO_pulse_effects.txt` | Add `popp_monthly_update` |
| `common/on_actions/TNO_economy_definitions.txt` | Add POPP variable init per country |
| `interface/TNO_economyview.gui` | Add POPP display sections |
## Performance Optimization Strategies
### Problem
The POPP system runs monthly for `every_country` that uses the economy system. Each country iterates `every_owned_state` multiple times. With 15 goods, 8 POPP types, and potentially 100+ countries × 50+ states, this can cause lag.
### Mitigation Strategies
1. **Minimize `every_owned_state` passes**: Combine multiple per-state calculations into a single pass. Instead of separate effects for population calc, attraction calc, and promotion/demotion, do them all in one `every_owned_state` loop.
- **Target**: Max 2 `every_owned_state` passes per country per month (down from 6+)
- Pass 1: Calculate state populations + attraction + culture
- Pass 2: Apply promotion/demotion + migration + normalize
2. **Batch goods calculations at country level**: All 15 goods' supply/demand/pricing is done with country-scope variables — no per-state goods iteration needed. Production is derived from national totals (`total_miners_k`, `total_laborers_k`) not per-state.
3. **Use `set_temp_variable` aggressively**: Temp variables are cheaper than persistent variables. Only persist what's needed between months (ratios, prices, needs_met). All intermediate calculations use temp vars.
4. **Skip trivial countries**: Add `popp_can_use_popp_system` trigger that excludes:
- Countries with < 5 states (too small to matter)
- Countries at war with no factories (warlords already excluded)
- Non-existent/annexed countries
5. **Stagger heavy calculations**: Migration runs **yearly** (every 12th tick). Trade runs every OTHER month:
```
# Trade: every other month
if = {
limit = { check_variable = { popp_trade_tick = 1 } }
popp_trade_monthly = yes
set_variable = { popp_trade_tick = 0 }
}
else = { add_to_variable = { popp_trade_tick = 1 } }
# Migration: yearly
add_to_variable = { popp_migration_tick = 1 }
if = {
limit = { check_variable = { popp_migration_tick > 11 } }
popp_calculate_migration = yes
popp_apply_migration = yes
set_variable = { popp_migration_tick = 0 }
}
```
6. **Cap trade pool iterations**: Trade pools (Phase 5) use a single global variable pool per good, not per-country bilateral trade. Each country just reads from and writes to the pool — O(n) not O(n²).
7. **Avoid `every_country` inside `every_country`**: Never nest country iterations. Trade pools are processed via `on_actions` with a single pass per good.
8. **Display variables only for player**: `popp_calculate_display_variables` only runs for `is_ai = no` countries, saving computation for all AI nations.
### Variable Count Budget
- Per state: 8 ratios + 8 _k values = 16 variables (acceptable)
- Per country: ~90 variables (8 totals + 15 goods × 4 + income/tax/needs/militancy)
- Global: 15 trade pool variables
- **Total**: ~106 per country + 16 per state — within HOI4's comfortable range
---
## National Law Interactions
The POPP system reads from existing national laws to modify its behavior. **No new law categories are created** (except economy type in Phase 4) — we hook into the existing law system.
### Economic Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_tax_rate** | Directly sets `popp_tax_rate_modifier`: no_tax=0.10, low=0.30, medium=0.50, high=0.60, exploitative=0.65 |
| **tno_income_taxation** | Shifts tax burden between classes: `elite_exemptions` → capitalists pay 50% less tax, `high_income_weighted` → capitalists pay 50% more |
| **tno_trade_laws** | Sets `popp_trade_efficiency`: free_trade=1.3, export_focus=1.0, limited=0.7, closed=0.3 |
| **tno_economic_focus** | Sets `popp_factory_output_modifier`: civilian_economy=+15% civ output, war_economy=+30% arms output but -40% civ |
| **tno_minimum_wage** | Sets floor on laborer/miner income: no_minimum=income×0.7, good_minimum=income×1.3. Also affects promotion rate |
| **tno_max_workhours** | Multiplies production output: unlimited=×1.15, 8_hour=×0.95, 6_hour=×0.85 |
| **tno_child_labor** | If legal: +10% farmer/laborer production, -10% intellectual promotion rate |
### Social Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_safety** | Modifies laborer/miner production: no_regulations=+15%, excellent=-15% |
| **tno_health_care** | Modifies needs satisfaction effectiveness: no_care=basic_needs_met×0.8, universal=basic_needs_met×1.1 |
| **tno_education** | Modifies intellectual promotion rate: elite_only=×0.3, free_education=×2.0. Also affects Wunderwaffe production |
| **tno_penal_system** | If penal_slavery: slaves contribute to production (mining/construction). If rehabilitation: slave ratio decreases faster |
| **tno_gender_rights** | traditional_roles: -12% effective workforce (women excluded). equality: +10% effective laborers/intellectuals |
### Political Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_trade_unions** | illegal: +5% laborer output, -15% laborer needs_met (exploitation). all_allowed: -5% output, +15% needs_met |
| **tno_immigration** | Sets `popp_border_control_factor` for migration: closed=0.1, open=0.8, encouraged=1.0 |
| **tno_slavery** | If allowed: slave ratio maintained/grows. If outlawed: slave ratio decays to 0 over ~24 months, converting to laborers |
| **tno_minorities** | oppression: unaccepted culture militancy ×1.5. affirmative_action: ×0.5 |
### Military Laws → POPP Effects
| Law | POPP Effect |
|-----|------------|
| **tno_conscription** | Sets minimum soldier ratio: disarmed=0.01, volunteer=0.03, one_year=0.05, scraping_barrel=0.15. Excess conscription forcibly converts laborers/farmers → soldiers |
| **tno_women** | If combat_roles/total_equality: soldier pool draws from full population, higher soldier ratio ceiling |
| **tno_military_spending** | (Currently empty — POPP can fill this) Sets `popp_military_goods_demand`: how much Stahlhelm soldiers consume |
### Implementation
Each law interaction is implemented as a simple variable read in the monthly update:
```
# Example: Read tax rate law
if = {
limit = { has_idea = tno_tax_rate_no_taxation }
set_variable = { popp_tax_rate = 0.10 }
}
else_if = {
limit = { has_idea = tno_tax_rate_low_taxation }
set_variable = { popp_tax_rate = 0.30 }
}
# ... etc
```
This is done once per month per country — negligible performance cost. The variables are then used throughout the POPP calculations.
---
## Verification
- Run game with `tdebug`, verify POPP variables populate correctly on startup
- Observe monthly ticks: income, goods prices, needs satisfaction changing
- Verify militancy responds to unmet needs
- Verify promotion/demotion shifts ratios over 24+ months
- Verify normalization keeps ratios summing to ~1.0
- Performance test: 5+ year full-speed run, no lag
- Rich nations should naturally develop better socdev, less poverty
- War should cause soldier ratio loss and civilian casualties in combat states
Nearly finished the focus skeleton for the main Fuhrerdemocracy Germany tree. Including the Gang of Four intro tree, it's about 300 focuses large, which is larger then Heydrich's Europa focus tree. It's especially large considering most of the political content is handled by the Reichstag mechanic. Of course number of focuses doesn't really mean much. Goering has exactly 1000 focuses and he's broken. India has about 2300 focuses and much of it is barely coded or inaccessible without cheats.
Anyhow, much of the focus tree will be shared with Dengist Speer with some changes. Speer-Schwab will have their own political content revolving around the factions of the speerite-nsdap. The quickest way to describe it would be the affinity mechanic of Civ:BE, if anyone knows what that is.
Anyhow, at @Sooty Soot's suggestion, Schwab will always suceed dengist speer, but what kind of Schwab you get is dependent on which faction is dominant.
One more note for today; Cuba, Hati, and the Dominican Republic will, when they recieve their content, act as agents of change in the Americas. They'll be focused on punching above their weight, and turning proxy wars in their respective patrons favor.





















