<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.simtx.net/index.php?action=history&amp;feed=atom&amp;title=SimTX_API%2FFraming</id>
	<title>SimTX API/Framing - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.simtx.net/index.php?action=history&amp;feed=atom&amp;title=SimTX_API%2FFraming"/>
	<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API/Framing&amp;action=history"/>
	<updated>2026-11-04T21:35:06Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.simtx.net/index.php?title=SimTX_API/Framing&amp;diff=2382&amp;oldid=prev</id>
		<title>Clanker: Remove development history and server internals</title>
		<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API/Framing&amp;diff=2382&amp;oldid=prev"/>
		<updated>2026-10-24T17:14:17Z</updated>

		<summary type="html">&lt;p&gt;Remove development history and server internals&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 17:14, 24 October 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-l10&quot;&gt;Line 10:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 10:&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;&amp;lt;/syntaxhighlight&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;&amp;lt;/syntaxhighlight&amp;gt;&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 server sends no preface. The preface is the only part of the protocol outside protobuf, and the only place the protocol version appears. A server that does not speak the requested version answers with a [[SimTX API/Packets/ServerHello|ServerHello]] whose status is &amp;lt;code&amp;gt;HELLO_STATUS_VERSION_UNSUPPORTED&amp;lt;/code&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;; see [[SimTX API/Connection and handshake#Version 24 clients|Version 24 clients]] for the v24 case&lt;/del&gt;.&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 server sends no preface. The preface is the only part of the protocol outside protobuf, and the only place the protocol version appears. A server that does not speak the requested version answers with a [[SimTX API/Packets/ServerHello|ServerHello]] whose status is &amp;lt;code&amp;gt;HELLO_STATUS_VERSION_UNSUPPORTED&amp;lt;/code&amp;gt;.&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;== Frames ==&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;== Frames ==&lt;/div&gt;&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-l20&quot;&gt;Line 20:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 20:&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;&amp;lt;/syntaxhighlight&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;&amp;lt;/syntaxhighlight&amp;gt;&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;This is protobuf&#039;s standard &#039;&#039;length-delimited&#039;&#039; encoding of a message, as written by &amp;lt;code&amp;gt;writeDelimitedTo&amp;lt;/code&amp;gt; and read by &amp;lt;code&amp;gt;parseDelimitedFrom&amp;lt;/code&amp;gt; &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;in the Java library&lt;/del&gt;, &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;and by &lt;/del&gt;the equivalent helpers of other protobuf libraries. The varint is the usual base-128 encoding, least significant group first.&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;This is protobuf&#039;s standard &#039;&#039;length-delimited&#039;&#039; encoding of a message, as written by &amp;lt;code&amp;gt;writeDelimitedTo&amp;lt;/code&amp;gt; and read by &amp;lt;code&amp;gt;parseDelimitedFrom&amp;lt;/code&amp;gt;, &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;or &lt;/ins&gt;the equivalent helpers of other protobuf libraries. The varint is the usual base-128 encoding, least significant group first.&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;&amp;lt;code&amp;gt;ClientFrame&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ServerFrame&amp;lt;/code&amp;gt; each consist of one &amp;lt;code&amp;gt;oneof msg&amp;lt;/code&amp;gt;. Exactly one member is set in every frame. The member number says what the frame is, and the member&amp;#039;s value is the message:&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;&amp;lt;code&amp;gt;ClientFrame&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ServerFrame&amp;lt;/code&amp;gt; each consist of one &amp;lt;code&amp;gt;oneof msg&amp;lt;/code&amp;gt;. Exactly one member is set in every frame. The member number says what the frame is, and the member&amp;#039;s value is the message:&lt;/div&gt;&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-l55&quot;&gt;Line 55:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 55:&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;|}&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;|}&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;Numbers 1 to 15 encode the tag in one byte. &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Numbers that were used before release &lt;/del&gt;are reserved &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;and never reused&lt;/del&gt;.&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;Numbers 1 to 15 encode the tag in one byte. &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;code&amp;gt;ServerFrame&amp;lt;/code&amp;gt; numbers 15, 16 and 62 &lt;/ins&gt;are reserved&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;; do not use them&lt;/ins&gt;.&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;== Size and shape limits ==&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;== Size and shape limits ==&lt;/div&gt;&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-l74&quot;&gt;Line 74:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 74:&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;|}&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;|}&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;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;The element budget exists because a frame&#039;s size in bytes says little about the memory it needs once parsed: an empty repeated message costs 2 bytes on the wire but far more as an object. Receivers check a frame&#039;s shape before parsing it. &lt;/del&gt;A client frame over a limit is a protocol violation; the server answers [[SimTX API/Packets/Error|Error]] &amp;lt;code&amp;gt;INVALID_REQUEST&amp;lt;/code&amp;gt; where it can and closes the connection. Clients should apply the same limits to server frames.&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 client frame over a limit is a protocol violation; the server answers [[SimTX API/Packets/Error|Error]] &amp;lt;code&amp;gt;INVALID_REQUEST&amp;lt;/code&amp;gt; where it can and closes the connection. Clients should apply the same limits to server frames.&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;A reader should not allocate the announced length blindly: check it against 16 MiB first, and for large frames let the buffer grow as bytes arrive.&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;A reader should not allocate the announced length blindly: check it against 16 MiB first, and for large frames let the buffer grow as bytes arrive.&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;== Unknown frames and fields ==&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;== Unknown frames and fields ==&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;The protocol grows within version 25 by adding messages, &amp;lt;code&amp;gt;oneof&amp;lt;/code&amp;gt; members, fields and enum values. &lt;/del&gt;A reader must &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;therefore&lt;/del&gt;:&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 reader must:&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;* &amp;#039;&amp;#039;&amp;#039;Skip unknown frames.&amp;#039;&amp;#039;&amp;#039; A frame whose member number it does not know parses as a frame with no member set. Ignore it and read the next frame. Never treat it as fatal. An empty frame is skipped the same way.&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;* &amp;#039;&amp;#039;&amp;#039;Skip unknown frames.&amp;#039;&amp;#039;&amp;#039; A frame whose member number it does not know parses as a frame with no member set. Ignore it and read the next frame. Never treat it as fatal. An empty frame is skipped the same way.&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;* &amp;#039;&amp;#039;&amp;#039;Skip unknown fields&amp;#039;&amp;#039;&amp;#039; of every wire type: varint (0), 64-bit (1), length-delimited (2) and 32-bit (5). Generated protobuf code does this already; hand-written decoders must do it explicitly.&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;* &amp;#039;&amp;#039;&amp;#039;Skip unknown fields&amp;#039;&amp;#039;&amp;#039; of every wire type: varint (0), 64-bit (1), length-delimited (2) and 32-bit (5). Generated protobuf code does this already; hand-written decoders must do it explicitly.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key simtxwiki:diff:1.41:old-2254:rev-2382:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Clanker</name></author>
	</entry>
	<entry>
		<id>https://wiki.simtx.net/index.php?title=SimTX_API/Framing&amp;diff=2254&amp;oldid=prev</id>
		<title>Clanker: Protocol v25 reference</title>
		<link rel="alternate" type="text/html" href="https://wiki.simtx.net/index.php?title=SimTX_API/Framing&amp;diff=2254&amp;oldid=prev"/>
		<updated>2026-10-24T16:19:12Z</updated>

		<summary type="html">&lt;p&gt;Protocol v25 reference&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SimTX API navigation}}&lt;br /&gt;
This page describes how messages of the [[SimTX API]] game protocol, version 25, are laid out on the TLS byte stream: the preface, the length-delimited frames, the limits a frame must respect, and how a reader skips what it does not understand.&lt;br /&gt;
&lt;br /&gt;
== Preface ==&lt;br /&gt;
The client opens the stream with exactly 8 bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
53 49 4D 54     magic      0x53494D54, &amp;quot;SIMT&amp;quot;, big-endian int32&lt;br /&gt;
00 00 00 19     version    25, big-endian int32&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The server sends no preface. The preface is the only part of the protocol outside protobuf, and the only place the protocol version appears. A server that does not speak the requested version answers with a [[SimTX API/Packets/ServerHello|ServerHello]] whose status is &amp;lt;code&amp;gt;HELLO_STATUS_VERSION_UNSUPPORTED&amp;lt;/code&amp;gt;; see [[SimTX API/Connection and handshake#Version 24 clients|Version 24 clients]] for the v24 case.&lt;br /&gt;
&lt;br /&gt;
== Frames ==&lt;br /&gt;
After the preface, each direction is a sequence of frames:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
varint      length       number of bytes that follow&lt;br /&gt;
bytes       message      one ClientFrame (client to server) or ServerFrame (server to client)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is protobuf&amp;#039;s standard &amp;#039;&amp;#039;length-delimited&amp;#039;&amp;#039; encoding of a message, as written by &amp;lt;code&amp;gt;writeDelimitedTo&amp;lt;/code&amp;gt; and read by &amp;lt;code&amp;gt;parseDelimitedFrom&amp;lt;/code&amp;gt; in the Java library, and by the equivalent helpers of other protobuf libraries. The varint is the usual base-128 encoding, least significant group first.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;ClientFrame&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ServerFrame&amp;lt;/code&amp;gt; each consist of one &amp;lt;code&amp;gt;oneof msg&amp;lt;/code&amp;gt;. Exactly one member is set in every frame. The member number says what the frame is, and the member&amp;#039;s value is the message:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;protobuf&amp;quot;&amp;gt;&lt;br /&gt;
message ClientFrame {&lt;br /&gt;
  oneof msg {&lt;br /&gt;
    ClientHello hello = 1;&lt;br /&gt;
    Ping ping = 2;&lt;br /&gt;
    ...&lt;br /&gt;
    ReceiverStart receiver_start = 10;&lt;br /&gt;
    ...&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So a frame body always starts with the tag of its member (field number × 8 + 2), then the member&amp;#039;s length, then the member&amp;#039;s message. The complete lists are on [[SimTX API/Packet list]].&lt;br /&gt;
&lt;br /&gt;
=== Member numbers ===&lt;br /&gt;
Member numbers are allocated in blocks, the same in both directions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Numbers !! Area&lt;br /&gt;
|-&lt;br /&gt;
| 1 to 9 || Connection: hello, ping, errors, banners&lt;br /&gt;
|-&lt;br /&gt;
| 10 to 29 || Receiver and transmitter sessions&lt;br /&gt;
|-&lt;br /&gt;
| 30 to 59 || Control sessions&lt;br /&gt;
|-&lt;br /&gt;
| 60 to 79 || Moderation sessions&lt;br /&gt;
|-&lt;br /&gt;
| 80 to 99 || Reserved for the next area&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Numbers 1 to 15 encode the tag in one byte. Numbers that were used before release are reserved and never reused.&lt;br /&gt;
&lt;br /&gt;
== Size and shape limits ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Limit !! Value&lt;br /&gt;
|-&lt;br /&gt;
| Frame length || At most 16 MiB (16,777,216 bytes), both directions&lt;br /&gt;
|-&lt;br /&gt;
| Hello frame || At most 64 KiB&lt;br /&gt;
|-&lt;br /&gt;
| Frames before the hello || At most 16 unknown or empty frames&lt;br /&gt;
|-&lt;br /&gt;
| Elements per frame || At most 16,384 in client frames and 2,097,152 in server frames, counting nested messages, elements of repeated string, bytes and message fields, and unknown fields&lt;br /&gt;
|-&lt;br /&gt;
| Nesting depth || At most 32 levels of nested messages&lt;br /&gt;
|-&lt;br /&gt;
| Group encoding || Not allowed (wire types 3 and 4)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The element budget exists because a frame&amp;#039;s size in bytes says little about the memory it needs once parsed: an empty repeated message costs 2 bytes on the wire but far more as an object. Receivers check a frame&amp;#039;s shape before parsing it. A client frame over a limit is a protocol violation; the server answers [[SimTX API/Packets/Error|Error]] &amp;lt;code&amp;gt;INVALID_REQUEST&amp;lt;/code&amp;gt; where it can and closes the connection. Clients should apply the same limits to server frames.&lt;br /&gt;
&lt;br /&gt;
A reader should not allocate the announced length blindly: check it against 16 MiB first, and for large frames let the buffer grow as bytes arrive.&lt;br /&gt;
&lt;br /&gt;
== Unknown frames and fields ==&lt;br /&gt;
The protocol grows within version 25 by adding messages, &amp;lt;code&amp;gt;oneof&amp;lt;/code&amp;gt; members, fields and enum values. A reader must therefore:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Skip unknown frames.&amp;#039;&amp;#039;&amp;#039; A frame whose member number it does not know parses as a frame with no member set. Ignore it and read the next frame. Never treat it as fatal. An empty frame is skipped the same way.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Skip unknown fields&amp;#039;&amp;#039;&amp;#039; of every wire type: varint (0), 64-bit (1), length-delimited (2) and 32-bit (5). Generated protobuf code does this already; hand-written decoders must do it explicitly.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Keep unknown enum values.&amp;#039;&amp;#039;&amp;#039; Treat them as &amp;quot;unknown&amp;quot; in the user interface rather than failing. Each enum documents how its 0 value and unknown values are read; see [[SimTX API/Data types#Enumerations|Enumerations]].&lt;br /&gt;
&lt;br /&gt;
Within a session, frames that are known but not allowed (for example a [[SimTX API/Packets/TxUpdate|TxUpdate]] on a receiver connection) are a protocol violation.&lt;br /&gt;
&lt;br /&gt;
== Order ==&lt;br /&gt;
Frames are processed in order on each connection. Responses to control requests arrive in the order of the requests, but other frames can arrive between any two of them: [[SimTX API/Packets/Pong|Pong]], [[SimTX API/Packets/Banner|Banner]], [[SimTX API/Packets/MonitorBlock|MonitorBlock]], [[SimTX API/Packets/SessionStatus|SessionStatus]] updates and [[SimTX API/Packets/Error|Error]]. Read each connection with a loop that dispatches on the member number, rather than expecting a particular frame next.&lt;br /&gt;
&lt;br /&gt;
== Reading loop ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
send preface, then the hello frame&lt;br /&gt;
loop:&lt;br /&gt;
    length = read varint                      (at most 5 bytes for a valid length)&lt;br /&gt;
    if length &amp;gt; 16 MiB: protocol error, close&lt;br /&gt;
    body = read exactly length bytes&lt;br /&gt;
    frame = parse ServerFrame from body       (unknown fields skipped)&lt;br /&gt;
    switch on the member that is set:&lt;br /&gt;
        known member  -&amp;gt; handle it&lt;br /&gt;
        nothing set   -&amp;gt; ignore (newer message or empty frame)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
A ping and its pong:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;ping&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039; (client to server, 12 bytes):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
0B                      frame length 11&lt;br /&gt;
12 09                   ping (Ping), 9 bytes&lt;br /&gt;
  08 63                 nonce = 99&lt;br /&gt;
  10 80 94 83 B9 97 34  client_time_ms = 1793000000000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;lt;code&amp;gt;pong&amp;lt;/code&amp;gt;&amp;#039;&amp;#039;&amp;#039; (server to client, 19 bytes):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
12                      frame length 18&lt;br /&gt;
12 10                   pong (Pong), 16 bytes&lt;br /&gt;
  08 63                 nonce = 99&lt;br /&gt;
  10 80 94 83 B9 97 34  client_time_ms = 1793000000000&lt;br /&gt;
  18 8C 94 83 B9 97 34  server_time_ms = 1793000000012&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{SimTX API navbox}}&lt;br /&gt;
[[Category:SimTX API]]&lt;br /&gt;
[[Category:SimTX API sessions]]&lt;/div&gt;</summary>
		<author><name>Clanker</name></author>
	</entry>
</feed>