Skip to content

Commit 90b3fe3

Browse files
committed
Add uncapped value-added trade model
1 parent 6805b85 commit 90b3fe3

5 files changed

Lines changed: 267 additions & 53 deletions

File tree

site/admin/index.html

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
})();
1919
</script>
2020
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%2314171a'/%3E%3Cpath d='M8 8h32L8 40z' fill='%23f0c33b'/%3E%3Cpath d='M56 56H24l32-32z' fill='%230d65d9'/%3E%3C/svg%3E">
21-
<link rel="stylesheet" href="../css/base.css?v=20260604-trade-v4-soften">
22-
<link rel="stylesheet" href="../css/trade.css?v=20260604-trade-v4-soften">
23-
<link rel="stylesheet" href="../css/ledger.css?v=20260604-trade-v4-soften">
24-
<link rel="stylesheet" href="../css/simulation.css?v=20260604-trade-v4-soften">
25-
<link rel="stylesheet" href="../css/records.css?v=20260604-trade-v4-soften">
26-
<link rel="stylesheet" href="../css/responsive.css?v=20260604-trade-v4-soften">
21+
<link rel="stylesheet" href="../css/base.css?v=20260604-value-added-trade">
22+
<link rel="stylesheet" href="../css/trade.css?v=20260604-value-added-trade">
23+
<link rel="stylesheet" href="../css/ledger.css?v=20260604-value-added-trade">
24+
<link rel="stylesheet" href="../css/simulation.css?v=20260604-value-added-trade">
25+
<link rel="stylesheet" href="../css/records.css?v=20260604-value-added-trade">
26+
<link rel="stylesheet" href="../css/responsive.css?v=20260604-value-added-trade">
2727
</head>
2828
<body data-app-mode="admin">
2929
<header class="topbar">
@@ -63,24 +63,24 @@ <h1>Global Ledger</h1>
6363
<span id="sourceNote"></span>
6464
</footer>
6565

66-
<script src="../data.js?v=20260604-trade-v4-soften"></script>
67-
<script src="../js/engine/fiscal.js?v=20260604-trade-v4-soften"></script>
68-
<script src="../js/engine/tradePolicy.js?v=20260604-trade-v4-soften"></script>
69-
<script src="../js/engine/trade.js?v=20260604-trade-v4-soften"></script>
70-
<script src="../engine.js?v=20260604-trade-v4-soften"></script>
71-
<script src="../js/app/config.js?v=20260604-trade-v4-soften"></script>
72-
<script src="../js/app/format.js?v=20260604-trade-v4-soften"></script>
73-
<script src="../js/app/sync.js?v=20260604-trade-v4-soften"></script>
74-
<script src="../js/app/statusTables.js?v=20260604-trade-v4-soften"></script>
75-
<script src="../js/app/recordsParser.js?v=20260604-trade-v4-soften"></script>
76-
<script src="../js/app/records.js?v=20260604-trade-v4-soften"></script>
77-
<script src="../js/app/tradeMapShapes.js?v=20260604-trade-v4-soften"></script>
78-
<script src="../js/app/tradeZones.js?v=20260604-trade-v4-soften"></script>
79-
<script src="../js/app/tradeRouteMesh.js?v=20260604-trade-v4-soften"></script>
80-
<script src="../js/app/tradeLaneSkeleton.js?v=20260604-trade-v4-soften"></script>
81-
<script src="../js/app/tradeMap.js?v=20260604-trade-v4-soften"></script>
82-
<script src="../js/app/tradeView.js?v=20260604-trade-v4-soften"></script>
83-
<script src="../js/app/editorView.js?v=20260604-trade-v4-soften"></script>
84-
<script src="../app.js?v=20260604-trade-v4-soften"></script>
66+
<script src="../data.js?v=20260604-value-added-trade"></script>
67+
<script src="../js/engine/fiscal.js?v=20260604-value-added-trade"></script>
68+
<script src="../js/engine/tradePolicy.js?v=20260604-value-added-trade"></script>
69+
<script src="../js/engine/trade.js?v=20260604-value-added-trade"></script>
70+
<script src="../engine.js?v=20260604-value-added-trade"></script>
71+
<script src="../js/app/config.js?v=20260604-value-added-trade"></script>
72+
<script src="../js/app/format.js?v=20260604-value-added-trade"></script>
73+
<script src="../js/app/sync.js?v=20260604-value-added-trade"></script>
74+
<script src="../js/app/statusTables.js?v=20260604-value-added-trade"></script>
75+
<script src="../js/app/recordsParser.js?v=20260604-value-added-trade"></script>
76+
<script src="../js/app/records.js?v=20260604-value-added-trade"></script>
77+
<script src="../js/app/tradeMapShapes.js?v=20260604-value-added-trade"></script>
78+
<script src="../js/app/tradeZones.js?v=20260604-value-added-trade"></script>
79+
<script src="../js/app/tradeRouteMesh.js?v=20260604-value-added-trade"></script>
80+
<script src="../js/app/tradeLaneSkeleton.js?v=20260604-value-added-trade"></script>
81+
<script src="../js/app/tradeMap.js?v=20260604-value-added-trade"></script>
82+
<script src="../js/app/tradeView.js?v=20260604-value-added-trade"></script>
83+
<script src="../js/app/editorView.js?v=20260604-value-added-trade"></script>
84+
<script src="../app.js?v=20260604-value-added-trade"></script>
8585
</body>
8686
</html>

site/engine.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@
569569
const { civFactories, militaryFactories, shipyards, mobilization, national, tradeBalance } = inputs;
570570
const maintenanceCost = (civFactories + shipyards + militaryFactories * mobilization.maintenanceCost) * 0.1;
571571
const baseBudgetTotal = 10 + industrialContribution + populationContribution - maintenanceCost;
572-
const tradeImpactOnBudget = clamp(1 + (tradeBalance / Math.max(baseBudgetTotal, 100)) * 0.1, 0.1, 2);
572+
const tradeImpactOnBudget = Math.max(0.1, 1 + (tradeBalance / Math.max(baseBudgetTotal, 100)) * 0.1);
573573
const budgetCapacity = Math.max(0, Math.round(baseBudgetTotal * tradeImpactOnBudget + number(tariffRevenue, 0)) + number(national.budgetAdjustment, 0));
574574
return {
575575
budgetCapacity,

site/index.html

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@
2828
})();
2929
</script>
3030
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='10' fill='%2314171a'/%3E%3Cpath d='M8 8h32L8 40z' fill='%23f0c33b'/%3E%3Cpath d='M56 56H24l32-32z' fill='%230d65d9'/%3E%3C/svg%3E">
31-
<link rel="stylesheet" href="css/base.css?v=20260604-trade-v4-soften">
32-
<link rel="stylesheet" href="css/trade.css?v=20260604-trade-v4-soften">
33-
<link rel="stylesheet" href="css/ledger.css?v=20260604-trade-v4-soften">
34-
<link rel="stylesheet" href="css/simulation.css?v=20260604-trade-v4-soften">
35-
<link rel="stylesheet" href="css/records.css?v=20260604-trade-v4-soften">
36-
<link rel="stylesheet" href="css/responsive.css?v=20260604-trade-v4-soften">
31+
<link rel="stylesheet" href="css/base.css?v=20260604-value-added-trade">
32+
<link rel="stylesheet" href="css/trade.css?v=20260604-value-added-trade">
33+
<link rel="stylesheet" href="css/ledger.css?v=20260604-value-added-trade">
34+
<link rel="stylesheet" href="css/simulation.css?v=20260604-value-added-trade">
35+
<link rel="stylesheet" href="css/records.css?v=20260604-value-added-trade">
36+
<link rel="stylesheet" href="css/responsive.css?v=20260604-value-added-trade">
3737
</head>
3838
<body data-app-mode="public">
3939
<header class="topbar">
@@ -75,24 +75,24 @@ <h1>Global Ledger</h1>
7575
</span>
7676
</footer>
7777

78-
<script src="data.js?v=20260604-trade-v4-soften"></script>
79-
<script src="js/engine/fiscal.js?v=20260604-trade-v4-soften"></script>
80-
<script src="js/engine/tradePolicy.js?v=20260604-trade-v4-soften"></script>
81-
<script src="js/engine/trade.js?v=20260604-trade-v4-soften"></script>
82-
<script src="engine.js?v=20260604-trade-v4-soften"></script>
83-
<script src="js/app/config.js?v=20260604-trade-v4-soften"></script>
84-
<script src="js/app/format.js?v=20260604-trade-v4-soften"></script>
85-
<script src="js/app/sync.js?v=20260604-trade-v4-soften"></script>
86-
<script src="js/app/statusTables.js?v=20260604-trade-v4-soften"></script>
87-
<script src="js/app/recordsParser.js?v=20260604-trade-v4-soften"></script>
88-
<script src="js/app/records.js?v=20260604-trade-v4-soften"></script>
89-
<script src="js/app/tradeMapShapes.js?v=20260604-trade-v4-soften"></script>
90-
<script src="js/app/tradeZones.js?v=20260604-trade-v4-soften"></script>
91-
<script src="js/app/tradeRouteMesh.js?v=20260604-trade-v4-soften"></script>
92-
<script src="js/app/tradeLaneSkeleton.js?v=20260604-trade-v4-soften"></script>
93-
<script src="js/app/tradeMap.js?v=20260604-trade-v4-soften"></script>
94-
<script src="js/app/tradeView.js?v=20260604-trade-v4-soften"></script>
95-
<script src="js/app/editorView.js?v=20260604-trade-v4-soften"></script>
96-
<script src="app.js?v=20260604-trade-v4-soften"></script>
78+
<script src="data.js?v=20260604-value-added-trade"></script>
79+
<script src="js/engine/fiscal.js?v=20260604-value-added-trade"></script>
80+
<script src="js/engine/tradePolicy.js?v=20260604-value-added-trade"></script>
81+
<script src="js/engine/trade.js?v=20260604-value-added-trade"></script>
82+
<script src="engine.js?v=20260604-value-added-trade"></script>
83+
<script src="js/app/config.js?v=20260604-value-added-trade"></script>
84+
<script src="js/app/format.js?v=20260604-value-added-trade"></script>
85+
<script src="js/app/sync.js?v=20260604-value-added-trade"></script>
86+
<script src="js/app/statusTables.js?v=20260604-value-added-trade"></script>
87+
<script src="js/app/recordsParser.js?v=20260604-value-added-trade"></script>
88+
<script src="js/app/records.js?v=20260604-value-added-trade"></script>
89+
<script src="js/app/tradeMapShapes.js?v=20260604-value-added-trade"></script>
90+
<script src="js/app/tradeZones.js?v=20260604-value-added-trade"></script>
91+
<script src="js/app/tradeRouteMesh.js?v=20260604-value-added-trade"></script>
92+
<script src="js/app/tradeLaneSkeleton.js?v=20260604-value-added-trade"></script>
93+
<script src="js/app/tradeMap.js?v=20260604-value-added-trade"></script>
94+
<script src="js/app/tradeView.js?v=20260604-value-added-trade"></script>
95+
<script src="js/app/editorView.js?v=20260604-value-added-trade"></script>
96+
<script src="app.js?v=20260604-value-added-trade"></script>
9797
</body>
9898
</html>

site/js/engine/trade.js

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,43 @@
255255
return clamp(0.88 + Math.sqrt(Math.max(0, input.economicTradeDiversity)) / 58, 0.88, 1.22);
256256
}
257257

258+
function valueAddedStrength(input) {
259+
const industryScale = input.civilianFactories + input.militaryFactories * 0.35 + input.shipyards * 2.5;
260+
const diversityScore = clamp(Math.sqrt(Math.max(0, input.economicTradeDiversity)) / 12, 0, 1.18);
261+
const developmentScore = clamp(input.developmentLevel / 20, 0, 1);
262+
const industryScore = clamp(Math.log10(Math.max(industryScale, 1)) / 3, 0, 1);
263+
const shipyardScore = clamp(Math.sqrt(Math.max(input.shipyards, 0)) / 10, 0, 1);
264+
const stabilityScore = clamp(number(input.governmentalStability, 70) / 100, 0, 1);
265+
const corruptionScore = clamp((100 - number(input.corruption, 0)) / 100, 0, 1);
266+
return clamp(
267+
diversityScore * 30
268+
+ developmentScore * 22
269+
+ industryScore * 18
270+
+ shipyardScore * 12
271+
+ stabilityScore * 10
272+
+ corruptionScore * 8,
273+
0,
274+
100
275+
);
276+
}
277+
278+
function valueAddedProfile(input) {
279+
const strength = valueAddedStrength(input);
280+
const strengthRatio = strength / 100;
281+
const autarkyRatio = clamp(input.autarkyIndex, 0, 100) / 100;
282+
const tradeAccess = clamp(1.1 - autarkyRatio * 0.55, 0.38, 1.08);
283+
const exportMultiplier = clamp(0.76 + Math.pow(strengthRatio, 1.18) * 1.45 - autarkyRatio * 0.22, 0.72, 2.08);
284+
const capacityMultiplier = clamp(0.78 + strengthRatio * 0.55 - autarkyRatio * 0.25, 0.72, 1.32);
285+
const productiveImportShare = clamp(Math.pow(strengthRatio, 1.08) * tradeAccess, 0, 0.82);
286+
return {
287+
strength,
288+
strengthRatio,
289+
exportMultiplier,
290+
capacityMultiplier,
291+
productiveImportShare
292+
};
293+
}
294+
258295
function physicalTradeBase(input) {
259296
const populationMarket = Math.sqrt(Math.max(input.population, 0) / 1000000) * 5200;
260297
const industrialMarket = input.civilianFactories * 1500 + input.militaryFactories * 340 + input.shipyards * 3000;
@@ -283,10 +320,12 @@
283320
const reliance = Math.pow(Math.max(0, input.exportReliance) / 100, 1.32);
284321
const production = input.civilianFactories * 850 + input.shipyards * 2500 + input.developmentLevel * 1750;
285322
const policy = tradePolicyProfile(input.tradePolicy);
323+
const valueAdded = valueAddedProfile(input);
286324
return Math.max(
287325
1,
288326
(physicalTradeBase(input) * reliance * 0.92 + production)
289327
* diversityResilience(input)
328+
* valueAdded.exportMultiplier
290329
* policy.exportSupply
291330
* sanctionNetworkAccess(input.sanctionsLevel)
292331
* autarkyTradeAccess(input, "export")
@@ -312,6 +351,7 @@
312351
function worldPoolCapacityScore(input) {
313352
const policy = tradePolicyProfile(input.tradePolicy);
314353
const logistics = 0.58 + tradeLogisticsProfile(input).overall / 82;
354+
const valueAdded = valueAddedProfile(input);
315355
return Math.max(
316356
1,
317357
physicalTradeBase(input)
@@ -320,6 +360,7 @@
320360
* autarkyTradeAccess(input)
321361
* logistics
322362
* diversityResilience(input)
363+
* valueAdded.capacityMultiplier
323364
);
324365
}
325366

@@ -2123,20 +2164,26 @@
21232164
const totalFlow = Math.max(0, importFlow + exportFlow);
21242165
const policy = tradePolicyProfile(current.tradePolicy);
21252166
const logistics = tradeLogisticsProfile(current);
2167+
const valueAdded = valueAddedProfile(current);
21262168
const relianceGap = number(current.exportReliance, 0) - number(current.importReliance, 0);
21272169
const relianceGapSignal = Math.sign(relianceGap) * Math.pow(Math.abs(relianceGap), 0.88);
21282170
const relianceAverage = Math.max(1, (number(current.exportReliance, 0) + number(current.importReliance, 0)) / 2);
21292171
const normalizedGap = relianceGap / relianceAverage;
21302172
const balanceScale = 70 + Math.sqrt(Math.max(totalFlow, 0)) * 0.24 + Math.sqrt(Math.max(current.budgetCapacity, 0)) * 3.2;
21312173
const structuralBalance = relianceGapSignal * balanceScale * policy.balanceRisk;
2132-
const flowBalance = exportFlow * 0.014 - importFlow * 0.015;
2174+
const exportValuePremium = exportFlow * valueAdded.strengthRatio * 0.1;
2175+
const productiveImportCredit = importFlow * valueAdded.productiveImportShare * 0.038;
2176+
const rawImportCost = importFlow * (0.018 + clamp(current.autarkyIndex, 0, 100) / 10000);
2177+
const flowBalance = exportFlow * 0.022 + exportValuePremium + productiveImportCredit - rawImportCost;
21332178
const tariffBalance = number(impact.tariffRevenueDelta, 0) * 0.55 - number(impact.importCostDelta, 0) * 0.36;
2134-
const imbalancePenalty = -Math.pow(Math.abs(normalizedGap), 1.35) * balanceScale * 0.72 * (relianceGap < 0 ? 1.14 : 0.34);
2179+
const importGapPressure = relianceGap < 0 ? clamp(1.2 - valueAdded.productiveImportShare * 0.78, 0.46, 1.2) : 0.34;
2180+
const imbalancePenalty = -Math.pow(Math.abs(normalizedGap), 1.35) * balanceScale * 0.72 * importGapPressure;
21352181
const tradeBalance = roundCurrency(flowBalance + structuralBalance + tariffBalance + imbalancePenalty + number(impact.tradeBalanceDelta, 0));
21362182
const tradeCapacity = roundCurrency(
21372183
worldPoolCapacityScore(current) / 600
21382184
+ logistics.overall * 140
21392185
+ diversityResilience(current) * 1800
2186+
+ valueAdded.strength * 42
21402187
);
21412188
const tradeFlow = roundCurrency(totalFlow);
21422189
const economicImpactScore = Math.max(

0 commit comments

Comments
 (0)