code wiki / (root) / nx_econsim_page.nx

nx_econsim_page.nx source

↩ module page · 245 lines · 15361 B

1// nx_econsim_page.nx -- EMIT the live nishifamily.com/econsim page for the 2// Capitalism Lab (EconSim). Self-contained game-side emitter: it imports the 3// sovereign sim organs and renders their output COMPUTED AT RENDER TIME (no 4// hand-typed numbers), then writes web_assets/econsim.html. Publishing is the 5// separate sovereign step nx_aw_push (additive, vault-backed) -- the shared 6// loop every property reuses. No JS/HTML is hand-written; this organ authors 7// the page. license_tier: ORIGINAL 8// 9// genealogy_id: capitalism_lab_econsim_page 10// lineage_id: nx_econsim_page_v1 11 12import "nx_syscalls.nx" 13import "nx_caplab_market.nx" 14import "nx_caplab_compete.nx" 15import "nx_caplab_supply.nx" 16import "nx_caplab_sim.nx" 17import "nx_caplab_quality.nx" 18 19const EC_OUT: *u8 = "web_assets/econsim.html" 20const EC_CAP: i64 = 262144 21 22// append a NUL-terminated string into dst at off; returns new off. 23func ec_cat(dst: *u8, off: i64, s: *u8) -> i64 { 24 var o: i64 = off 25 var i: i64 = 0 26 while s[i] != 0 as u8 { dst[o] = s[i]; o = o + 1; i = i + 1 } 27 return o 28} 29 30// append a signed decimal into dst at off; returns new off (handles losses). 31func ec_catn(dst: *u8, off: i64, v: i64) -> i64 { 32 var o: i64 = off 33 var n: i64 = v 34 if n < 0 { dst[o] = 45 as u8; o = o + 1; n = 0 - n } 35 let tmp: *u8 = sys_mmap(32) 36 var k: i64 = 0 37 if n == 0 { tmp[0] = 48 as u8; k = 1 } 38 while n > 0 { tmp[k] = (48 + (n % 10)) as u8; n = n / 10; k = k + 1 } 39 var j: i64 = k - 1 40 while j >= 0 { dst[o] = tmp[j]; o = o + 1; j = j - 1 } 41 return o 42} 43 44func main() -> i64 { 45 let now: i64 = sys_now_realtime_sec() 46 let h: *u8 = sys_mmap(EC_CAP) 47 var w: i64 = 0 48 49 // market under view (same atom the R0 gate proves): a=100, b=2, cost=10 50 let mkt_a: i64 = 100 51 let mkt_b: i64 = 2 52 let mkt_c: i64 = 10 53 54 w = ec_cat(h, w, "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\">\n" as *u8) 55 w = ec_cat(h, w, "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n" as *u8) 56 w = ec_cat(h, w, "<title>EconSim &mdash; Nishi Capitalism Lab</title>\n" as *u8) 57 w = ec_cat(h, w, "<style>\n" as *u8) 58 w = ec_cat(h, w, ":root{--bg:#0b0f14;--panel:#131b24;--ink:#e6edf3;--mut:#8aa0b4;--acc:#4cc2ff;--good:#3fb950;--bad:#f85149;--line:#243140}\n" as *u8) 59 w = ec_cat(h, w, "*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 system-ui,Segoe UI,Roboto,sans-serif}\n" as *u8) 60 w = ec_cat(h, w, "header{padding:32px 20px 18px;max-width:920px;margin:0 auto}h1{margin:0;font-size:30px;letter-spacing:.3px}\n" as *u8) 61 w = ec_cat(h, w, ".sub{color:var(--mut);margin:.5em 0 0}.stamp{color:var(--mut);font-size:12.5px;margin:.4em 0 0}\n" as *u8) 62 w = ec_cat(h, w, "main{max-width:920px;margin:0 auto;padding:0 20px 60px}section{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:18px 20px;margin:18px 0}\n" as *u8) 63 w = ec_cat(h, w, "h2{margin:.1em 0 .3em;font-size:19px}code{color:var(--acc);font-size:.92em}\n" as *u8) 64 w = ec_cat(h, w, "table{border-collapse:collapse;width:100%;margin:.6em 0}th,td{padding:7px 10px;text-align:right;border-bottom:1px solid var(--line)}th:first-child,td:first-child{text-align:left}\n" as *u8) 65 w = ec_cat(h, w, "th{color:var(--mut);font-weight:600;font-size:12.5px;text-transform:uppercase;letter-spacing:.4px}\n" as *u8) 66 w = ec_cat(h, w, ".pos{color:var(--good)}.neg{color:var(--bad)}.peak{background:#10261a}\n" as *u8) 67 w = ec_cat(h, w, ".ladder{list-style:none;padding:0;margin:.4em 0}.ladder li{padding:4px 0;border-bottom:1px solid var(--line)}.done{color:var(--good)}.todo{color:var(--mut)}\n" as *u8) 68 w = ec_cat(h, w, "footer{max-width:920px;margin:0 auto;padding:8px 20px 40px;color:var(--mut);font-size:12.5px}\n" as *u8) 69 w = ec_cat(h, w, "</style></head><body>\n" as *u8) 70 71 w = ec_cat(h, w, "<header><h1>EconSim &mdash; Capitalism Lab</h1>\n" as *u8) 72 w = ec_cat(h, w, "<p class=\"sub\">An in-browser, multiplayer economic strategy game built 100&percnt; on the Nishi sovereign stack &mdash; no shell, no Python, no hand-written JS/HTML. This page was emitted by the organ <code>nx_econsim_page</code>.</p>\n" as *u8) 73 w = ec_cat(h, w, "<p class=\"stamp\">Generated LIVE at epoch " as *u8) 74 w = ec_catn(h, w, now) 75 w = ec_cat(h, w, " &mdash; every number below is COMPUTED by the sovereign sim (<code>nx_caplab_market</code> + <code>nx_caplab_compete</code>) at render time, not typed in.</p></header>\n" as *u8) 76 77 w = ec_cat(h, w, "<main>\n" as *u8) 78 79 // ===== R0: the market atom ===== 80 w = ec_cat(h, w, "<section><h2>R0 &mdash; the market atom (one firm)</h2>\n" as *u8) 81 w = ec_cat(h, w, "<p>Linear demand: max demand <b>100</b>, slope <b>2</b>, unit cost <b>10</b>. Demand falls as price rises; profit = (price &minus; cost) &times; units sold.</p>\n" as *u8) 82 w = ec_cat(h, w, "<table><tr><th>Price</th><th>Demand</th><th>Revenue</th><th>Profit</th></tr>\n" as *u8) 83 let opt: i64 = nx_clab_optimal_price(mkt_a, mkt_b, mkt_c) 84 var p: i64 = 0 85 while p <= 50 { 86 let pf: i64 = nx_clab_profit(mkt_a, mkt_b, p, mkt_c) 87 if p == opt { w = ec_cat(h, w, "<tr class=\"peak\">" as *u8) } 88 else { w = ec_cat(h, w, "<tr>" as *u8) } 89 w = ec_cat(h, w, "<td>" as *u8); w = ec_catn(h, w, p) 90 w = ec_cat(h, w, "</td><td>" as *u8); w = ec_catn(h, w, nx_clab_demand(mkt_a, mkt_b, p)) 91 w = ec_cat(h, w, "</td><td>" as *u8); w = ec_catn(h, w, nx_clab_revenue(mkt_a, mkt_b, p)) 92 if pf < 0 { w = ec_cat(h, w, "</td><td class=\"neg\">" as *u8) } 93 else { w = ec_cat(h, w, "</td><td class=\"pos\">" as *u8) } 94 w = ec_catn(h, w, pf) 95 w = ec_cat(h, w, "</td></tr>\n" as *u8) 96 p = p + 10 97 } 98 w = ec_cat(h, w, "</table>\n" as *u8) 99 w = ec_cat(h, w, "<p>The sim's optimiser scans every price and returns the profit-maximising one: <b>" as *u8) 100 w = ec_catn(h, w, opt) 101 w = ec_cat(h, w, "</b> (profit <b>" as *u8) 102 w = ec_catn(h, w, nx_clab_profit(mkt_a, mkt_b, opt, mkt_c)) 103 w = ec_cat(h, w, "</b>) &mdash; which matches the closed-form monopoly price. The highlighted row is that peak.</p></section>\n" as *u8) 104 105 // ===== R1: competition ===== 106 w = ec_cat(h, w, "<section><h2>R1 &mdash; competition (three firms, one market)</h2>\n" as *u8) 107 w = ec_cat(h, w, "<p>Max willingness-to-pay <b>100</b>, <b>100</b> customers. Customers split by how far each firm undercuts; the split is conserved (largest-remainder) so quantities always sum to the market. Each firm's unit cost is <b>20</b>.</p>\n" as *u8) 108 let prices: *i64 = sys_mmap(24) as *i64 109 prices[0] = 40 110 prices[1] = 50 111 prices[2] = 60 112 let q: *i64 = sys_mmap(24) as *i64 113 nx_clab_split(3, prices, 100, 100, q) 114 w = ec_cat(h, w, "<table><tr><th>Firm price</th><th>Customers</th><th>Profit</th></tr>\n" as *u8) 115 var f: i64 = 0 116 var qsum: i64 = 0 117 while f < 3 { 118 w = ec_cat(h, w, "<tr><td>" as *u8); w = ec_catn(h, w, prices[f]) 119 w = ec_cat(h, w, "</td><td>" as *u8); w = ec_catn(h, w, q[f]) 120 w = ec_cat(h, w, "</td><td class=\"pos\">" as *u8); w = ec_catn(h, w, nx_clab_firm_profit(prices[f], 20, q[f])) 121 w = ec_cat(h, w, "</td></tr>\n" as *u8) 122 qsum = qsum + q[f] 123 f = f + 1 124 } 125 w = ec_cat(h, w, "<tr><td><b>total</b></td><td><b>" as *u8); w = ec_catn(h, w, qsum) 126 w = ec_cat(h, w, "</b></td><td></td></tr>\n" as *u8) 127 w = ec_cat(h, w, "</table>\n" as *u8) 128 w = ec_cat(h, w, "<p>The cheapest firm wins the most <i>customers</i> &mdash; but margin &times; volume decides who actually earns the most. That tension is the whole game.</p></section>\n" as *u8) 129 130 // ===== R2: supply chain ===== 131 w = ec_cat(h, w, "<section><h2>R2 &mdash; production &amp; supply chains</h2>\n" as *u8) 132 w = ec_cat(h, w, "<p>No magic costs: a firm converts raw &rarr; factory &rarr; finished, and input costs roll UP into the unit cost it prices against. Output is capped by the scarcest input.</p>\n" as *u8) 133 let sqp: *i64 = (sys_mmap(8)) as *i64 134 sqp[0] = 2 135 let spr: *i64 = (sys_mmap(8)) as *i64 136 spr[0] = 5 137 let s_inter: i64 = nx_clab_unit_cost(1, sqp, spr, 3) 138 let fqp: *i64 = (sys_mmap(8)) as *i64 139 fqp[0] = 3 140 let fpr: *i64 = (sys_mmap(8)) as *i64 141 fpr[0] = s_inter 142 let s_fin: i64 = nx_clab_unit_cost(1, fqp, fpr, 4) 143 w = ec_cat(h, w, "<table><tr><th>Stage</th><th>Recipe</th><th>Unit cost</th></tr>\n" as *u8) 144 w = ec_cat(h, w, "<tr><td>raw material</td><td>market price</td><td>" as *u8); w = ec_catn(h, w, 5); w = ec_cat(h, w, "</td></tr>\n" as *u8) 145 w = ec_cat(h, w, "<tr><td>intermediate</td><td>2 raw + proc 3</td><td>" as *u8); w = ec_catn(h, w, s_inter); w = ec_cat(h, w, "</td></tr>\n" as *u8) 146 w = ec_cat(h, w, "<tr><td>finished</td><td>3 intermediate + proc 4</td><td>" as *u8); w = ec_catn(h, w, s_fin); w = ec_cat(h, w, "</td></tr>\n" as *u8) 147 w = ec_cat(h, w, "</table>\n" as *u8) 148 let tqp: *i64 = (sys_mmap(16)) as *i64 149 tqp[0] = 2 150 tqp[1] = 1 151 let tst: *i64 = (sys_mmap(16)) as *i64 152 tst[0] = 100 153 tst[1] = 30 154 w = ec_cat(h, w, "<p>With 100 raw (2/unit) and 30 labor (1/unit), throughput is <b>" as *u8) 155 w = ec_catn(h, w, nx_clab_throughput(2, tqp, tst)) 156 w = ec_cat(h, w, "</b> units &mdash; labor is the bottleneck. Pricing the finished good (cost " as *u8) 157 w = ec_catn(h, w, s_fin) 158 w = ec_cat(h, w, ") the optimiser sets price <b>" as *u8) 159 w = ec_catn(h, w, nx_clab_optimal_price(100, 2, s_fin)) 160 w = ec_cat(h, w, "</b> &mdash; thin margins, because the supply chain is expensive.</p></section>\n" as *u8) 161 162 // ===== R3: a 12-month game over time ===== 163 w = ec_cat(h, w, "<section><h2>R3 &mdash; a 12-month game (firms compete over time)</h2>\n" as *u8) 164 w = ec_cat(h, w, "<p>Three firms run a 12-month year. Each month the market splits by price, firms sell up to capacity, cash banks. Same inputs &rarr; identical replay (deterministic).</p>\n" as *u8) 165 let gp: *i64 = (sys_mmap(24)) as *i64 166 gp[0] = 60 167 gp[1] = 45 168 gp[2] = 35 169 let guc: *i64 = (sys_mmap(24)) as *i64 170 guc[0] = 20 171 guc[1] = 20 172 guc[2] = 20 173 let gcap: *i64 = (sys_mmap(24)) as *i64 174 gcap[0] = 100 175 gcap[1] = 100 176 gcap[2] = 100 177 let gcash: *i64 = (sys_mmap(24)) as *i64 178 gcash[0] = 0 179 gcash[1] = 0 180 gcash[2] = 0 181 nx_clab_sim_run(3, gp, guc, gcap, 100, 120, gcash, 12) 182 w = ec_cat(h, w, "<table><tr><th>Strategy</th><th>Price</th><th>Cash after 12 months</th></tr>\n" as *u8) 183 w = ec_cat(h, w, "<tr><td>premium</td><td>60</td><td class=\"pos\">" as *u8); w = ec_catn(h, w, gcash[0]); w = ec_cat(h, w, "</td></tr>\n" as *u8) 184 w = ec_cat(h, w, "<tr><td>mid-market</td><td>45</td><td class=\"pos\">" as *u8); w = ec_catn(h, w, gcash[1]); w = ec_cat(h, w, "</td></tr>\n" as *u8) 185 w = ec_cat(h, w, "<tr><td>discount</td><td>35</td><td class=\"pos\">" as *u8); w = ec_catn(h, w, gcash[2]); w = ec_cat(h, w, "</td></tr>\n" as *u8) 186 w = ec_cat(h, w, "</table>\n" as *u8) 187 w = ec_cat(h, w, "<p>At these inputs the premium price wins the year on margin &mdash; change the numbers and the winner changes. That's the game.</p></section>\n" as *u8) 188 189 // ===== R4: quality + brand ===== 190 w = ec_cat(h, w, "<section><h2>R4 &mdash; quality &amp; brand (why premium wins)</h2>\n" as *u8) 191 w = ec_cat(h, w, "<p>Customers weigh price, quality AND brand. A pricier product with better quality and brand can take MORE of the market than a cheap commodity &mdash; the heart of Capitalism Lab.</p>\n" as *u8) 192 let qpr: *i64 = (sys_mmap(16)) as *i64 193 qpr[0] = 40 194 qpr[1] = 60 195 let qql: *i64 = (sys_mmap(16)) as *i64 196 qql[0] = 0 197 qql[1] = 30 198 let qbr: *i64 = (sys_mmap(16)) as *i64 199 qbr[0] = 0 200 qbr[1] = 20 201 let qout: *i64 = (sys_mmap(16)) as *i64 202 nx_clab_split_qb(2, qpr, qql, qbr, 100, 1, 2, 1, 120, qout) 203 w = ec_cat(h, w, "<table><tr><th>Product</th><th>Price</th><th>Quality</th><th>Brand</th><th>Customers</th></tr>\n" as *u8) 204 w = ec_cat(h, w, "<tr><td>cheap commodity</td><td>40</td><td>0</td><td>0</td><td>" as *u8); w = ec_catn(h, w, qout[0]); w = ec_cat(h, w, "</td></tr>\n" as *u8) 205 w = ec_cat(h, w, "<tr><td>premium brand</td><td>60</td><td>30</td><td>20</td><td class=\"pos\">" as *u8); w = ec_catn(h, w, qout[1]); w = ec_cat(h, w, "</td></tr>\n" as *u8) 206 w = ec_cat(h, w, "</table>\n" as *u8) 207 w = ec_cat(h, w, "<p>The premium product costs MORE yet wins more customers.</p></section>\n" as *u8) 208 209 // ===== build status ===== 210 w = ec_cat(h, w, "<section><h2>Build status &mdash; from the hardware rung up</h2>\n" as *u8) 211 w = ec_cat(h, w, "<ul class=\"ladder\">\n" as *u8) 212 w = ec_cat(h, w, "<li class=\"done\">&#10003; R0 &mdash; economic atom: single-firm market (gate 15/15, sovereign)</li>\n" as *u8) 213 w = ec_cat(h, w, "<li class=\"done\">&#10003; R1 &mdash; multi-firm price competition (gate 20/20, sovereign)</li>\n" as *u8) 214 w = ec_cat(h, w, "<li class=\"done\">&#10003; P0 &mdash; this page is live: emit &rarr; push &rarr; verify loop</li>\n" as *u8) 215 w = ec_cat(h, w, "<li class=\"done\">&#10003; R2 &mdash; production / supply chains (gate 8/8)</li>\n" as *u8) 216 w = ec_cat(h, w, "<li class=\"done\">&#10003; R3 &mdash; tick loop + AI competitor + game config (gate 17/17)</li>\n" as *u8) 217 w = ec_cat(h, w, "<li class=\"done\">&#10003; R4 &mdash; quality + brand demand (gate 11/11)</li>\n" as *u8) 218 w = ec_cat(h, w, "<li class=\"todo\">&#9633; R5 &mdash; multiple products + categories</li>\n" as *u8) 219 w = ec_cat(h, w, "<li class=\"todo\">&#9633; R6 &mdash; cities + retail units + per-city demand (the map)</li>\n" as *u8) 220 w = ec_cat(h, w, "<li class=\"todo\">&#9633; R7 &mdash; firm finances: loans, debt, bankruptcy</li>\n" as *u8) 221 w = ec_cat(h, w, "<li class=\"todo\">&#9633; R8 &mdash; stock market + corporations + acquisitions</li>\n" as *u8) 222 w = ec_cat(h, w, "<li class=\"todo\">&#9633; then &mdash; interactive in-browser client + multiplayer; measured S-class census vs Capitalism Lab</li>\n" as *u8) 223 w = ec_cat(h, w, "</ul>\n" as *u8) 224 w = ec_cat(h, w, "<p class=\"stamp\">Honest scope: this is a live read-out of the sim so far, not yet the interactive game (that arrives at R4/R5). Numbers are real, computed on render.</p></section>\n" as *u8) 225 226 w = ec_cat(h, w, "</main>\n" as *u8) 227 w = ec_cat(h, w, "<footer>Sovereign Nishi stack &middot; sim: <code>nx_caplab_market</code> + <code>nx_caplab_compete</code> &middot; published via <code>nx_aw_push</code> &middot; nishifamily.com/econsim</footer>\n" as *u8) 228 w = ec_cat(h, w, "</body></html>\n" as *u8) 229 230 let fd: i64 = sys_openat_wr(EC_OUT, 0x1a4) 231 if fd < 0 { sys_write(2, "FATAL: cannot open web_assets/econsim.html\n" as *u8, 43); sys_exit(2); return 2 } 232 sys_write(fd, h, w) 233 sys_close(fd) 234 sys_write(1, "[nx_econsim_page] wrote econsim.html bytes=" as *u8, 43) 235 let nb: *u8 = sys_mmap(28) 236 var k2: i64 = 0 237 var m2: i64 = w 238 if m2 == 0 { nb[0] = 48 as u8; k2 = 1 } 239 while m2 > 0 { nb[k2] = (48 + (m2 % 10)) as u8; m2 = m2 / 10; k2 = k2 + 1 } 240 var qd: i64 = k2 - 1 241 while qd >= 0 { let o1: *u8 = sys_mmap(1); o1[0] = nb[qd]; sys_write(1, o1, 1); qd = qd - 1 } 242 sys_write(1, "\n" as *u8, 1) 243 sys_exit(0) 244 return 0 245}