<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://www.tt-wiki.net/index.php?action=history&amp;feed=atom&amp;title=NetworkCompatibleCode</id>
	<title>NetworkCompatibleCode - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.tt-wiki.net/index.php?action=history&amp;feed=atom&amp;title=NetworkCompatibleCode"/>
	<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;action=history"/>
	<updated>2026-05-02T06:04:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;diff=7298&amp;oldid=prev</id>
		<title>Orudge: Reformat and update</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;diff=7298&amp;oldid=prev"/>
		<updated>2011-07-31T12:52:46Z</updated>

		<summary type="html">&lt;p&gt;Reformat and update&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-GB&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 12:52, 31 July 2011&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&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; 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;br /&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty 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;&#039;&#039;&#039;&#039;&#039;HowTo write a code that works in a network game&#039;&#039;&#039;&#039;&#039;&lt;/div&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty 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;br /&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty 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;=Network Compatible Code=&lt;/div&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty 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;br /&gt;&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty 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;div&gt;During multiplayer, the gamestate must be the same on both machines at all times. TTD doesn&#039;t transmit the whole gamestate date to achieve this, though.&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;During multiplayer, the gamestate must be the same on both machines at all times. TTD doesn&#039;t transmit the whole gamestate date to achieve this, though.&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;Instead, every user-initiated action is transmitted to the other computer, and both machines execute it at the same time. It is important to note that the random generator seed is part of the gamestate, too. When everything goes well, the gamestate (including the random seed) is in sync because both machines do the same things and generate the same random numbers. When things go wrong, however, the random seeds will start to differ soon (the first time one side calls randomfn without the other doing the same). From this point on, random events will start to differ on the to machines, making the gamestates drift further and further apart from each other. The easiest way to detect this problem is comparing the random seeds of the two machines; TTDPatch does this to detect desyncs.&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;Instead, every user-initiated action is transmitted to the other computer, and both machines execute it at the same time. It is important to note that the random generator seed is part of the gamestate, too. When everything goes well, the gamestate (including the random seed) is in sync because both machines do the same things and generate the same random numbers. When things go wrong, however, the random seeds will start to differ soon (the first time one side calls randomfn without the other doing the same). From this point on, random events will start to differ on the to machines, making the gamestates drift further and further apart from each other. The easiest way to detect this problem is comparing the random seeds of the two machines; TTDPatch does this to detect desyncs.&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;An action is transmitted only if it&#039;s called through &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))DoAction[[]]&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[&lt;/del&gt;, you should use it for every action that changes the gamestate. (The dopatchaction macro calls &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[]]DoAction[[&lt;/del&gt; behind the scenes, so it&#039;s safe.) The only information transmitted is the input registers of &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))DoAction[[]]&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[&lt;/del&gt;, and the content of textrefstack. Therefore, you can&#039;t use global variables to communicate with the action handler.&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;An action is transmitted only if it&#039;s called through DoAction, you should use it for every action that changes the gamestate. (The dopatchaction macro calls DoAction behind the scenes, so it&#039;s safe.) The only information transmitted is the input registers of DoAction, and the content of textrefstack. Therefore, you can&#039;t use global variables to communicate with the action handler.&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;You should indicate errors via setting ebx to 0x80000000, and setting operrormsg2, if appliable. This way, both PCs will see that the action failed.&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;You should indicate errors via setting ebx to 0x80000000, and setting operrormsg2, if appliable. This way, both PCs will see that the action failed.&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;The action handler must do the same things on both machines. This includes checking whether the action is possible at all, even if you&#039;re sure that it is possible when calling &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[]]DoAction[[&lt;/del&gt;. The games may be out of sync already, so the action may not be possible on the other machine. Additionally, with the new asynchronous protocol, actions won&#039;t be executed instantly, so the action may become impossible by the time it gets scheduled.&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;The action handler must do the same things on both machines. This includes checking whether the action is possible at all, even if you&#039;re sure that it is possible when calling DoAction. The games may be out of sync already, so the action may not be possible on the other machine. Additionally, with the new asynchronous protocol, actions won&#039;t be executed instantly, so the action may become impossible by the time it gets scheduled.&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;Calling the random generator at only one PC will desync the games.&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;Calling the random generator at only one PC will desync the games.&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;You can&#039;t pass pointers into &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[]]DoAction[[&lt;/del&gt;, you have to convert them into an index because the memory locations on the clients may not be the same.&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;You can&#039;t pass pointers into DoAction, you have to convert them into an index because the memory locations on the clients may not be the same.&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;This means:&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;This means:&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;div&gt;* Always use actions to change the gamestate, so both PCs will do it.&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;* Always use actions to change the gamestate, so both PCs will do it.&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;* Don&#039;t use global variables for communication between normal code and action code. Bad example: Set flag -&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;gt;&lt;/del&gt; call &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[]]DoAction[[&lt;/del&gt; -&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;amp;gt;&lt;/del&gt; action code tests for the flag - the flag is now only set on one PC, and you get a desync.&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;* Don&#039;t use global variables for communication between normal code and action code. Bad example: Set flag -&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&lt;/ins&gt; call DoAction -&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;gt;&lt;/ins&gt; action code tests for the flag - the flag is now only set on one PC, and you get a desync.&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;div&gt;* Always pass back an error if something fails. Or in other words, if the action fails, return an error and if something costs money, it has to cost the same on all PCs.&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;* Always pass back an error if something fails. Or in other words, if the action fails, return an error and if something costs money, it has to cost the same on all PCs.&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;div&gt;* Don&#039;t change the landscape/gamestate when the action flag says to do a test only.&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;* Don&#039;t change the landscape/gamestate when the action flag says to do a test only.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 29:&lt;/td&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 24:&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;* Don&#039;t pass pointers to code or variables. Example: Don&#039;t pass a pointer to a vehicle entry, but the relevant index into the vehicle array.&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;* Don&#039;t pass pointers to code or variables. Example: Don&#039;t pass a pointer to a vehicle entry, but the relevant index into the vehicle array.&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;div&gt;* Don&#039;t write code that assumes a window is opened, or on a kind of state, or try to access a window. The window is opened on one PC only.&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;* Don&#039;t write code that assumes a window is opened, or on a kind of state, or try to access a window. The window is opened on one PC only.&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;* Don&#039;t try to open a window in an &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;))&lt;/del&gt;DoAction&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[]]DoAction[[&lt;/del&gt;, unless it should be opend on both ends. Be sure that the window is network aware if it pops up on both PCs.&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;* Don&#039;t try to open a window in an DoAction, unless it should be opend on both ends. Be sure that the window is network aware if it pops up on both PCs.&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td colspan=&quot;2&quot; class=&quot;diff-empty diff-side-deleted&quot;&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;[[Category:TTDPatch Development]]&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Orudge</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;diff=2264&amp;oldid=prev</id>
		<title>Orudge: 4 revisions</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;diff=2264&amp;oldid=prev"/>
		<updated>2011-06-12T19:09:17Z</updated>

		<summary type="html">&lt;p&gt;4 revisions&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;HowTo write a code that works in a network game&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=Network Compatible Code=&lt;br /&gt;
&lt;br /&gt;
During multiplayer, the gamestate must be the same on both machines at all times. TTD doesn&amp;#039;t transmit the whole gamestate date to achieve this, though.&lt;br /&gt;
&lt;br /&gt;
Instead, every user-initiated action is transmitted to the other computer, and both machines execute it at the same time. It is important to note that the random generator seed is part of the gamestate, too. When everything goes well, the gamestate (including the random seed) is in sync because both machines do the same things and generate the same random numbers. When things go wrong, however, the random seeds will start to differ soon (the first time one side calls randomfn without the other doing the same). From this point on, random events will start to differ on the to machines, making the gamestates drift further and further apart from each other. The easiest way to detect this problem is comparing the random seeds of the two machines; TTDPatch does this to detect desyncs.&lt;br /&gt;
&lt;br /&gt;
An action is transmitted only if it&amp;#039;s called through ))DoAction[[]]DoAction[[, you should use it for every action that changes the gamestate. (The dopatchaction macro calls ))DoAction[[]]DoAction[[ behind the scenes, so it&amp;#039;s safe.) The only information transmitted is the input registers of ))DoAction[[]]DoAction[[, and the content of textrefstack. Therefore, you can&amp;#039;t use global variables to communicate with the action handler.&lt;br /&gt;
&lt;br /&gt;
You should indicate errors via setting ebx to 0x80000000, and setting operrormsg2, if appliable. This way, both PCs will see that the action failed.&lt;br /&gt;
&lt;br /&gt;
The action handler must do the same things on both machines. This includes checking whether the action is possible at all, even if you&amp;#039;re sure that it is possible when calling ))DoAction[[]]DoAction[[. The games may be out of sync already, so the action may not be possible on the other machine. Additionally, with the new asynchronous protocol, actions won&amp;#039;t be executed instantly, so the action may become impossible by the time it gets scheduled.&lt;br /&gt;
&lt;br /&gt;
Calling the random generator at only one PC will desync the games.&lt;br /&gt;
&lt;br /&gt;
You can&amp;#039;t pass pointers into ))DoAction[[]]DoAction[[, you have to convert them into an index because the memory locations on the clients may not be the same.&lt;br /&gt;
&lt;br /&gt;
This means:&lt;br /&gt;
* Always use actions to change the gamestate, so both PCs will do it.&lt;br /&gt;
* Don&amp;#039;t use global variables for communication between normal code and action code. Bad example: Set flag -&amp;amp;gt; call ))DoAction[[]]DoAction[[ -&amp;amp;gt; action code tests for the flag - the flag is now only set on one PC, and you get a desync.&lt;br /&gt;
* Always pass back an error if something fails. Or in other words, if the action fails, return an error and if something costs money, it has to cost the same on all PCs.&lt;br /&gt;
* Don&amp;#039;t change the landscape/gamestate when the action flag says to do a test only.&lt;br /&gt;
&lt;br /&gt;
(There may be exceptions, or it may be irrelevant because the action doesn&amp;#039;t have the concept of testing-executing a command. This is true for gameplay setting changes, however this is surely not true for landscape tools, building stuff, buying vehicles as they may fail because of money)&lt;br /&gt;
* Don&amp;#039;t use the random number generator outside action handlers.&lt;br /&gt;
* Don&amp;#039;t assume a company is an AI player, use the relevant code pieces to check if it&amp;#039;s an human player.&lt;br /&gt;
* Don&amp;#039;t pass pointers to code or variables. Example: Don&amp;#039;t pass a pointer to a vehicle entry, but the relevant index into the vehicle array.&lt;br /&gt;
* Don&amp;#039;t write code that assumes a window is opened, or on a kind of state, or try to access a window. The window is opened on one PC only.&lt;br /&gt;
* Don&amp;#039;t try to open a window in an ))DoAction[[]]DoAction[[, unless it should be opend on both ends. Be sure that the window is network aware if it pops up on both PCs.&lt;/div&gt;</summary>
		<author><name>Orudge</name></author>
	</entry>
	<entry>
		<id>https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;diff=2262&amp;oldid=prev</id>
		<title>eis_os at 08:49, 5 July 2007</title>
		<link rel="alternate" type="text/html" href="https://www.tt-wiki.net/index.php?title=NetworkCompatibleCode&amp;diff=2262&amp;oldid=prev"/>
		<updated>2007-07-05T08:49:16Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;HowTo write a code that works in a network game&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=Network Compatible Code=&lt;br /&gt;
&lt;br /&gt;
TTD works with a 100% synced game state on two PCs, however it doesn&amp;#039;t transmit the whole game date.&lt;br /&gt;
&lt;br /&gt;
Every Action that is created by an User is transmitted to the other computer and aswell executed at the same time. The random generator value is always the same on both PCs if the gamestate isn&amp;#039;t different. (Example the landscape data is different, then the random generator value is different) and every PC does always the same.&lt;br /&gt;
&lt;br /&gt;
As only the raw ))DoAction[[]]DoAction[[ Player data is transmitted, all initiated Players action need to be passed to an ))DoAction[[]]DoAction[[ / TTDPatch Action. As only the Action Data is transmitted, you can&amp;#039;t change any global variable to pass extra data, or settings / flags into the DoAction.&lt;br /&gt;
&lt;br /&gt;
You should provide an Error Code if something goes wrong, so both PCs see that the action fails.&lt;br /&gt;
&lt;br /&gt;
The the fired Action Handler needs to work on both PCs the same way,&lt;br /&gt;
&lt;br /&gt;
this means it has to do the same checks on both PCs, as the gamestate on the other PCs maybe already in a different state so the action may fail. Specially this will be true with the new network protocol.&lt;br /&gt;
&lt;br /&gt;
Calling the random generator at only one PC will desync the game too (The random value)&lt;br /&gt;
&lt;br /&gt;
You can&amp;#039;t pass pointers into DoActions, you have to convert them into an index because the memory locations on the clients may not be the same!&lt;br /&gt;
&lt;br /&gt;
This means:&lt;br /&gt;
* Always use an Action to change the gamestate, so both PCs will do it.&lt;br /&gt;
* Don&amp;#039;t change the way a Action works, or code that an Action invokes via a global variable. Bad Example: Set Flag enabled -&amp;amp;gt; DoAction -&amp;amp;gt; Test for the flag - the flag is now only set on one PC, result is a desync !&lt;br /&gt;
* Always pass back an error if something fails. Or in other words, if the Action fails, return an error and if something costs money, it has to cost the same on all PCs!&lt;br /&gt;
* Don&amp;#039;t change the landscape/gamestate when the action flag says it only do an tests.&lt;br /&gt;
&lt;br /&gt;
(There may be exceptions or it may be irrelevant because this action doesn&amp;#039;t have the concept of testing-executing a command. This is true for gameplay setting changes, however this is surely not true for landscape tools, building stuff, buying vehicles as they may fail because of money)&lt;br /&gt;
* Don&amp;#039;t use the random number outside an Action Handler.&lt;br /&gt;
* Don&amp;#039;t assume an company is an ai player, use the relevant code pieces to check if it&amp;#039;s an human player...&lt;br /&gt;
* Don&amp;#039;t pass pointers to code or variables. Example: Don&amp;#039;t pass a pointer to a vehicle entry, but the relevant index into the vehicle array.&lt;br /&gt;
* Don&amp;#039;t write code that assumes a window is opened, or on a kind of state, or trying to access a window, the window is only opend on one PC.&lt;br /&gt;
* Don&amp;#039;t try to open a window in an DoAction, only if it should be opend on both ends. Be sure that the window is network aware if you write a window that popups on both PCs.&lt;/div&gt;</summary>
		<author><name>eis_os</name></author>
	</entry>
</feed>