<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wallstreetraiderwiki.com/index.php?action=history&amp;feed=atom&amp;title=Modding</id>
	<title>Modding - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wallstreetraiderwiki.com/index.php?action=history&amp;feed=atom&amp;title=Modding"/>
	<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;action=history"/>
	<updated>2026-07-29T10:18:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=10&amp;oldid=prev</id>
		<title>74.83.75.1 at 13:13, 17 May 2026</title>
		<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=10&amp;oldid=prev"/>
		<updated>2026-05-17T13:13:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:13, 17 May 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= Wall Street Raider - Modding Guide =&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= Wall Street Raider - Modding Guide =&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;A reference for everything you can mod in WSR with nothing but a text editor. The Electron frontend has &#039;&#039;&#039;no build step&#039;&#039;&#039; and the install ships with &amp;lt;code&amp;gt;asar: false&amp;lt;/code&amp;gt;, so every file under &amp;lt;code&amp;gt;resources/app/&amp;lt;/code&amp;gt; is a normal editable file. &#039;&#039;&#039;Edit, &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;restart&lt;/del&gt;, see your change.&#039;&#039;&#039;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;A reference for everything you can mod in WSR with nothing but a text editor. The Electron frontend has &#039;&#039;&#039;no build step&#039;&#039;&#039; and the install ships with &amp;lt;code&amp;gt;asar: false&amp;lt;/code&amp;gt;, so every file under &amp;lt;code&amp;gt;resources/app/&amp;lt;/code&amp;gt; is a normal editable file. &#039;&#039;&#039;Edit, &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;CTRL+R&lt;/ins&gt;, see your change.&#039;&#039;&#039;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;What you &amp;#039;&amp;#039;&amp;#039;can&amp;#039;t&amp;#039;&amp;#039;&amp;#039; mod without recompiling: the PowerBASIC engine (&amp;lt;code&amp;gt;wsr.exe&amp;lt;/code&amp;gt;), the C++ bridge (&amp;lt;code&amp;gt;ui.dll&amp;lt;/code&amp;gt;), and the binary &amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;.PRM&amp;lt;/code&amp;gt; files.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;What you &amp;#039;&amp;#039;&amp;#039;can&amp;#039;t&amp;#039;&amp;#039;&amp;#039; mod without recompiling: the PowerBASIC engine (&amp;lt;code&amp;gt;wsr.exe&amp;lt;/code&amp;gt;), the C++ bridge (&amp;lt;code&amp;gt;ui.dll&amp;lt;/code&amp;gt;), and the binary &amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;.PRM&amp;lt;/code&amp;gt; files.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>74.83.75.1</name></author>
	</entry>
	<entry>
		<id>https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=9&amp;oldid=prev</id>
		<title>74.83.75.1: /* For the WSR maintainer: Steamworks partner-site setup */</title>
		<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=9&amp;oldid=prev"/>
		<updated>2026-05-16T02:40:50Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;For the WSR maintainer: Steamworks partner-site setup&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 03:40, 16 May 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l944&quot;&gt;Line 944:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 944:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Tags are optional. Multiple tags are fine when a mod spans categories (e.g. a &amp;quot;1929 era&amp;quot; mod might tag &amp;lt;code&amp;gt;Theme&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Companies&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Assets&amp;lt;/code&amp;gt;).&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Tags are optional. Multiple tags are fine when a mod spans categories (e.g. a &amp;quot;1929 era&amp;quot; mod might tag &amp;lt;code&amp;gt;Theme&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Companies&amp;lt;/code&amp;gt; + &amp;lt;code&amp;gt;Assets&amp;lt;/code&amp;gt;).&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== For the WSR maintainer: Steamworks partner-site setup ===&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Workshop is configured for AppID &amp;lt;code&amp;gt;3525620&amp;lt;/code&amp;gt; (the public release / main build depot). The playtest AppID &amp;lt;code&amp;gt;4080310&amp;lt;/code&amp;gt; is separate and intentionally does not host Workshop content.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;One-time configuration on [https://partner.steamgames.com partner.steamgames.com] - &#039;&#039;&#039;every step matters and the order is significant&#039;&#039;&#039;. The two starred steps are the ones that burned us during initial setup:&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;App Admin &amp;amp;rarr; Workshop&#039;&#039;&#039; for AppID &amp;lt;code&amp;gt;3525620&amp;lt;/code&amp;gt;: set &#039;&#039;&#039;Workshop type&#039;&#039;&#039; to &#039;&#039;&#039;&quot;Ready-to-Use Content&quot;&#039;&#039;&#039; (checkbox &#039;&#039;&#039;&quot;Enable Ready-To-Use Content&quot;&#039;&#039;&#039;).&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Additional Configuration Options &amp;amp;rarr; ISteamUGC file transfer&#039;&#039;&#039;: check &#039;&#039;&#039;&quot;Enable ISteamUGC for file transfer&quot;&#039;&#039;&#039;. Without this, every &amp;lt;code&amp;gt;SubmitItemUpdate&amp;lt;/code&amp;gt; from the SDK returns &amp;lt;code&amp;gt;AccessDenied&amp;lt;/code&amp;gt;.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;* Steam Cloud quota&#039;&#039;&#039;: go to [https://partner.steamgames.com/apps/cloud/3525620 App Admin &amp;amp;rarr; Cloud Settings] and set &#039;&#039;&#039;Byte quota per user&#039;&#039;&#039; (at least &amp;lt;code&amp;gt;1073741824&amp;lt;/code&amp;gt; / 1 GB) and &#039;&#039;&#039;Number of files allowed per user&#039;&#039;&#039; (e.g. &amp;lt;code&amp;gt;100&amp;lt;/code&amp;gt;). Preview images are stored in Steam Cloud; if the quota is zero (the default), &amp;lt;code&amp;gt;SubmitItemUpdate&amp;lt;/code&amp;gt; returns &amp;lt;code&amp;gt;AccessDenied&amp;lt;/code&amp;gt; after the content upload reaches 100%. This step is barely documented but mandatory.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Tags&#039;&#039;&#039;: by default, Workshop accepts any tag the uploader sends. To restrict to a curated list (recommended once the Workshop has users), add a category under &#039;&#039;&#039;Ready-to-Use Item Tags&#039;&#039;&#039; with the seven tags from [[#Standard tags|§Standard tags]].&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Legal agreement&#039;&#039;&#039;: paste the Workshop Submission Agreement text below into the Workshop config page. Modders acknowledge it on first publish; Steam stores acceptance per-user per-app.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Visibility State&#039;&#039;&#039;: leave at &quot;Only Developers&quot; until you have at least one real Workshop item published (Steam blocks switching to &quot;Visible to Everyone&quot; until the checklist is complete, which requires one publicly visible item).&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;* Click the top-nav &quot;Publish&quot; tab &amp;amp;rarr; &quot;Prepare for Publishing&quot; &amp;amp;rarr; &quot;Publish to Steam&quot;&#039;&#039;&#039;. This is the step most people miss. Save buttons on individual config pages only write a draft to the partner-side DB. Until you Publish from the top-nav, Steam&#039;s live backend does not see any of your changes, and SDK calls will fail with &amp;lt;code&amp;gt;AccessDenied&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;Busy&amp;lt;/code&amp;gt; as if Workshop wasn&#039;t configured at all. &#039;&#039;&#039;Every config change requires a separate Publish push.&#039;&#039;&#039;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;After Publish: allow ~5 minutes for propagation, then test by publishing the [https://github.com/your-repo/wallstreetraider/tree/main/tools/test-mod-neon-bloomberg test mod] via the bundled uploader.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;==== Workshop Submission Agreement (copy verbatim into the partner site) ====&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;blockquote&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&#039;&#039;&#039;Wall Street Raider Workshop Submission Agreement&#039;&#039;&#039;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;By submitting an item (&quot;Submission&quot;) to the Wall Street Raider Steam Workshop, you confirm and agree that:&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Ownership / Originality.&#039;&#039;&#039; You are the sole author of the Submission, or have obtained all rights necessary to publish and license it. You will not submit content that infringes any third party&#039;s copyright, trademark, patent, trade secret, privacy, or publicity rights.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;License to Hackjack Games and Roninsoft.&#039;&#039;&#039; You grant Hackjack Games and Roninsoft (collectively, the &quot;Publisher&quot;) and other Wall Street Raider players a perpetual, worldwide, non-exclusive, royalty-free license to use, reproduce, modify, publish, distribute, publicly display, and create derivative works of the Submission for the purpose of operating, promoting, and improving Wall Street Raider and the Workshop.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;License to other Workshop users.&#039;&#039;&#039; You grant other Steam users a perpetual, worldwide, non-exclusive, royalty-free license to download, install, use, and modify the Submission for personal, non-commercial use in Wall Street Raider.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Content standards.&#039;&#039;&#039; Submissions must not contain unlawful, obscene, hateful, harassing, malicious, or otherwise objectionable content. Submissions must not include executable binaries that replace &amp;lt;code&amp;gt;wsr.exe&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ui.dll&amp;lt;/code&amp;gt;, malware, tracking code, or any mechanism that exfiltrates user data.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Steam Subscriber Agreement.&#039;&#039;&#039; Your Submission is also governed by the [https://store.steampowered.com/subscriber_agreement/ Steam Subscriber Agreement] and the [https://steamcommunity.com/workshop/workshoplegalagreement/ Steam Workshop Terms].&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Removal.&#039;&#039;&#039; The Publisher and Valve reserve the right to remove any Submission at any time for any reason, with or without notice. You may unpublish your own Submission at any time; existing subscribers may retain installed copies.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;No compensation.&#039;&#039;&#039; Submissions are unpaid. You are not entitled to any compensation, revenue share, or attribution beyond your Workshop author byline.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;# &#039;&#039;&#039;Indemnification.&#039;&#039;&#039; You agree to indemnify and hold harmless the Publisher and Valve from any claims arising from your Submission or your breach of this Agreement.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;By clicking &quot;Submit,&quot; you accept this Agreement.&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/blockquote&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Troubleshooting ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Troubleshooting ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>74.83.75.1</name></author>
	</entry>
	<entry>
		<id>https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=8&amp;oldid=prev</id>
		<title>74.83.75.1 at 02:40, 16 May 2026</title>
		<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=8&amp;oldid=prev"/>
		<updated>2026-05-16T02:40:16Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wallstreetraiderwiki.com/index.php?title=Modding&amp;amp;diff=8&amp;amp;oldid=7&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>74.83.75.1</name></author>
	</entry>
	<entry>
		<id>https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=7&amp;oldid=prev</id>
		<title>74.83.75.1 at 21:29, 15 May 2026</title>
		<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=7&amp;oldid=prev"/>
		<updated>2026-05-15T21:29:35Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wallstreetraiderwiki.com/index.php?title=Modding&amp;amp;diff=7&amp;amp;oldid=6&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>74.83.75.1</name></author>
	</entry>
	<entry>
		<id>https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=6&amp;oldid=prev</id>
		<title>74.83.75.1 at 12:16, 15 May 2026</title>
		<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=6&amp;oldid=prev"/>
		<updated>2026-05-15T12:16:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;https://wallstreetraiderwiki.com/index.php?title=Modding&amp;amp;diff=6&amp;amp;oldid=5&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>74.83.75.1</name></author>
	</entry>
	<entry>
		<id>https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=5&amp;oldid=prev</id>
		<title>74.83.75.1: Created page with &quot;= Wall Street Raider - Modding Guide =  This document describes &#039;&#039;&#039;everything you can mod today&#039;&#039;&#039; in Wall Street Raider, and exactly how to do it. It covers the practical, supported surfaces: the Electron frontend (code, styling, assets, help, translations, hints), the plain-text company-name database, the REST + WebSocket API, and the &#039;&#039;&#039;CustomData API&#039;&#039;&#039; - the one supported path for writing your own persistent data into a save file.  It does &#039;&#039;&#039;not&#039;&#039;&#039; cover modifying...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wallstreetraiderwiki.com/index.php?title=Modding&amp;diff=5&amp;oldid=prev"/>
		<updated>2026-05-15T11:25:21Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Wall Street Raider - Modding Guide =  This document describes &amp;#039;&amp;#039;&amp;#039;everything you can mod today&amp;#039;&amp;#039;&amp;#039; in Wall Street Raider, and exactly how to do it. It covers the practical, supported surfaces: the Electron frontend (code, styling, assets, help, translations, hints), the plain-text company-name database, the REST + WebSocket API, and the &amp;#039;&amp;#039;&amp;#039;CustomData API&amp;#039;&amp;#039;&amp;#039; - the one supported path for writing your own persistent data into a save file.  It does &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; cover modifying...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Wall Street Raider - Modding Guide =&lt;br /&gt;
&lt;br /&gt;
This document describes &amp;#039;&amp;#039;&amp;#039;everything you can mod today&amp;#039;&amp;#039;&amp;#039; in Wall Street Raider, and exactly how to do it. It covers the practical, supported surfaces: the Electron frontend (code, styling, assets, help, translations, hints), the plain-text company-name database, the REST + WebSocket API, and the &amp;#039;&amp;#039;&amp;#039;CustomData API&amp;#039;&amp;#039;&amp;#039; - the one supported path for writing your own persistent data into a save file.&lt;br /&gt;
&lt;br /&gt;
It does &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; cover modifying the PowerBASIC game engine itself (the simulation logic), because that requires recompiling &amp;lt;code&amp;gt;wsr.exe&amp;lt;/code&amp;gt; from source with a PowerBASIC 9.80 compiler. Everything below is doable with nothing more than a text editor.&lt;br /&gt;
&lt;br /&gt;
== How the game is built (why modding is easy) ==&lt;br /&gt;
&lt;br /&gt;
WSR is three layers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
PowerBASIC engine  →  C++ bridge DLL (REST + WebSocket server)  →  Electron UI&lt;br /&gt;
   wsr.exe              ui.dll                                      everything you see&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The crucial fact for modders: &amp;#039;&amp;#039;&amp;#039;the Electron frontend has no build step.&amp;#039;&amp;#039;&amp;#039; The UI is plain ES modules, plain CSS, and plain asset files loaded directly from disk at runtime. There is no webpack, no transpile, no bundling. The app is packaged with &amp;lt;code&amp;gt;asar: false&amp;lt;/code&amp;gt;, which means after installation every file is still a normal editable file on disk - nothing is archived or compressed.&lt;br /&gt;
&lt;br /&gt;
That means: &amp;#039;&amp;#039;&amp;#039;edit a file, restart the game, see your change.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Where the files live ==&lt;br /&gt;
&lt;br /&gt;
=== During development (running from source) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
electron/&lt;br /&gt;
├── index.html            # app entry point&lt;br /&gt;
├── main.js               # Electron main process&lt;br /&gt;
├── js/                   # all frontend code&lt;br /&gt;
├── css/                  # all styling&lt;br /&gt;
├── assets/               # images, videos, icons, help&lt;br /&gt;
└── ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In an installed / Steam copy ===&lt;br /&gt;
&lt;br /&gt;
After packing, everything lands under the install directory in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;amp;lt;install&amp;amp;gt;/resources/app/&lt;br /&gt;
├── index.html&lt;br /&gt;
├── main.js&lt;br /&gt;
├── js/                   # ← editable&lt;br /&gt;
├── css/                  # ← editable&lt;br /&gt;
├── assets/               # ← editable&lt;br /&gt;
├── wsr.exe               # game engine (binary, not moddable without source)&lt;br /&gt;
├── ui.dll                # bridge (binary, not moddable without source)&lt;br /&gt;
├── CORPNAME.DAT          # ← editable plain-text company database&lt;br /&gt;
├── *.DAT / *.PRM         # other game data (mostly binary/encoded)&lt;br /&gt;
└── ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resources/app/js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;resources/app/css&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;resources/app/assets&amp;lt;/code&amp;gt; are copied verbatim from the &amp;lt;code&amp;gt;electron/&amp;lt;/code&amp;gt; source tree at pack time (see the &amp;lt;code&amp;gt;extraFiles&amp;lt;/code&amp;gt; block in &amp;lt;code&amp;gt;electron/package.json&amp;lt;/code&amp;gt;). Editing them in an installed copy works exactly the same as editing them in source.&lt;br /&gt;
&lt;br /&gt;
{{Note|Back up any file before you edit it. A Steam &amp;quot;verify integrity of game files&amp;quot; will revert your changes - that is also your safety net.}}&lt;br /&gt;
&lt;br /&gt;
== What you can mod ==&lt;br /&gt;
&lt;br /&gt;
=== Frontend code - &amp;lt;code&amp;gt;resources/app/js/&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The entire UI is here, as ES modules. Highlights:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Path !! What it is&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/app.js&amp;lt;/code&amp;gt; || Preact root component, WebSocket wiring, gameState polling, hotkey handling&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/api.js&amp;lt;/code&amp;gt; || REST/WebSocket client, the Zustand &amp;lt;code&amp;gt;gameStore&amp;lt;/code&amp;gt;, all constants, the command map&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/components/&amp;lt;/code&amp;gt; || 100+ Preact components - every panel, modal, table, tab&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/hooks/&amp;lt;/code&amp;gt; || Reusable Preact hooks (&amp;lt;code&amp;gt;useCookie&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;useInterval&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;usePanelSelection&amp;lt;/code&amp;gt;, …)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/services/&amp;lt;/code&amp;gt; || Logic helpers (e.g. &amp;lt;code&amp;gt;hintMatcher.js&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/utils/&amp;lt;/code&amp;gt; || Misc utilities&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/icons.js&amp;lt;/code&amp;gt; || Inline SVG icon definitions&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;js/debug-log.js&amp;lt;/code&amp;gt; || Frontend logging&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Components use &amp;#039;&amp;#039;&amp;#039;Preact + htm&amp;#039;&amp;#039;&amp;#039; (JSX-like template literals, no compile step) and &amp;#039;&amp;#039;&amp;#039;Zustand&amp;#039;&amp;#039;&amp;#039; for state. A minimal component looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import { html, Component } from &amp;#039;../lib/preact.standalone.module.js&amp;#039;;&lt;br /&gt;
import { useGameStore } from &amp;#039;../api.js&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
export function MyPanel() {&lt;br /&gt;
    const cash = useGameStore(s =&amp;gt; s.gameState.cash);&lt;br /&gt;
    return html`&amp;amp;lt;div class=&amp;quot;p-4&amp;quot;&amp;amp;gt;Cash: ${cash}&amp;amp;lt;/div&amp;amp;gt;`;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can freely:&lt;br /&gt;
* Change layout, text, colors, behavior of any existing component.&lt;br /&gt;
* Add brand-new components and wire them into &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; or any parent.&lt;br /&gt;
* Add new hotkeys (search &amp;lt;code&amp;gt;hotkey&amp;lt;/code&amp;gt; across &amp;lt;code&amp;gt;js/&amp;lt;/code&amp;gt; - the handling lives in &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;HotkeyButtonBar.js&amp;lt;/code&amp;gt;).&lt;br /&gt;
* Add new derived/computed displays from &amp;lt;code&amp;gt;gameState&amp;lt;/code&amp;gt; (see [[#The gameState - everything you can read|§6]]).&lt;br /&gt;
* Add new buttons that call any API endpoint (see [[#The API - everything you can make the game do|§5]]).&lt;br /&gt;
&lt;br /&gt;
Libraries are vendored in &amp;lt;code&amp;gt;js/lib/&amp;lt;/code&amp;gt; (&amp;lt;code&amp;gt;preact.standalone.module.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;zustand.module.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tailwind.module.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;fast-json-patch.module.js&amp;lt;/code&amp;gt;) - no npm install needed to develop against them.&lt;br /&gt;
&lt;br /&gt;
=== Styling - &amp;lt;code&amp;gt;resources/app/css/&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
CSS is modular and loaded at runtime. The structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
css/&lt;br /&gt;
├── style.css             # the single file index.html links - imports the rest&lt;br /&gt;
├── base.css              # resets / base element styles&lt;br /&gt;
├── variables.css         # CSS custom properties (THE place for theme colors)&lt;br /&gt;
├── theme.css             # theme layer&lt;br /&gt;
├── layout.css            # app layout&lt;br /&gt;
├── chart-styles.js       # chart styling injected as JS&lt;br /&gt;
├── components/           # buttons, dropdown, forms, modals, panels, tables, tabs&lt;br /&gt;
├── features/             # assets, calculator, help, market, menu, notes, ticker, tutorial&lt;br /&gt;
└── pages/                # game, main-menu, quotes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tailwind utility classes are also available (loaded via &amp;lt;code&amp;gt;js/lib/tailwind.module.js&amp;lt;/code&amp;gt;), so most components use Tailwind utilities inline plus the modular CSS for anything custom.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;To re-theme the game&amp;#039;&amp;#039;&amp;#039;, start with &amp;lt;code&amp;gt;css/variables.css&amp;lt;/code&amp;gt; - it defines the color palette as CSS custom properties. Override those and the whole app follows. For finer control, edit the per-component and per-feature files.&lt;br /&gt;
&lt;br /&gt;
=== Assets - &amp;lt;code&amp;gt;resources/app/assets/&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
All images, videos, icons, and the loading animation:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Asset type !! Files&lt;br /&gt;
|-&lt;br /&gt;
| Background videos || The many &amp;lt;code&amp;gt;*.mp4&amp;lt;/code&amp;gt; files (Wall Street footage, industry b-roll, etc.)&lt;br /&gt;
|-&lt;br /&gt;
| Event images || &amp;lt;code&amp;gt;blackswan.png&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ponzi.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;soupline.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;zimbabwe.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;helicopter.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;yacht.mp4&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Branding / logos || &amp;lt;code&amp;gt;wallstreetraider_logo.png&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;hackjackgames_logo.png&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;roninsoft_logo.png&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Social widgets || &amp;lt;code&amp;gt;discord-widget.png&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;reddit-widget.png&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Loading spinner || &amp;lt;code&amp;gt;loading.gif&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| App icon || &amp;lt;code&amp;gt;wsr.ico&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Replace any of these with a same-named file of the same type to reskin the game. (Keep filenames identical - components reference them by name.)&lt;br /&gt;
&lt;br /&gt;
=== Help content - &amp;lt;code&amp;gt;resources/app/assets/help/&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The in-game manual is &amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;wsrbook.htm&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039; - a single ~1 MB HTML file. It is plain HTML; edit it directly to rewrite, correct, or extend the manual. The &amp;lt;code&amp;gt;*.jpg&amp;lt;/code&amp;gt; files in the same folder are diagrams embedded by the manual (&amp;lt;code&amp;gt;advanopt.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;alerts.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;automate.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;buyloans.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;capcont.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;treasury.jpg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;rlogotxt.jpg&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;electron/UI_HELP_CATALOG.txt&amp;lt;/code&amp;gt; is a developer reference catalog of help sections - useful to read when navigating the manual.&lt;br /&gt;
&lt;br /&gt;
=== Translations / locales - &amp;lt;code&amp;gt;resources/app/js/locale/&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
WSR ships an English base plus full translation dictionaries. You can add a new language with &amp;#039;&amp;#039;&amp;#039;no code changes to the engine&amp;#039;&amp;#039;&amp;#039; - it is pure data.&lt;br /&gt;
&lt;br /&gt;
How it works (&amp;lt;code&amp;gt;js/locale/localeManager.js&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;LANGUAGE_OPTIONS&amp;lt;/code&amp;gt; maps a locale code → &amp;lt;code&amp;gt;{ name, dictionary, warning? }&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Each &amp;lt;code&amp;gt;dictionary&amp;lt;/code&amp;gt; is a flat object: &amp;lt;code&amp;gt;{ &amp;quot;English source string&amp;quot;: &amp;quot;translated string&amp;quot;, … }&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A &amp;lt;code&amp;gt;translator&amp;lt;/code&amp;gt; does runtime lookup/replacement on UI strings.&lt;br /&gt;
* Existing locale files: &amp;lt;code&amp;gt;zh-CN.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;es-419.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ja-JP.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;pt-BR.js&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ru-RU.js&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To add or improve a language:&lt;br /&gt;
&lt;br /&gt;
# Create &amp;lt;code&amp;gt;js/locale/&amp;amp;lt;your-locale&amp;amp;gt;.js&amp;lt;/code&amp;gt; exporting a dictionary object, e.g.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
export const frFR = {&lt;br /&gt;
    &amp;quot;New Game&amp;quot;: &amp;quot;Nouvelle partie&amp;quot;,&lt;br /&gt;
    &amp;quot;Buy Stock&amp;quot;: &amp;quot;Acheter des actions&amp;quot;,&lt;br /&gt;
    // … one entry per source string you want translated&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# In &amp;lt;code&amp;gt;js/locale/localeManager.js&amp;lt;/code&amp;gt;, import it and add an entry to &amp;lt;code&amp;gt;LANGUAGE_OPTIONS&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import { frFR } from &amp;#039;./fr-FR.js&amp;#039;;&lt;br /&gt;
// …&lt;br /&gt;
&amp;#039;fr-FR&amp;#039;: { name: &amp;#039;Français&amp;#039;, dictionary: frFR },&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
# The chosen locale is persisted by the engine (in &amp;lt;code&amp;gt;CFIG.WSR&amp;lt;/code&amp;gt;) and exposed as &amp;lt;code&amp;gt;gameState.locale&amp;lt;/code&amp;gt;; the UI switches via the &amp;lt;code&amp;gt;/set_locale&amp;lt;/code&amp;gt; endpoint.&lt;br /&gt;
&lt;br /&gt;
{{Note|Strings missing from the dictionary simply fall through to English, so a partial translation is perfectly valid.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;*-backup-*&amp;lt;/code&amp;gt; files in the locale folder are timestamped editing backups and are git-ignored - ignore them.}}&lt;br /&gt;
&lt;br /&gt;
=== In-game hints - &amp;lt;code&amp;gt;resources/app/js/data/hints/&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
The contextual hint system is data-driven. Hint files are grouped by view:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
js/data/hints/&lt;br /&gt;
├── index.js        # aggregates all hint sets&lt;br /&gt;
├── global.js       # fallback hints&lt;br /&gt;
├── company.js      # hints while viewing a company&lt;br /&gt;
├── industry.js&lt;br /&gt;
├── market.js&lt;br /&gt;
├── modals.js&lt;br /&gt;
├── player.js&lt;br /&gt;
├── portfolio.js&lt;br /&gt;
└── swap-info-text.js&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each file exports an array of hint objects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    id: &amp;#039;company-overview-controlled-etf&amp;#039;,&lt;br /&gt;
    match: { view: &amp;#039;company&amp;#039;, tab: &amp;#039;overview&amp;#039;, controls: true, entityKind: &amp;#039;mutual-fund&amp;#039; },&lt;br /&gt;
    title: &amp;#039;Advising an ETF&amp;#039;,&lt;br /&gt;
    content: `&amp;amp;lt;p&amp;amp;gt;HTML body shown to the player…&amp;amp;lt;/p&amp;amp;gt;`,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The matcher (&amp;lt;code&amp;gt;js/services/hintMatcher.js&amp;lt;/code&amp;gt;) picks the most specific matching hint for the current screen. You can rewrite hint text, add new hints, or retarget &amp;lt;code&amp;gt;match&amp;lt;/code&amp;gt; conditions - all without touching engine code.&lt;br /&gt;
&lt;br /&gt;
=== Company names - &amp;lt;code&amp;gt;CORPNAME.DAT&amp;lt;/code&amp;gt; (plain text, directly editable) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;resources/app/CORPNAME.DAT&amp;lt;/code&amp;gt; is the company-name database, and unlike most &amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt; files it is &amp;#039;&amp;#039;&amp;#039;plain pipe-delimited text&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0011|00|JPB  |  J.P. MULLINS WALL ST. BANK |&lt;br /&gt;
0012|00|UBC  |  URBAN BANCORP |&lt;br /&gt;
0015|26|KYOB |  KYOTO BANK |&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Columns: &amp;lt;code&amp;gt;company ID | nation code | ticker symbol | company name&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
It is read by the engine&amp;#039;s &amp;lt;code&amp;gt;GetCorpNames&amp;lt;/code&amp;gt; routine at &amp;#039;&amp;#039;&amp;#039;new-game&amp;#039;&amp;#039;&amp;#039; time, so edits take effect on the next new game (not on already-saved games). You can rename companies, change ticker symbols, or change a company&amp;#039;s home nation.&lt;br /&gt;
&lt;br /&gt;
Keep the format exact: 4-digit zero-padded ID, 2-digit nation code, the fixed-width symbol field, and the surrounding &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; delimiters and spacing. &amp;lt;code&amp;gt;CORPNAME.ORI&amp;lt;/code&amp;gt; is the pristine original - keep it as your reference/backup.&lt;br /&gt;
&lt;br /&gt;
=== Other game-data files (limited / not practical) ===&lt;br /&gt;
&lt;br /&gt;
These ship in &amp;lt;code&amp;gt;resources/app/&amp;lt;/code&amp;gt; but are &amp;#039;&amp;#039;&amp;#039;not practically moddable&amp;#039;&amp;#039;&amp;#039; without the original tooling:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! File(s) !! Content !! Why limited&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;QUOTEWSR.DAT&amp;lt;/code&amp;gt; || &amp;quot;Quote of the day&amp;quot; text || Encrypted/encoded; plaintext source is &amp;lt;code&amp;gt;quotehs.prm&amp;lt;/code&amp;gt; but the engine reads the encoded &amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;MSCNEWS.DAT&amp;lt;/code&amp;gt; || News &amp;amp; scenario headline text (hundreds of paragraphs) || Encoded; &amp;lt;code&amp;gt;MSCNEWS.PRM&amp;lt;/code&amp;gt; is a near-plaintext source but the engine reads the encoded &amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;scenwin1-4.prm&amp;lt;/code&amp;gt; || Scenario window text || Engine-internal format&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;GAME01.DAT … GAME50.DAT&amp;lt;/code&amp;gt; || Save slots / scenario data || Proprietary binary save format&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;WSR101.DAT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;REGINFO.DAT&amp;lt;/code&amp;gt;, etc. || Engine data || Proprietary binary&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Treat these as read-only. (Company names are the one genuinely editable game-data file - see [[#Company names - CORPNAME.DAT (plain text, directly editable)|above]].)&lt;br /&gt;
&lt;br /&gt;
== The runtime: how the UI talks to the engine ==&lt;br /&gt;
&lt;br /&gt;
When &amp;lt;code&amp;gt;wsr.exe&amp;lt;/code&amp;gt; starts, &amp;lt;code&amp;gt;ui.dll&amp;lt;/code&amp;gt; binds a &amp;#039;&amp;#039;&amp;#039;REST server&amp;#039;&amp;#039;&amp;#039; and a &amp;#039;&amp;#039;&amp;#039;WebSocket server&amp;#039;&amp;#039;&amp;#039; on OS-assigned ephemeral ports, and writes them to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
%LOCALAPPDATA%\Wall Street Raider\runtime.json&lt;br /&gt;
{ &amp;quot;pid&amp;quot;: 12345, &amp;quot;rest_port&amp;quot;: 54321, &amp;quot;ws_port&amp;quot;: 54322 }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Electron&amp;#039;s main process reads that file and hands the ports to the renderer via the &amp;lt;code&amp;gt;bridge-ports&amp;lt;/code&amp;gt; IPC message.&lt;br /&gt;
* &amp;lt;code&amp;gt;js/api.js&amp;lt;/code&amp;gt; builds &amp;lt;code&amp;gt;http://127.0.0.1:&amp;amp;lt;rest_port&amp;amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ws://127.0.0.1:&amp;amp;lt;ws_port&amp;amp;gt;&amp;lt;/code&amp;gt; from it.&lt;br /&gt;
* The &amp;#039;&amp;#039;&amp;#039;WebSocket&amp;#039;&amp;#039;&amp;#039; pushes game-state updates (full snapshot on connect, then JSON-patch diffs on &amp;lt;code&amp;gt;/game_state_patch&amp;lt;/code&amp;gt;). When WS is connected, HTTP polling is suspended; if WS drops, &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt; falls back to polling &amp;lt;code&amp;gt;GET /gamestate&amp;lt;/code&amp;gt; (200 ms on the menu, 50 ms in-game).&lt;br /&gt;
&lt;br /&gt;
For a mod, you almost never touch this plumbing directly - you call the functions in &amp;lt;code&amp;gt;api.js&amp;lt;/code&amp;gt; and read from the &amp;lt;code&amp;gt;gameStore&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== The API - everything you can make the game do ==&lt;br /&gt;
&lt;br /&gt;
All state-changing actions go through a fixed set of named REST endpoints, each of which the bridge turns into a typed engine event. &amp;#039;&amp;#039;&amp;#039;There is no generic &amp;quot;run arbitrary command&amp;quot; endpoint&amp;#039;&amp;#039;&amp;#039; - you can only do what an endpoint exists for. The good news: there are ~150 of them, covering every player action in the game.&lt;br /&gt;
&lt;br /&gt;
=== Calling the API from a mod ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;js/api.js&amp;lt;/code&amp;gt; already wraps every endpoint in a named async function. Import and call:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import * as api from &amp;#039;../api.js&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
await api.buyStock(companyId);            // buy&lt;br /&gt;
await api.setDividend(actingAsId);        // open the set-dividend flow&lt;br /&gt;
await api.merger(targetId, actingAsId);   // start a merger&lt;br /&gt;
await api.cheatAddCash();                 // cheat menu: add cash&lt;br /&gt;
const state = await api.getGameState();   // full state snapshot&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Under the hood there are four request shapes (also exported, if you need to hit an endpoint that has no named wrapper yet):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Helper !! Body sent !! Use&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;postNoArg(path)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;{}&amp;lt;/code&amp;gt; || actions with no parameter&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;postIdArg(path, id)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;{ id }&amp;lt;/code&amp;gt; || actions on a specific entity/slot&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;postIdArgWithActingAs(path, id, actingAsId)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;{ id, intParam2? }&amp;lt;/code&amp;gt; || most corporate/trade actions; &amp;lt;code&amp;gt;actingAsId&amp;lt;/code&amp;gt; runs the action as a company you control&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;postOptionsTradeWithActingAs(path, id, actingAsId, underlyingId)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;{ id, intParam2?, underlyingId? }&amp;lt;/code&amp;gt; || options trades&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;postStringArg(path, str)&amp;lt;/code&amp;gt; || &amp;lt;code&amp;gt;{ str }&amp;lt;/code&amp;gt; || actions taking a string (e.g. save-as filename)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;getJSON(path)&amp;lt;/code&amp;gt; || - || &amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; endpoints&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;actingAsId&amp;lt;/code&amp;gt; parameter is important: passing the ID of a company you control makes the engine execute the action &amp;#039;&amp;#039;as that company&amp;#039;&amp;#039; (e.g. have a subsidiary buy stock), then restore. &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; means &amp;quot;as the player.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Endpoint reference ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Read (GET):&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Endpoint !! Returns&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/status&amp;lt;/code&amp;gt; || health check&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/gamestate&amp;lt;/code&amp;gt; || full game-state JSON (see [[#The gameState - everything you can read|§6]])&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/quote&amp;lt;/code&amp;gt; || quote of the day&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/asset_chart&amp;lt;/code&amp;gt; || price history for an asset&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/database_data&amp;lt;/code&amp;gt; || database/search dataset&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/ownership_tree&amp;lt;/code&amp;gt; || corporate ownership tree&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;/subsidiaries_tree&amp;lt;/code&amp;gt; || subsidiary tree&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Game / session control:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/newgame&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/loadgame&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/load_specific_save&amp;lt;/code&amp;gt; (str), &amp;lt;code&amp;gt;/savegame&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/savegameas&amp;lt;/code&amp;gt; (str), &amp;lt;code&amp;gt;/exit_game&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/check_scoreboard&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/start_ticker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/run_ticker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/stop_ticker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_ticker_speed&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/ticker_advance&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/clear_event_string&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/splash_screen_played&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Trading - stocks &amp;amp; bonds:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/buy_stock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_stock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/short_stock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cover_short_stock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_corporate_bond&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_corporate_bond&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_long_govt_bonds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_long_govt_bonds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_short_govt_bonds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_short_govt_bonds&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Trading - commodities &amp;amp; crypto:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/buy_commodity_futures&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_commodity_futures&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/close_long_commodity_futures_by_slot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/short_commodity_futures&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cover_short_commodity_futures&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cover_short_commodity_futures_by_slot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_physical_commodity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_physical_commodity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_physical_crypto&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_physical_crypto&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_crypto_futures&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_crypto_futures&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Trading - options:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/buy_calls&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_calls&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_puts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_puts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/advanced_options_trading&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/exercise_call_options_early&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/exercise_put_options_early&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Corporate management:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/prepay_taxes&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/elect_ceo&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/resign_as_ceo&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/change_managers&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_dividend&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_productivity&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_growth_rate&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/restructure&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_corporate_assets&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_corporate_assets&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/offer_corporate_assets_for_sale&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/view_for_sale_items&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_subsidiary_stock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/rebrand&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/toggle_company_autopilot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/toggle_global_autopilot&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/become_etf_advisor&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_advisory_fee&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/decrease_earnings&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/increase_earnings&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;M&amp;amp;A / corporate finance:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/merger&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/greenmail&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/lbo&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/startup&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/capital_contribution&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/public_stock_offering&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/private_stock_offering&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/issue_new_corp_bonds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/redeem_corp_bonds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/extraordinary_dividend&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/tax_free_liquidation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/taxable_liquidation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/spin_off&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/split_stock&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/reverse_split_stock&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Banking / loans / swaps:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/borrow_money&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/repay_loan&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/advance_funds&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/call_in_advance&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/interest_rate_swaps&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/view_swap_details&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/terminate_swap&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_bank_allocation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/trade_tbills&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/list_bank_loans&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/change_bank&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/call_in_loan&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_business_loans&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_business_loan&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_consumer_loans&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_consumer_loans&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_prime_mortgages&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_prime_mortgages&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/buy_subprime_mortgages&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sell_subprime_mortgages&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/list_etfs&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/freeze_all_loans&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/freeze_loan&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Legal / dirty tricks:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/change_law_firm&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/antitrust_lawsuit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/harrassing_lawsuit&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/spread_rumors&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Reports / views / navigation:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/set_active_ui_report&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/set_view_asset&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/set_view_industry&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/database_search&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/clear_chart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/growth_throttle&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/clear_stream_list&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/fill_stream_list&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/toggle_streaming_quote&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/nav_back&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/nav_forward&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/nav_clear&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/nav_goto&amp;lt;/code&amp;gt; (id), plus the market-report triggers &amp;lt;code&amp;gt;/view_current_interest_rates&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/whos_ahead&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/db_research_tool&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/economic_stats&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/most_cash_report&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/largest_market_cap&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/largest_tax_losses&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/industry_summary&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/industry_projections&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/view_corp_assets_for_sale&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Settings (toggles):&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/supp_earn_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/currency_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/supp_warn_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/suppress_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/autosave_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/exercise_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/sweep_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/makedelivery_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/takedelivery_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/tooltips_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/shareholdergraph_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/disablehotkeys_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/autoadd_select&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/set_chart_type&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/set_locale&amp;lt;/code&amp;gt; (str).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cheat menu:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/cheat_disable&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cheat_disable_lawsuits&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cheat_merger_info&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cheat_earnings_info&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/cheat_add_cash&amp;lt;/code&amp;gt;. (These are fixed-function - e.g. &amp;lt;code&amp;gt;/cheat_add_cash&amp;lt;/code&amp;gt; adds a preset amount; there is no &amp;quot;set cash to N&amp;quot; endpoint.)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Modals:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/close_modal&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/modal_result&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tutorial:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/set_tutorial_step&amp;lt;/code&amp;gt; (id), &amp;lt;code&amp;gt;/set_tutorial_enabled&amp;lt;/code&amp;gt; (id).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Price alerts:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/create_price_alert&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/show_price_alerts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/delete_price_alert&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;CustomData:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;/set_custom_data&amp;lt;/code&amp;gt; - see [[#The CustomData API - your persistent storage|§7]].&lt;br /&gt;
&lt;br /&gt;
{{Note|&amp;lt;code&amp;gt;js/api.js&amp;lt;/code&amp;gt; also exports useful &amp;#039;&amp;#039;&amp;#039;ID constants&amp;#039;&amp;#039;&amp;#039; so you don&amp;#039;t hardcode magic numbers: entity IDs (&amp;lt;code&amp;gt;HUMAN1_ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;COMPUTER1_ID&amp;lt;/code&amp;gt;, …), industry indices (&amp;lt;code&amp;gt;BANK_IND&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;INSURANCE_IND&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ETF_IND&amp;lt;/code&amp;gt;, …), special asset IDs (&amp;lt;code&amp;gt;OIL_ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GOLD_ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BITCOIN_ID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;PRIME_RATE_ID&amp;lt;/code&amp;gt;, …), and the &amp;lt;code&amp;gt;UI_*&amp;lt;/code&amp;gt; report IDs used with &amp;lt;code&amp;gt;/set_active_ui_report&amp;lt;/code&amp;gt;.}}&lt;br /&gt;
&lt;br /&gt;
== The gameState - everything you can read ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;GET /gamestate&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;api.getGameState()&amp;lt;/code&amp;gt;, or the live &amp;lt;code&amp;gt;gameStore&amp;lt;/code&amp;gt;) returns a single JSON object - roughly 90 top-level fields - that is the complete read model of the game. In a component, subscribe to just the fields you need so you only re-render on those:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import { useGameStore } from &amp;#039;../api.js&amp;#039;;&lt;br /&gt;
const cash = useGameStore(s =&amp;gt; s.gameState.cash);&lt;br /&gt;
const year = useGameStore(s =&amp;gt; s.gameState.currentYear);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Major fields include:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Player:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;cash&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;otherAssets&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;totalAssets&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;totalDebt&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;netWorth&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;playerId&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;playerName&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;chairedCompanyId&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Clock / session:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;currentYear&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;currentQuarter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;currentMonth&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;currentDay&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;currentTime&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;nextEarningsDate&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;gameLoaded&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;gameOver&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;readyToRestart&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;isTickerRunning&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tickSpeed&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;splashScreenPlayed&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Active selection:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;activeEntityNum&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;activeEntityName&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;activeEntitySymbol&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;activeIndustryNum&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;activeIndustryId&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;actingAsId&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;actingAsName&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;actingAsSymbol&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;actingAsIndustryId&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;actingAs&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Modal state:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;modalType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;modalText&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;modalTitle&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;modalDefault&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;modalFilter&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Collections:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;allCompanies&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;allPlayers&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;allSecurities&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;allIndustries&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;controlledCompanies&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tickerQueue&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;streamingQuotesList&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;newsHeadlines&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;trendingNews&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;navHistory&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;navPointerIndex&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Active entity detail:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;activeEntityData&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;activeEntityFinancials&amp;lt;/code&amp;gt; (a deep object: cash, assets, debt, equity, EPS, cash-flow, etc.), &amp;lt;code&amp;gt;activeEntityPlayerFinancials&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;financialProfile&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cashflowProjection&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;portfolio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;portHoldings&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;swapsPortfolio&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;optionsList&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;commodityList&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;shareholdersList&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;researchReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;advisorySummary&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;earningsReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;advances&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;loansReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;myCorporationsReport&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Market reports:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;whoOwns*Report&amp;lt;/code&amp;gt; (futures, physical commodities, options, swaps, stocks, investment contracts), &amp;lt;code&amp;gt;industrySummaryReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;industryProjectionReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;industryGrowthRatesReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mostMarketShareReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mostTaxLossReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mostCashReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;mostMarketCapReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;economicDataReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;interestRatesReport&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;whosAheadReport&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Settings:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;suppEarnSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;suppWarnSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;supPopupSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;autosaveSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;exerciseItSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;sweepSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;makeDeliverySetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;takeDeliverySetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tooltipsSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;shareholderGraphSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;unethicalSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;disableHotkeysSetting&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;chartType&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;locale&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Tutorial / misc:&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;tutorialEnabled&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tutorialStep&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;alerts&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;frozenAllLoans&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;dlrSign&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;euro&amp;lt;/code&amp;gt;, and &amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;customData&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039; (see [[#The CustomData API - your persistent storage|§7]]).&lt;br /&gt;
&lt;br /&gt;
The exact shape can change between versions - the authoritative move is to &amp;lt;code&amp;gt;GET /gamestate&amp;lt;/code&amp;gt; from a running game and inspect it. (&amp;lt;code&amp;gt;Ctrl+Shift+I&amp;lt;/code&amp;gt; opens DevTools; &amp;lt;code&amp;gt;gameStore.getState().gameState&amp;lt;/code&amp;gt; in the console dumps the live object.)&lt;br /&gt;
&lt;br /&gt;
== The CustomData API - your persistent storage ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;customData&amp;lt;/code&amp;gt; is a free-form JSON object that &amp;#039;&amp;#039;&amp;#039;rides along inside the save file&amp;#039;&amp;#039;&amp;#039;. The engine never reads it for simulation - it just stores it verbatim, writes it into the &amp;lt;code&amp;gt;.WSR&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt; save on save, and restores it on load. It is exposed back to you on every &amp;lt;code&amp;gt;gameState&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;gameState.customData&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This is the supported way for a mod to persist its own state per-save.&lt;br /&gt;
&lt;br /&gt;
=== Reading ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import { useGameStore } from &amp;#039;../api.js&amp;#039;;&lt;br /&gt;
const customData = useGameStore(s =&amp;gt; s.gameState?.customData ?? {});&lt;br /&gt;
const myStuff = customData.myModKey;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Writing ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import { setCustomData } from &amp;#039;../api.js&amp;#039;;&lt;br /&gt;
await setCustomData({ myModKey: { highScore: 42, notes: &amp;#039;hello&amp;#039; } });&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important semantics:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Shallow merge.&amp;#039;&amp;#039;&amp;#039; &amp;lt;code&amp;gt;POST /set_custom_data&amp;lt;/code&amp;gt; merges your object into the existing &amp;lt;code&amp;gt;customData&amp;lt;/code&amp;gt; at the &amp;#039;&amp;#039;&amp;#039;top level&amp;#039;&amp;#039;&amp;#039; - incoming top-level keys overwrite, other keys are preserved. So namespace your data under one top-level key (e.g. &amp;lt;code&amp;gt;myModKey&amp;lt;/code&amp;gt;) and write that whole sub-object each time.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;It round-trips.&amp;#039;&amp;#039;&amp;#039; After you write, the new value comes back on the next &amp;lt;code&amp;gt;gameState&amp;lt;/code&amp;gt; broadcast as &amp;lt;code&amp;gt;gameState.customData&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;It is inert.&amp;#039;&amp;#039;&amp;#039; The engine does not validate, interpret, or simulate on it. It is pure storage. It cannot be used to change cash, prices, or any engine value - for that you must use the action endpoints in [[#The API - everything you can make the game do|§5]].&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;It is per-save.&amp;#039;&amp;#039;&amp;#039; It is saved and loaded with the game; a fresh &amp;quot;New Game&amp;quot; starts with empty &amp;lt;code&amp;gt;customData&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Keys already in use by the base game ===&lt;br /&gt;
&lt;br /&gt;
The stock UI already stores a few things in &amp;lt;code&amp;gt;customData&amp;lt;/code&amp;gt; - &amp;#039;&amp;#039;&amp;#039;do not reuse these top-level keys&amp;#039;&amp;#039;&amp;#039; for your own data:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Used by !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;notes&amp;lt;/code&amp;gt; || Notes modal || the player&amp;#039;s free-text notes&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;navHistory&amp;lt;/code&amp;gt; || Navigation system || saved navigation history&lt;br /&gt;
|-&lt;br /&gt;
| (DB search criteria) || Database Search view || saved search filters/sort&lt;br /&gt;
|-&lt;br /&gt;
| (holdings prefs) || Portfolio Holdings table || saved filters/sort/hide-subsidiaries&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Pick a unique top-level key for your mod (e.g. &amp;lt;code&amp;gt;customData[&amp;quot;mymod:state&amp;quot;]&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
== What you cannot do (today) ==&lt;br /&gt;
&lt;br /&gt;
So expectations are clear:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No raw memory / pointer writes.&amp;#039;&amp;#039;&amp;#039; The bridge exposes the engine&amp;#039;s state through curated endpoints only. You cannot poke an arbitrary game variable from JavaScript - there is no generic &amp;quot;set value X&amp;quot; endpoint. The only free-form write is &amp;lt;code&amp;gt;customData&amp;lt;/code&amp;gt;, and it is inert ([[#The CustomData API - your persistent storage|§7]]).&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No intercepting the update loop.&amp;#039;&amp;#039;&amp;#039; The WebSocket delivers a &amp;#039;&amp;#039;snapshot&amp;#039;&amp;#039;. You can read it and react, but you cannot mutate values mid-update or inject into the serialization.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No new engine behavior without recompiling.&amp;#039;&amp;#039;&amp;#039; The simulation lives in PowerBASIC (&amp;lt;code&amp;gt;src/main/wsr/*.inc&amp;lt;/code&amp;gt;, ~178K lines). Adding a genuinely new game mechanic, a new event type, or a new endpoint means editing that source and rebuilding &amp;lt;code&amp;gt;wsr.exe&amp;lt;/code&amp;gt; (PowerBASIC 9.80) and usually &amp;lt;code&amp;gt;ui.dll&amp;lt;/code&amp;gt; (Visual Studio C++). That is engine development, not modding.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;No editing binary game data.&amp;#039;&amp;#039;&amp;#039; Saves and most &amp;lt;code&amp;gt;.DAT&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;.PRM&amp;lt;/code&amp;gt; files are proprietary binary or encoded formats. &amp;lt;code&amp;gt;CORPNAME.DAT&amp;lt;/code&amp;gt; (plain text) is the one exception you can safely edit ([[#Company names - CORPNAME.DAT (plain text, directly editable)|§3.7]]).&lt;br /&gt;
&lt;br /&gt;
== Workflow &amp;amp; sharing ==&lt;br /&gt;
&lt;br /&gt;
=== Editing and testing ===&lt;br /&gt;
&lt;br /&gt;
# Edit a file under &amp;lt;code&amp;gt;js/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;css/&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;assets/&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;CORPNAME.DAT&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Restart the game (frontend has no hot reload).&lt;br /&gt;
# Use &amp;lt;code&amp;gt;Ctrl+Shift+I&amp;lt;/code&amp;gt; for DevTools - console errors, the &amp;lt;code&amp;gt;gameStore&amp;lt;/code&amp;gt;, network tab against the REST API.&lt;br /&gt;
&lt;br /&gt;
=== Packaging a mod for others ===&lt;br /&gt;
&lt;br /&gt;
Because there is no build step, a mod is just &amp;#039;&amp;#039;&amp;#039;a set of replacement files&amp;#039;&amp;#039;&amp;#039;. The simplest distribution is a zip that mirrors the &amp;lt;code&amp;gt;resources/app/&amp;lt;/code&amp;gt; structure, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
my-dark-theme/&lt;br /&gt;
├── css/variables.css&lt;br /&gt;
└── css/theme.css&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with install instructions: &amp;quot;drop these into &amp;lt;code&amp;gt;resources/app/&amp;lt;/code&amp;gt;, overwriting.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Good practice:&lt;br /&gt;
* Keep mods &amp;#039;&amp;#039;&amp;#039;additive&amp;#039;&amp;#039;&amp;#039; where possible - new component files wired in with one import line, rather than rewriting core files, so two mods are less likely to collide.&lt;br /&gt;
* Document which base files you replace.&lt;br /&gt;
* Tell users that Steam&amp;#039;s &amp;quot;verify integrity of game files&amp;quot; reverts changes (their uninstall path) and that they should back up originals.&lt;br /&gt;
&lt;br /&gt;
== Quick reference ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! I want to… !! Do this&lt;br /&gt;
|-&lt;br /&gt;
| Re-theme the game || Edit &amp;lt;code&amp;gt;css/variables.css&amp;lt;/code&amp;gt;, then &amp;lt;code&amp;gt;css/theme.css&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;css/components/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Change UI text/layout/behavior || Edit the relevant file in &amp;lt;code&amp;gt;js/components/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Add a new panel/feature || New file in &amp;lt;code&amp;gt;js/components/&amp;lt;/code&amp;gt;, import it in a parent or &amp;lt;code&amp;gt;app.js&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Replace a background video or image || Drop a same-named file into &amp;lt;code&amp;gt;assets/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Rewrite the manual || Edit &amp;lt;code&amp;gt;assets/help/wsrbook.htm&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Add a language || New &amp;lt;code&amp;gt;js/locale/&amp;amp;lt;code&amp;amp;gt;.js&amp;lt;/code&amp;gt; + register in &amp;lt;code&amp;gt;localeManager.js&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Change/add contextual hints || Edit files in &amp;lt;code&amp;gt;js/data/hints/&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Rename companies / tickers || Edit &amp;lt;code&amp;gt;CORPNAME.DAT&amp;lt;/code&amp;gt; (plain text), starts on next New Game&lt;br /&gt;
|-&lt;br /&gt;
| Make the game &amp;#039;&amp;#039;do&amp;#039;&amp;#039; something || Call an &amp;lt;code&amp;gt;api.js&amp;lt;/code&amp;gt; function ([[#The API - everything you can make the game do|§5]]) - ~150 endpoints&lt;br /&gt;
|-&lt;br /&gt;
| Read game state || &amp;lt;code&amp;gt;useGameStore(s =&amp;gt; s.gameState.&amp;amp;lt;field&amp;amp;gt;)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;GET /gamestate&amp;lt;/code&amp;gt; ([[#The gameState - everything you can read|§6]])&lt;br /&gt;
|-&lt;br /&gt;
| Persist my mod&amp;#039;s own data in saves || &amp;lt;code&amp;gt;setCustomData({ myKey: … })&amp;lt;/code&amp;gt; ([[#The CustomData API - your persistent storage|§7]])&lt;br /&gt;
|-&lt;br /&gt;
| Change a core simulation rule || Not moddable - requires engine source + recompile&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Modding]]&lt;br /&gt;
[[Category:Wall Street Raider]]&lt;/div&gt;</summary>
		<author><name>74.83.75.1</name></author>
	</entry>
</feed>