Supply chains¶
In the previous chapter, we ranked production units (buildings with certain production methods combinations) by their employment and construction requirements. But in the end, a country's economy cannot be solely based on oil rigs and automobile factories (unless you actually go for it). A world-dominating superpower's economy must be self-sufficient, which means some people must work in less productive production units to produce the upstream goods.
So this time, our analysis focuses on goods. We will find a set of production units, so that overall, the set produces at least a certain amount of a specific good (and maybe some inevitable byproducts) but consumes only labor and construction points, and no other goods at all. We call this set of production units a supply chain.
The supply chain can be visualized as a directed graph, where the nodes are goods and production units, and the edges are the flows of goods between them.
There are multiple implementations of a supply chain, one of which would be optimized for different objectives, such as minimizing employment or construction points. We are here today to find them, with the help of examples/supply_chain_compare.py, which solves for the minimum employment and minimum construction supply chains for every producible good, under different configurations.
The supply-chain guide explains the API and graph model. The data dictionary defines the report columns, units, formulas, and failure behavior.
View examples/supply_chain_compare.py
Methodology¶
To normalize the comparison, each supply chain has a weekly target base value of £100,000 of its corresponding terminal good, with target quantity calculated as 100_000 / base_price. This is fixed export demand with a zero goods-balance floor and no imports. Surplus and coproducts are possible, so equal target value does not imply equal GDP or make goods interchangeable.
The following table summarizes the three scenarios used in the comparison, with their objectives and additional restrictions. The cangshulun preset, originating from this video, bans certain oil-using production methods to represent the resource constraints. Monuments, ownership buildings and government buildings are also banned in all configurations, as they are not part of the production chain.
| Configuration | Objective | Technology and additional restrictions |
|---|---|---|
era_3_construction |
Minimum whole-system construction | Era 3 |
era_5_automation |
Minimum whole-system employment | Era 5 |
cangshulun |
Minimum whole-system employment | Era 5, CANGSHULUN_BANNED_PMS, and CANGSHULUN_BUILDING_LIMITS |
Note that the above constraints do not simulate every in-game law, qualification, or state-specific PM restriction. These are idealized model requirements, with no wage costs or profession availability constraints.
A failed solve produces a configuration-summary row with its requested target, status, and error text, and the script continues to the next configuration and good. Failed configurations have no detailed reports or plots. Unknown goods, duplicate good keys, and invalid base prices raise before any output is written.
The automobile supply chain¶
The employment and construction requirements for the automobile supply chain under different scenarios are summarized in the following table.
| Configuration | Status | Employment (workers) | Construction (points) |
|---|---|---|---|
| Era 3 construction | Infeasible | Unavailable | Unavailable |
| Era 5 automation | Success | 125,161 | 25,217.7 |
| Cangshulun | Success | 138,218 | 27,713.7 |
The £100,000 target corresponds to 1,000 automobiles per week. Both successful cases produce £100,000 of weekly value added, or £5.2 million annually, while using different amounts of labor and construction. In this example, whole-system and terminal-chain totals agree; that equality is not a general guarantee of the API.
Within analyses/supply_chains/era_5_automation/automobiles/, the reports explain
where those requirements come from:
goods.csvandgoods_balance.svgcompare supply, consumption, imports, and net production. The terminal production floor is a separate constraint, rather than a population or export buy order.processes.csvidentifies the selected building/PM configurations and their levels.flows.csvrecords process inputs and outputs.workforce.csvandworkforce.svgdescribe employment by profession. Minimizing total employment does not necessarily minimize skilled labor.constraints.csv,bottlenecks.csv, andconstraints.svgexpose LP diagnostics and useful binding inequalities. Marginals are local and objective-specific, and constraints can have different units.alternatives.csvlists all allowed producer configurations, including inactive ones. The diagrams can prune alternatives for readability.
Era 5 automation: automobile-chain goods balance, in units per week.
Era 5 automation: binding automobile-chain constraints, measured in workers saved per relaxed constraint unit.
The supply chain network graphs¶
supply_chain_recipe.mmd shows the allowed technology and
supply_chain_realised.mmd the realized chain. network.svg weights realized
edges by base-price value. Its layout distances have no economic units.
Allowed automobile technology in the era 5 automation preset:
flowchart LR
n0(("aeroplanes"))
n1(("automobiles ★"))
n2(("clippers"))
n3(("clothes"))
n4(("coal"))
n5(("copper"))
n6(("dye"))
n7(("electricity"))
n8(("engines"))
n9(("explosives"))
n10(("fabric"))
n11(("fertilizer"))
n12(("fish"))
n13(("fruit"))
n14(("furniture"))
n15(("glass"))
n16(("grain"))
n17(("hardwood"))
n18(("iron"))
n19(("lead"))
n20(("liquor"))
n21(("meat"))
n22(("oil"))
n23(("paper"))
n24(("porcelain"))
n25(("rubber"))
n26(("services"))
n27(("silk"))
n28(("steamers"))
n29(("steel"))
n30(("sugar"))
n31(("sulfur"))
n32(("tanks"))
n33(("tools"))
n34(("transportation"))
n35(("wood"))
n36["building_automotive_industry<br/>lvl=0"]
n37["building_automotive_industry<br/>lvl=0"]
n38["building_automotive_industry<br/>lvl=0"]
n39["building_automotive_industry<br/>lvl=0"]
n40["building_automotive_industry<br/>lvl=0"]
n41["building_automotive_industry<br/>lvl=0"]
n42["building_automotive_industry<br/>lvl=20 | active"]
n43["building_automotive_industry<br/>lvl=0"]
n44["building_chemical_plant<br/>lvl=0"]
n45["building_chemical_plant<br/>lvl=0"]
n46["building_chemical_plant<br/>lvl=0.03524 | active"]
n47["building_coal_mine<br/>lvl=0"]
n48["building_coal_mine<br/>lvl=0"]
n49["building_coal_mine<br/>lvl=0.4393 | active"]
n50["building_copper_mine<br/>lvl=0"]
n51["building_copper_mine<br/>lvl=0"]
n52["building_copper_mine<br/>lvl=0.3686 | active"]
n53["building_cossack_host<br/>lvl=0"]
n54["building_cossack_host<br/>lvl=0"]
n55["building_cotton_plantation<br/>lvl=0"]
n56["building_cotton_plantation<br/>lvl=0"]
n57["building_cotton_plantation<br/>lvl=0"]
n58["building_dye_plantation<br/>lvl=0"]
n59["building_explosives_factory<br/>lvl=0"]
n60["building_explosives_factory<br/>lvl=0.1379 | active"]
n61["building_explosives_factory<br/>lvl=0"]
n62["building_fishing_wharf<br/>lvl=0"]
n63["building_fishing_wharf<br/>lvl=0"]
n64["building_fishing_wharf<br/>lvl=0"]
n65["building_glassworks<br/>lvl=0"]
n66["building_glassworks<br/>lvl=0"]
n67["building_glassworks<br/>lvl=0"]
n68["building_glassworks<br/>lvl=0"]
n69["building_glassworks<br/>lvl=0"]
n70["building_glassworks<br/>lvl=0"]
n71["building_iron_mine<br/>lvl=0"]
n72["building_iron_mine<br/>lvl=0"]
n73["building_iron_mine<br/>lvl=1.186 | active"]
n74["building_lead_mine<br/>lvl=0"]
n75["building_lead_mine<br/>lvl=0"]
n76["building_lead_mine<br/>lvl=0"]
n77["building_livestock_ranch<br/>lvl=0"]
n78["building_livestock_ranch<br/>lvl=0"]
n79["building_livestock_ranch<br/>lvl=0"]
n80["building_logging_camp<br/>lvl=0"]
n81["building_logging_camp<br/>lvl=0"]
n82["building_logging_camp<br/>lvl=0"]
n83["building_logging_camp<br/>lvl=0.01241 | active"]
n84["building_logging_camp<br/>lvl=0"]
n85["building_logging_camp<br/>lvl=0"]
n86["building_motor_industry<br/>lvl=2.48 | active"]
n87["building_motor_industry<br/>lvl=0"]
n88["building_motor_industry<br/>lvl=0"]
n89["building_oil_rig<br/>lvl=0"]
n90["building_oil_rig<br/>lvl=0"]
n91["building_oil_rig<br/>lvl=5.084 | active"]
n92["building_paper_mill<br/>lvl=0"]
n93["building_paper_mill<br/>lvl=0.04136 | active"]
n94["building_paper_mill<br/>lvl=0"]
n95["building_power_plant<br/>lvl=0"]
n96["building_power_plant<br/>lvl=0"]
n97["building_power_plant<br/>lvl=1.908 | active"]
n98["building_railway<br/>lvl=1.551 | active"]
n99["building_railway<br/>lvl=0"]
n100["building_railway<br/>lvl=0"]
n101["building_railway<br/>lvl=0"]
n102["building_rice_farm<br/>lvl=0"]
n103["building_rice_farm<br/>lvl=0"]
n104["building_rice_farm<br/>lvl=0"]
n105["building_rice_farm<br/>lvl=0"]
n106["building_rice_farm<br/>lvl=0"]
n107["building_rice_farm<br/>lvl=0"]
n108["building_rubber_plantation<br/>lvl=0"]
n109["building_rubber_plantation<br/>lvl=3.254 | active"]
n110["building_rubber_plantation<br/>lvl=0"]
n111["building_rye_farm<br/>lvl=0"]
n112["building_rye_farm<br/>lvl=0"]
n113["building_rye_farm<br/>lvl=0"]
n114["building_rye_farm<br/>lvl=0"]
n115["building_rye_farm<br/>lvl=0"]
n116["building_rye_farm<br/>lvl=0"]
n117["building_shipyard<br/>lvl=0"]
n118["building_shipyard<br/>lvl=0"]
n119["building_shipyard<br/>lvl=0"]
n120["building_shipyard<br/>lvl=0"]
n121["building_steel_mill<br/>lvl=0"]
n122["building_steel_mill<br/>lvl=1.057 | active"]
n123["building_steel_mill<br/>lvl=0"]
n124["building_sulfur_mine<br/>lvl=0"]
n125["building_sulfur_mine<br/>lvl=0"]
n126["building_sulfur_mine<br/>lvl=0.07442 | active"]
n127["building_synthetics_plant<br/>lvl=0.00517 | active"]
n128["building_synthetics_plant<br/>lvl=0"]
n129["building_tooling_workshop<br/>lvl=1.151 | active"]
n130["building_tooling_workshop<br/>lvl=0"]
n131["building_tooling_workshop<br/>lvl=0"]
n132["building_urban_center<br/>lvl=0"]
n133["building_urban_center<br/>lvl=0"]
n134["building_urban_center<br/>lvl=0"]
n4 -.->|"1.474"| n52
n4 -->|"r=15"| n62
n4 -->|"r=15"| n63
n4 -->|"r=15"| n64
n4 -.->|"4.744"| n73
n4 -.->|"r=4"| n76
n4 -.->|"r=5"| n77
n4 -.->|"r=5"| n78
n4 -.->|"r=5"| n79
n4 -.->|"r=10"| n88
n4 -.->|"0.4136"| n93
n4 -.->|"r=5"| n94
n4 -.->|"r=15"| n95
n4 -.->|"r=5"| n96
n4 -.->|"r=2"| n102
n4 -.->|"r=2"| n105
n4 -.->|"r=1"| n112
n4 -.->|"r=1"| n115
n4 -->|"r=10"| n120
n4 -.->|"r=30"| n121
n4 -.->|"42.27"| n122
n4 -.->|"r=35"| n123
n4 -.->|"0.2977"| n126
n4 -.->|"r=15"| n131
n5 -->|"r=1"| n36
n5 -->|"r=1"| n38
n5 -->|"r=1"| n40
n5 -->|"r=1"| n41
n5 -->|"20"| n42
n5 -->|"r=1"| n62
n5 -->|"r=1"| n63
n5 -->|"r=1"| n64
n5 -.->|"2.48"| n86
n5 -.->|"r=4"| n95
n5 -.->|"r=2"| n96
n5 -.->|"9.542"| n97
n5 -.->|"1.151"| n129
n5 -.->|"r=1"| n132
n5 -.->|"r=1"| n133
n5 -.->|"r=1"| n134
n6 -.->|"r=10"| n65
n6 -.->|"r=10"| n66
n6 -.->|"r=10"| n67
n6 -.->|"r=5"| n68
n6 -.->|"r=10"| n92
n6 -.->|"0.4136"| n93
n6 -.->|"r=10"| n94
n7 -->|"r=5"| n36
n7 -->|"r=5"| n38
n7 -->|"r=5"| n40
n7 -->|"r=5"| n41
n7 -->|"100"| n42
n7 -.->|"2.758"| n60
n7 -->|"r=6"| n62
n7 -->|"r=4"| n63
n7 -->|"r=4"| n64
n7 -.->|"r=1"| n77
n7 -.->|"r=1"| n78
n7 -.->|"r=5"| n80
n7 -.->|"r=5"| n81
n7 -.->|"r=5"| n82
n7 -.->|"0.06204"| n83
n7 -.->|"r=5"| n84
n7 -.->|"r=5"| n85
n7 -.->|"12.4"| n86
n7 -.->|"r=10"| n101
n7 -->|"r=30"| n117
n7 -.->|"r=30"| n121
n7 -.->|"31.7"| n122
n7 -.->|"r=30"| n123
n7 -.->|"5.753"| n129
n7 -.->|"r=4"| n132
n7 -.->|"r=4"| n133
n7 -.->|"r=4"| n134
n8 -->|"r=10"| n36
n8 -->|"r=10"| n37
n8 -->|"r=10"| n38
n8 -->|"r=10"| n39
n8 -->|"r=10"| n40
n8 -->|"r=10"| n41
n8 -->|"200"| n42
n8 -->|"r=10"| n43
n8 -.->|"0.4393"| n49
n8 -.->|"0.3686"| n52
n8 -->|"r=5"| n55
n8 -->|"r=5"| n56
n8 -->|"r=5"| n57
n8 -.->|"r=5"| n58
n8 -.->|"r=2"| n65
n8 -.->|"r=2"| n67
n8 -.->|"r=2"| n68
n8 -.->|"r=2"| n69
n8 -.->|"1.186"| n73
n8 -.->|"r=1"| n76
n8 -.->|"r=1"| n80
n8 -.->|"r=1"| n81
n8 -.->|"r=1"| n82
n8 -.->|"0.01241"| n83
n8 -.->|"r=1"| n84
n8 -.->|"r=1"| n85
n8 -.->|"r=10"| n89
n8 -.->|"r=10"| n90
n8 -.->|"50.84"| n91
n8 -.->|"r=6"| n95
n8 -.->|"r=4"| n96
n8 -.->|"19.08"| n97
n8 -.->|"9.306"| n98
n8 -.->|"r=6"| n99
n8 -.->|"r=6"| n100
n8 -.->|"r=6"| n101
n8 -.->|"r=5"| n108
n8 -.->|"16.27"| n109
n8 -.->|"r=5"| n110
n8 -.->|"r=1"| n111
n8 -.->|"r=1"| n114
n8 -->|"r=10"| n117
n8 -->|"r=5"| n119
n8 -->|"r=10"| n120
n8 -.->|"0.07442"| n126
n9 -.->|"r=10"| n47
n9 -.->|"r=10"| n48
n9 -.->|"4.393"| n49
n9 -.->|"r=10"| n50
n9 -.->|"r=10"| n51
n9 -.->|"3.686"| n52
n9 -.->|"r=10"| n71
n9 -.->|"r=10"| n72
n9 -.->|"11.86"| n73
n9 -.->|"r=10"| n74
n9 -.->|"r=10"| n75
n9 -.->|"r=10"| n76
n9 -.->|"r=10"| n124
n9 -.->|"r=10"| n125
n9 -.->|"0.7442"| n126
n10 -->|"r=4"| n36
n10 -->|"r=4"| n37
n10 -->|"r=4"| n40
n10 -->|"r=4"| n41
n10 -->|"r=20"| n118
n10 -->|"r=20"| n119
n11 -.->|"r=30"| n59
n11 -.->|"6.894"| n60
n11 -.->|"r=40"| n61
n11 -.->|"r=30"| n102
n11 -.->|"r=30"| n103
n11 -.->|"r=30"| n104
n11 -.->|"r=30"| n105
n11 -.->|"r=30"| n106
n11 -.->|"r=30"| n107
n11 -.->|"r=15"| n111
n11 -.->|"r=15"| n112
n11 -.->|"r=15"| n113
n11 -.->|"r=15"| n114
n11 -.->|"r=15"| n115
n11 -.->|"r=15"| n116
n11 -.->|"0.1551"| n127
n11 -.->|"r=30"| n128
n15 -.->|"r=2"| n132
n15 -.->|"r=2"| n133
n15 -.->|"r=2"| n134
n16 -.->|"r=15"| n77
n16 -.->|"r=15"| n78
n16 -.->|"r=15"| n79
n17 -->|"r=4"| n36
n17 -->|"r=4"| n37
n17 -->|"r=4"| n40
n17 -->|"r=4"| n41
n17 -->|"r=20"| n119
n18 -.->|"r=10"| n44
n18 -.->|"r=30"| n45
n18 -.->|"1.057"| n46
n18 -.->|"r=1"| n77
n18 -.->|"r=1"| n78
n18 -.->|"r=1"| n79
n18 -.->|"r=100"| n121
n18 -.->|"105.7"| n122
n18 -.->|"r=100"| n123
n19 -.->|"r=35"| n65
n19 -.->|"r=35"| n66
n19 -.->|"r=30"| n68
n19 -.->|"r=30"| n69
n19 -.->|"r=30"| n70
n22 -->|"r=10"| n36
n22 -->|"r=5"| n37
n22 -->|"r=10"| n38
n22 -->|"r=5"| n39
n22 -->|"r=15"| n40
n22 -->|"r=15"| n41
n22 -->|"300"| n42
n22 -->|"r=10"| n43
n22 -.->|"0.7049"| n46
n22 -.->|"r=5"| n47
n22 -.->|"r=5"| n48
n22 -.->|"2.196"| n49
n22 -.->|"r=5"| n50
n22 -.->|"r=5"| n51
n22 -.->|"1.843"| n52
n22 -.->|"r=5"| n65
n22 -.->|"r=5"| n67
n22 -.->|"r=25"| n68
n22 -.->|"r=25"| n69
n22 -.->|"r=20"| n70
n22 -.->|"r=5"| n71
n22 -.->|"r=5"| n72
n22 -.->|"5.929"| n73
n22 -.->|"r=5"| n74
n22 -.->|"r=5"| n75
n22 -.->|"r=5"| n76
n22 -.->|"r=4"| n80
n22 -.->|"r=4"| n81
n22 -.->|"r=4"| n82
n22 -.->|"0.04964"| n83
n22 -.->|"r=4"| n84
n22 -.->|"r=4"| n85
n22 -.->|"136.4"| n86
n22 -.->|"r=50"| n87
n22 -.->|"r=50"| n88
n22 -.->|"38.17"| n97
n22 -.->|"12.41"| n98
n22 -.->|"r=8"| n99
n22 -.->|"r=8"| n100
n22 -.->|"r=2"| n111
n22 -.->|"r=2"| n114
n22 -.->|"r=5"| n124
n22 -.->|"r=5"| n125
n22 -.->|"0.3721"| n126
n22 -.->|"10.35"| n129
n23 -.->|"r=10"| n59
n23 -.->|"4.136"| n60
n23 -.->|"r=20"| n61
n25 -->|"r=5"| n36
n25 -->|"r=5"| n37
n25 -->|"r=5"| n38
n25 -->|"r=5"| n39
n25 -->|"r=10"| n40
n25 -->|"r=10"| n41
n25 -->|"200"| n42
n25 -->|"r=10"| n43
n25 -.->|"11.51"| n129
n25 -.->|"r=10"| n130
n25 -.->|"r=10"| n131
n28 -->|"r=5"| n62
n28 -->|"r=5"| n63
n28 -->|"r=5"| n64
n29 -->|"r=5"| n38
n29 -->|"r=5"| n39
n29 -->|"r=5"| n41
n29 -.->|"124"| n86
n29 -.->|"r=50"| n87
n29 -.->|"r=50"| n88
n29 -.->|"r=5"| n99
n29 -.->|"r=5"| n101
n29 -->|"r=30"| n117
n29 -->|"r=30"| n120
n29 -.->|"34.52"| n129
n29 -.->|"r=30"| n130
n29 -.->|"r=30"| n131
n29 -.->|"r=1"| n132
n29 -.->|"r=1"| n133
n29 -.->|"r=1"| n134
n31 -.->|"r=30"| n44
n31 -.->|"r=30"| n45
n31 -.->|"1.41"| n46
n31 -.->|"r=30"| n59
n31 -.->|"5.515"| n60
n31 -.->|"r=40"| n61
n31 -.->|"r=10"| n92
n31 -.->|"0.4136"| n93
n31 -.->|"r=10"| n94
n31 -.->|"0.1034"| n127
n31 -.->|"r=20"| n128
n33 -->|"r=4"| n36
n33 -->|"r=4"| n38
n33 -->|"r=4"| n40
n33 -->|"r=4"| n41
n33 -->|"80"| n42
n33 -.->|"r=15"| n47
n33 -.->|"r=15"| n48
n33 -.->|"6.589"| n49
n33 -.->|"r=15"| n50
n33 -.->|"r=15"| n51
n33 -.->|"5.529"| n52
n33 -.->|"r=2"| n65
n33 -.->|"r=2"| n67
n33 -.->|"r=2"| n68
n33 -.->|"r=2"| n69
n33 -.->|"r=15"| n71
n33 -.->|"r=15"| n72
n33 -.->|"17.79"| n73
n33 -.->|"r=15"| n74
n33 -.->|"r=15"| n75
n33 -.->|"r=15"| n76
n33 -.->|"r=5"| n77
n33 -.->|"r=5"| n78
n33 -.->|"r=5"| n79
n33 -.->|"r=10"| n80
n33 -.->|"r=10"| n81
n33 -.->|"r=10"| n82
n33 -.->|"0.1241"| n83
n33 -.->|"r=10"| n84
n33 -.->|"r=10"| n85
n33 -.->|"9.919"| n86
n33 -.->|"r=5"| n88
n33 -.->|"0.2068"| n93
n33 -.->|"r=5"| n94
n33 -.->|"r=4"| n102
n33 -.->|"r=4"| n103
n33 -.->|"r=4"| n105
n33 -.->|"r=4"| n106
n33 -.->|"r=2"| n112
n33 -.->|"r=2"| n113
n33 -.->|"r=2"| n115
n33 -.->|"r=2"| n116
n33 -.->|"5.284"| n122
n33 -.->|"r=5"| n123
n33 -.->|"r=15"| n124
n33 -.->|"r=15"| n125
n33 -.->|"1.116"| n126
n34 -.->|"r=5"| n47
n34 -.->|"2.196"| n49
n34 -.->|"r=5"| n50
n34 -.->|"1.843"| n52
n34 -->|"r=5"| n56
n34 -->|"r=7"| n62
n34 -->|"r=5"| n63
n34 -.->|"r=5"| n71
n34 -.->|"5.929"| n73
n34 -.->|"r=5"| n74
n34 -.->|"r=5"| n76
n34 -.->|"r=1"| n77
n34 -.->|"r=8"| n80
n34 -.->|"r=5"| n81
n34 -.->|"0.09927"| n83
n34 -.->|"r=5"| n84
n34 -.->|"r=5"| n89
n34 -.->|"50.84"| n91
n34 -.->|"16.27"| n109
n34 -.->|"r=5"| n124
n34 -.->|"0.3721"| n126
n35 -.->|"r=30"| n67
n35 -.->|"r=30"| n92
n35 -.->|"1.241"| n93
n35 -.->|"r=30"| n94
n35 -.->|"r=8"| n100
n35 -->|"r=40"| n118
n35 -->|"r=20"| n119
n35 -.->|"r=10"| n128
n36 -->|"r=10"| n0
n36 -->|"r=20"| n1
n37 -->|"r=10"| n0
n37 -->|"r=20"| n1
n38 -->|"r=10"| n1
n38 -->|"r=20"| n32
n39 -->|"r=10"| n1
n39 -->|"r=20"| n32
n40 -->|"r=10"| n0
n40 -->|"r=40"| n1
n41 -->|"r=10"| n0
n41 -->|"r=20"| n1
n41 -->|"r=20"| n32
n42 -->|"1000"| n1
n43 -->|"r=50"| n1
n44 -.->|"r=90"| n11
n45 -.->|"r=140"| n11
n46 -.->|"7.049"| n11
n47 -.->|"r=115"| n4
n48 -.->|"r=115"| n4
n49 -.->|"49.2"| n4
n50 -.->|"r=90"| n5
n51 -.->|"r=90"| n5
n52 -.->|"33.17"| n5
n53 -->|"r=0.25"| n3
n53 -->|"r=3"| n10
n53 -->|"r=0.25"| n14
n53 -->|"r=5"| n16
n53 -->|"r=0.25"| n20
n53 -->|"r=4"| n21
n53 -->|"r=0.25"| n26
n53 -->|"r=0.5"| n35
n54 -->|"r=0.25"| n3
n54 -->|"r=3"| n10
n54 -->|"r=0.25"| n14
n54 -->|"r=5"| n16
n54 -->|"r=0.25"| n20
n54 -->|"r=4"| n21
n54 -->|"r=0.25"| n26
n54 -->|"r=0.5"| n35
n55 -->|"r=100"| n10
n56 -->|"r=100"| n10
n57 -->|"r=90"| n10
n58 -.->|"r=60"| n6
n59 -.->|"r=80"| n9
n60 -.->|"20.68"| n9
n61 -.->|"r=110"| n9
n62 -->|"r=100"| n12
n63 -->|"r=100"| n12
n64 -->|"r=100"| n12
n65 -.->|"r=40"| n15
n65 -->|"r=30"| n24
n66 -.->|"r=40"| n15
n66 -->|"r=30"| n24
n67 -.->|"r=10"| n15
n67 -->|"r=30"| n24
n68 -.->|"r=90"| n15
n68 -->|"r=10"| n24
n69 -.->|"r=100"| n15
n70 -.->|"r=100"| n15
n71 -.->|"r=90"| n18
n72 -.->|"r=90"| n18
n73 -.->|"106.7"| n18
n74 -.->|"r=90"| n19
n75 -.->|"r=90"| n19
n76 -.->|"r=90"| n19
n77 -->|"r=25"| n10
n77 -.->|"r=5"| n11
n77 -->|"r=35"| n21
n78 -->|"r=25"| n10
n78 -.->|"r=5"| n11
n78 -->|"r=35"| n21
n79 -->|"r=25"| n10
n79 -.->|"r=5"| n11
n79 -->|"r=35"| n21
n80 -->|"r=20"| n17
n80 -.->|"r=60"| n35
n81 -->|"r=20"| n17
n81 -.->|"r=60"| n35
n82 -->|"r=20"| n17
n82 -.->|"r=60"| n35
n83 -.->|"1.241"| n35
n84 -.->|"r=100"| n35
n85 -.->|"r=100"| n35
n86 -.->|"297.6"| n8
n87 -.->|"r=120"| n8
n88 -.->|"r=120"| n8
n89 -.->|"r=100"| n22
n90 -.->|"r=100"| n22
n91 -.->|"508.4"| n22
n92 -.->|"r=100"| n23
n93 -.->|"4.136"| n23
n94 -.->|"r=100"| n23
n95 -.->|"r=50"| n7
n96 -.->|"r=25"| n7
n97 -.->|"152.7"| n7
n98 -.->|"77.55"| n34
n99 -.->|"r=65"| n34
n100 -.->|"r=60"| n34
n101 -.->|"r=60"| n34
n102 -->|"r=15"| n13
n102 -.->|"r=80"| n16
n102 -->|"r=2"| n30
n103 -->|"r=15"| n13
n103 -.->|"r=80"| n16
n103 -->|"r=2"| n30
n104 -->|"r=15"| n13
n104 -.->|"r=80"| n16
n104 -->|"r=2"| n30
n105 -.->|"r=100"| n16
n106 -.->|"r=100"| n16
n107 -.->|"r=100"| n16
n108 -.->|"r=65"| n25
n109 -.->|"211.5"| n25
n110 -.->|"r=50"| n25
n111 -.->|"r=50"| n16
n111 -->|"r=10"| n20
n112 -.->|"r=50"| n16
n112 -->|"r=10"| n20
n113 -.->|"r=50"| n16
n113 -->|"r=10"| n20
n114 -.->|"r=55"| n16
n114 -->|"r=4"| n30
n115 -.->|"r=55"| n16
n115 -->|"r=4"| n30
n116 -.->|"r=55"| n16
n116 -->|"r=4"| n30
n117 -->|"r=80"| n28
n118 -->|"r=40"| n2
n119 -->|"r=70"| n2
n120 -->|"r=65"| n28
n121 -.->|"r=150"| n29
n122 -.->|"158.5"| n29
n123 -.->|"r=150"| n29
n124 -.->|"r=100"| n31
n125 -.->|"r=100"| n31
n126 -.->|"7.442"| n31
n127 -.->|"0.4136"| n6
n128 -.->|"r=70"| n6
n128 -->|"r=30"| n27
n129 -.->|"126.6"| n33
n130 -.->|"r=110"| n33
n131 -.->|"r=110"| n33
n132 -->|"r=40"| n26
n132 -.->|"r=2"| n34
n133 -->|"r=40"| n26
n133 -.->|"r=2"| n34
n134 -->|"r=40"| n26
n134 -.->|"r=2"| n34
class n4,n5,n6,n7,n8,n9,n11,n15,n16,n18,n19,n22,n23,n25,n29,n31,n33,n34,n35,n44,n45,n46,n47,n48,n49,n50,n51,n52,n58,n59,n60,n61,n65,n66,n67,n68,n69,n70,n71,n72,n73,n74,n75,n76,n77,n78,n79,n80,n81,n82,n83,n84,n85,n86,n87,n88,n89,n90,n91,n92,n93,n94,n95,n96,n97,n98,n99,n100,n101,n102,n103,n104,n105,n106,n107,n108,n109,n110,n111,n112,n113,n114,n115,n116,n121,n122,n123,n124,n125,n126,n127,n128,n129,n130,n131,n132,n133,n134 cyclic
class n47,n48,n49,n50,n51,n52,n62,n63,n64,n71,n72,n73,n74,n75,n76,n80,n81,n82,n83,n84,n85,n89,n90,n91,n108,n109,n110,n124,n125,n126 resource
class n42,n46,n49,n52,n60,n73,n83,n86,n91,n93,n97,n98,n109,n122,n126,n127,n129 active
classDef cyclic stroke:#d97706,stroke-width:2px
classDef resource fill:#dcfce7,stroke:#15803d
classDef active fill:#dbeafe,stroke:#1d4ed8
Realized automobile chain:
flowchart LR
n0(("automobiles ★"))
n1(("coal"))
n2(("copper"))
n3(("dye"))
n4(("electricity"))
n5(("engines"))
n6(("explosives"))
n7(("fertilizer"))
n8(("iron"))
n9(("oil"))
n10(("paper"))
n11(("rubber"))
n12(("steel"))
n13(("sulfur"))
n14(("tools"))
n15(("transportation"))
n16(("wood"))
n17["building_automotive_industry<br/>lvl=20 | active"]
n18["building_chemical_plant<br/>lvl=0.03524 | active"]
n19["building_coal_mine<br/>lvl=0.4393 | active"]
n20["building_copper_mine<br/>lvl=0.3686 | active"]
n21["building_explosives_factory<br/>lvl=0.1379 | active"]
n22["building_iron_mine<br/>lvl=1.186 | active"]
n23["building_logging_camp<br/>lvl=0.01241 | active"]
n24["building_motor_industry<br/>lvl=2.48 | active"]
n25["building_oil_rig<br/>lvl=5.084 | active"]
n26["building_paper_mill<br/>lvl=0.04136 | active"]
n27["building_power_plant<br/>lvl=1.908 | active"]
n28["building_railway<br/>lvl=1.551 | active"]
n29["building_rubber_plantation<br/>lvl=3.254 | active"]
n30["building_steel_mill<br/>lvl=1.057 | active"]
n31["building_sulfur_mine<br/>lvl=0.07442 | active"]
n32["building_synthetics_plant<br/>lvl=0.00517 | active"]
n33["building_tooling_workshop<br/>lvl=1.151 | active"]
n1 -.->|"1.474"| n20
n1 -.->|"4.744"| n22
n1 -.->|"0.4136"| n26
n1 -.->|"42.27"| n30
n1 -.->|"0.2977"| n31
n2 -->|"20"| n17
n2 -.->|"2.48"| n24
n2 -.->|"9.542"| n27
n2 -.->|"1.151"| n33
n3 -.->|"0.4136"| n26
n4 -->|"100"| n17
n4 -.->|"2.758"| n21
n4 -.->|"0.06204"| n23
n4 -.->|"12.4"| n24
n4 -.->|"31.7"| n30
n4 -.->|"5.753"| n33
n5 -->|"200"| n17
n5 -.->|"0.4393"| n19
n5 -.->|"0.3686"| n20
n5 -.->|"1.186"| n22
n5 -.->|"0.01241"| n23
n5 -.->|"50.84"| n25
n5 -.->|"19.08"| n27
n5 -.->|"9.306"| n28
n5 -.->|"16.27"| n29
n5 -.->|"0.07442"| n31
n6 -.->|"4.393"| n19
n6 -.->|"3.686"| n20
n6 -.->|"11.86"| n22
n6 -.->|"0.7442"| n31
n7 -.->|"6.894"| n21
n7 -.->|"0.1551"| n32
n8 -.->|"1.057"| n18
n8 -.->|"105.7"| n30
n9 -->|"300"| n17
n9 -.->|"0.7049"| n18
n9 -.->|"2.196"| n19
n9 -.->|"1.843"| n20
n9 -.->|"5.929"| n22
n9 -.->|"0.04964"| n23
n9 -.->|"136.4"| n24
n9 -.->|"38.17"| n27
n9 -.->|"12.41"| n28
n9 -.->|"0.3721"| n31
n9 -.->|"10.35"| n33
n10 -.->|"4.136"| n21
n11 -->|"200"| n17
n11 -.->|"11.51"| n33
n12 -.->|"124"| n24
n12 -.->|"34.52"| n33
n13 -.->|"1.41"| n18
n13 -.->|"5.515"| n21
n13 -.->|"0.4136"| n26
n13 -.->|"0.1034"| n32
n14 -->|"80"| n17
n14 -.->|"6.589"| n19
n14 -.->|"5.529"| n20
n14 -.->|"17.79"| n22
n14 -.->|"0.1241"| n23
n14 -.->|"9.919"| n24
n14 -.->|"0.2068"| n26
n14 -.->|"5.284"| n30
n14 -.->|"1.116"| n31
n15 -.->|"2.196"| n19
n15 -.->|"1.843"| n20
n15 -.->|"5.929"| n22
n15 -.->|"0.09927"| n23
n15 -.->|"50.84"| n25
n15 -.->|"16.27"| n29
n15 -.->|"0.3721"| n31
n16 -.->|"1.241"| n26
n17 -->|"1000"| n0
n18 -.->|"7.049"| n7
n19 -.->|"49.2"| n1
n20 -.->|"33.17"| n2
n21 -.->|"20.68"| n6
n22 -.->|"106.7"| n8
n23 -.->|"1.241"| n16
n24 -.->|"297.6"| n5
n25 -.->|"508.4"| n9
n26 -.->|"4.136"| n10
n27 -.->|"152.7"| n4
n28 -.->|"77.55"| n15
n29 -.->|"211.5"| n11
n30 -.->|"158.5"| n12
n31 -.->|"7.442"| n13
n32 -.->|"0.4136"| n3
n33 -.->|"126.6"| n14
class n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33 cyclic
class n19,n20,n22,n23,n25,n29,n31 resource
class n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33 active
classDef cyclic stroke:#d97706,stroke-width:2px
classDef resource fill:#dcfce7,stroke:#15803d
classDef active fill:#dbeafe,stroke:#1d4ed8
Era 5 automation: realized automobile network, with edge widths weighted by weekly base-price value (£).
Cycles represent real feedback. For example, oil extraction can consume engines while motor industries consume oil. A traversal cutoff does not turn either good into a free resource. Check the quantitative flows rather than inferring requirements from graph depth.
The regenerated era 5 automobile network contains 16 processes, 16 goods, and 77 edges, with one cyclic component. The allowed graph includes many more alternatives, so a pruned diagram cannot establish their total count.
Compare contributions¶
contributions_gdp.svg, contributions_employment.svg, and
contributions_construction_cost.svg show leading whole-process contributions
to the terminal chain. The same process can matter very differently for labor,
construction, and value added.
Era 5 automation: leading automobile-chain contributions to weekly value added (£).
Era 5 automation: leading automobile-chain employment contributions, in workers.
Era 5 automation: leading automobile-chain construction contributions, in construction points.
For the era 5 automobile chain, automotive assembly employs 70,000 workers and requires 16,000 construction points. The upstream chain therefore accounts for another 55,161 workers. Rubber plantations employ about 16,392 workers but require only 655.7 construction points; oil rigs employ 15,590 workers and require 2,078.7 points. Their relative importance changes between the employment and construction charts. Machinists and engineers together account for 73.9% of chain employment, which illustrates why a small total workforce can still depend heavily on skilled professions.
Era 5 automation: automobile-chain workforce by profession, in workers.
Chain totals include whole selected processes, including their coproducts; they do not allocate a factory's workers or construction uniquely to one good. Whole-system totals can also include activity outside the graph-defined chain. Weekly value added is output base value minus intermediate input base cost; annual GDP is 52 times weekly GDP.
Goods & scenario sweep¶
The combined summary is
artifacts/analyses/supply_chains/comparison/summary.csv.
It contains one row per good/configuration pair selected in the current run,
in requested good order and then configuration order. It retains failures.
Each configuration has one summary.csv combining its selected goods,
for example analyses/supply_chains/era_5_automation/summary.csv.
It records each good's target, objective, solver status, whole-system totals,
chain totals, and configuration labels. No summary files are written inside
the individual good directories.
Use a single configuration when ranking goods under common assumptions.
| good | configuration | status | chain_gdp_per_capita_annual | chain_wage_normalized_employment | chain_levels_building_coal_mine | chain_levels_per_10k_pop_building_coal_mine |
|---|---|---|---|---|---|---|
| ammunition | era_3_construction | success | 7.925092066941082 | 1143356.0306570823 | 3.1222958678599477 | 0.03482277256028827 |
| ammunition | era_5_automation | success | 29.222049157420226 | 382442.64892258786 | 0.9727341863745714 | 0.05466401194488629 |
| ammunition | cangshulun | success | 25.71254709280572 | 410304.48677220684 | 4.114864422854238 | 0.203468548563751 |
| small_arms | era_3_construction | success | 6.069145869707615 | 1764288.4707792674 | 2.7551309265974004 | 0.018191127267855278 |
| small_arms | era_5_automation | success | 40.36656246940272 | 271104.334062767 | 1.4176454040431872 | 0.11004898415725188 |
The comparison directory contains this summary and three grouped bar charts:
pop.svgplotssystem_employment, the whole-system employed population in workers. It excludes dependents and unemployed people.construction_points.svgplotssystem_construction_costin construction points.gdp_per_capita.svgplotssystem_gdp_per_capita_annual: annual system GDP divided by system employment, in £ per worker per year. Zero employment gives zero, matching the economy model's GDP-per-capita convention.
All charts use goods as the main horizontal-axis ticks, with configuration ticks beneath the individual bars. Colors identify configurations consistently between charts. A failed solve keeps its tick and shows an × instead of a bar; it is not treated as a zero requirement. SVG width grows with the number of goods so the two tick levels remain readable when zoomed.
All three configurations: whole-system employment by terminal good, in workers.
All three configurations: whole-system construction requirements by terminal good, in construction points.
All three configurations: annual whole-system GDP per employed worker, in £ per worker per year.
Click any chart to open the original SVG and zoom in on its labels.
Population chart · Construction chart · Annual GDP per capita chart
from pathlib import Path
import pandas as pd
comparison = pd.read_csv(
Path("artifacts/analyses/supply_chains/comparison/summary.csv")
)
successful = comparison.loc[
comparison["configuration"].eq("era_5_automation")
& comparison["status"].eq("success")
]
lowest_employment = successful.sort_values(
["system_employment", "good"], kind="stable"
).head(10)
Sorting the automation rows by construction answers which of those minimum-employment chains uses least construction. It does not compute a minimum-construction optimum for each good.
Reproducing Cangshulun's video¶
Apart from the video mentioned above, the uploader also made a follow-up video running a complete supply chain analysis for all goods on the 1.12 patch. His methodology is not mathematic programming, but rather a leontief matrix approach, where production units are selected manually. To reproduce his results, the examples/supply_chain_cangshulun.py script adds throughput bonuses, production-method bans, and named product variants to approximate the video's assumptions.
The script writes the latest complete results to
artifacts/analyses/supply_chains/cangshulun_video/summary.csv. The frozen
artifacts/analyses/supply_chains/cangshulun_video/summary_1.12.csv contains
60 scenarios from the 1.12.5 results, extracted from artifact commit
e7a3748964cf28f453db1899f08636eb04c45d71 and sorted by annual value added per
worker. It retains only the columns used for the video comparison:
scenariosystem_gdp_annualsystem_employmentsystem_gdp_per_capita_annualsystem_levels_per_10k_pop_building_sulfur_minesystem_levels_per_10k_pop_building_coal_minesystem_levels_per_10k_pop_building_iron_minesystem_levels_per_10k_pop_building_lead_minesystem_levels_per_10k_pop_building_logging_campsystem_levels_per_10k_pop_building_rubber_plantationsystem_levels_per_10k_pop_building_oil_rig
The video's table at 1:04 is reproduced below. Its total value column is
weekly, so compare it with system_gdp_annual / 52; its per-worker value is
annual and corresponds to system_gdp_per_capita_annual. Resource columns
measure building levels per 10,000 employed workers. Our runs target £100,000
of weekly terminal output, so raw value and employment totals have a different
scale from the screenshot; compare the per-worker and per-10,000-worker ratios.
Source: Cangshulun's video, 1:04. Click the image to inspect the full table.
| scenario | system_gdp_per_capita_annual | system_levels_per_10k_pop_building_coal_mine | system_levels_per_10k_pop_building_oil_rig |
|---|---|---|---|
| base:oil | 108.919629312571 | 0.036890872165386 | 2.64369000668648 |
| base:sulfur | 103.356087210857 | 0.105249157282333 | 0.220526906758574 |
| base:transportation | 100.468515120695 | 0.0550937550952978 | 0.738706498450207 |
| base:electricity | 100.271318402311 | 0.0638803510830851 | 1.24121037351983 |
| base:merchant_marine | 92.1092956591867 | 0.0451802533435092 | 0.680902530759515 |
The following examples compare annual nominal value added per employed worker
(£/worker/year). Difference means (project / video - 1) * 100%.
| Supply chain | Video 1.12.4 | Project 1.12.5 | Difference |
|---|---|---|---|
| Oil | 107.99 | 108.92 | +0.9% |
| Sulfur | 102.31 | 103.36 | +1.0% |
| Automobiles | 87.47 | 88.86 | +1.6% |
| Engines | 84.68 | 86.90 | +2.6% |
| Tools | 78.82 | 80.93 | +2.7% |
| Coal-fired electricity | 73.08 | 73.14 | +0.1% |
| Rubber | 32.11 | 32.21 | +0.3% |
| Luxury furniture + surplus wood | 63.60 | 57.86 | −9.0% |
| Fine art | 36.80 | 37.32 | +1.4% |
| Urban services + transportation | 26.55 | 26.83 | +1.1% |
The electricity, luxury-furniture, and urban-service rows use the
coal_fired_plant:electricity, luxury_furniture:luxury_furniture, and
urban_center_transportation:services scenarios respectively; the other rows
use base:<good> scenarios. Most rows shown agree within 3%, supporting the
video's broad productivity ranking, except for luxury furniture, which remains 9.0% lower.
Production-method and coproduct choices can differ because the optimizer
selects a minimum-employment chain rather than the video's fixed recipe.
Download 1.12 selected results (1.12.5 inputs)
· Download latest complete results (1.13.11)
· View examples/supply_chain_cangshulun.py
Output inventory¶
Paths are relative to --output-dir. All text outputs use UTF-8 without a BOM.
The comparison writes one detailed result at a time rather than retaining
all goods' graphs and snapshots in memory.
| Directory | Files |
|---|---|
analyses/supply_chains/era_3_construction/<good>/ |
Detailed files below for successful solves |
analyses/supply_chains/era_5_automation/<good>/ |
Same reports, plots, and diagrams |
analyses/supply_chains/cangshulun/<good>/ |
Same reports, plots, and diagrams |
analyses/supply_chains/<configuration>/ |
summary.csv, combining that configuration's selected goods, and building_levels.csv, the complete production-unit levels for each selected good |
analyses/supply_chains/comparison/ |
summary.csv, pop.svg, construction_points.svg, gdp_per_capita.svg, covering all selected goods and presets |
analyses/supply_chains/cangshulun_video/ |
Latest complete summary.csv and frozen selected-column summary_1.12.csv; ordinary generation updates only summary.csv |
Each successful comparison configuration contains goods.csv, processes.csv,
flows.csv, workforce.csv, constraints.csv, bottlenecks.csv,
alternatives.csv, supply_chain_recipe.mmd, supply_chain_realised.mmd,
network.svg, goods_balance.svg, workforce.svg, constraints.svg,
contributions_gdp.svg, contributions_employment.svg, and
contributions_construction_cost.svg. Headline metrics and failure rows are
stored only in the configuration-level summary.csv and comparison CSVs.
The configuration summary and comparison CSVs use the public sweep schema,
plus configuration and ban_config. GDP efficiency and per-building resource
levels, including levels per 10,000 employed workers, are public summary fields
shared with the video export. The other detailed CSVs retain their
public report schemas. Cross-good summaries sit at configuration level.
A selected-good run replaces the configuration summaries and combined
comparison with that run's selection; other goods' directories remain.
Each configuration's building_levels.csv is also replaced for that selection.
Its first column, config, identifies the building and PM combination, followed
by one column per selected good. Unused production units have zero levels;
failed solves have blank cells throughout their good's column.
