diff options
| -rw-r--r-- | CHANGELOG.md | 13 | ||||
| -rw-r--r-- | docs/latest/draft-tasd-spec.html | 129 | ||||
| -rw-r--r-- | docs/latest/draft-tasd-spec.txt | 160 | ||||
| -rw-r--r-- | docs/tasd-spec-0001/draft-tasd-spec-0001.html | 129 | ||||
| -rw-r--r-- | docs/tasd-spec-0001/draft-tasd-spec-0001.txt | 160 | ||||
| -rw-r--r-- | src/docs/draft-tasd-spec-0001.xml | 57 |
6 files changed, 360 insertions, 288 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 77464b3..25b5a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), although currently without version numbers added. +## 2025-04-16 + +### Changed +- Improved wording in the Abstract, Introduction, Overview and several other sections +- Clarified what must happen when INPUT_MOMENTs conflict with INPUT_CHUNKs, and removed wording that suggested they shouldn't both be used in the same TASD file +- Changed the Index Type "Microseconds * 10" to "Microseconds" for INPUT_MOMENT and TRANSITION packets + +### Added +- A new Index Type of "Nanoseconds" for INPUT_MOMENT and TRANSITION packets (since the index number is 64-bits wide, even when using nanoseconds the largest number is equivalent to ~584.6 years) + + ## 2025-02-01 ### Changed -- Intended formatting and usage of INPUT_CHUNK and INPUT_MOMENT packets +- Clarified the intended formatting and usage of INPUT_CHUNK and INPUT_MOMENT packets - Clarified that INPUT_CHUNK Indexes in TRANSITION packets should be *byte* indexes - Genesis controller input formats to better reflect the bit ordering seen during replay diff --git a/docs/latest/draft-tasd-spec.html b/docs/latest/draft-tasd-spec.html index a216583..e3a41cc 100644 --- a/docs/latest/draft-tasd-spec.html +++ b/docs/latest/draft-tasd-spec.html @@ -9,7 +9,7 @@ <meta content="Bigbass" name="author"> <meta content="rasteri" name="author"> <meta content=' - The TASD file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) data for TAS replay devices to replay on physical video game console hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification at a later date. + The TASD file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) input and configuration data for use with devices (known as "TAS replay devices") that replay inputs on physical video game hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification. This document defines the file format specification for TASD files. ' name="description"> <meta content="xml2rfc 3.20.0" name="generator"> @@ -1211,7 +1211,7 @@ li > p:last-of-type:only-child { <thead><tr> <td class="left"></td> <td class="center">TASD File Format Specification</td> -<td class="right">February 2025</td> +<td class="right">April 2025</td> </tr></thead> <tfoot><tr> <td class="left">Grey, et al.</td> @@ -1226,7 +1226,7 @@ li > p:last-of-type:only-child { <dd class="workgroup">Independent TAS Console Replay Research Group</dd> <dt class="label-published">Published:</dt> <dd class="published"> -<time datetime="2025-02-01" class="published">1 February 2025</time> +<time datetime="2025-04-16" class="published">16 April 2025</time> </dd> <dt class="label-authors">Authors:</dt> <dd class="authors"> @@ -1245,7 +1245,7 @@ li > p:last-of-type:only-child { <h1 id="title">TASD File Format Specification Version 1</h1> <section id="section-abstract"> <h2 id="abstract"><a href="#abstract" class="selfRef">Abstract</a></h2> -<p id="section-abstract-1">The <strong>TASD</strong> file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) data for TAS replay devices to replay on physical video game console hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification at a later date.<a href="#section-abstract-1" class="pilcrow">¶</a></p> +<p id="section-abstract-1">The <strong>TASD</strong> file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) input and configuration data for use with devices (known as "TAS replay devices") that replay inputs on physical video game hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification.<a href="#section-abstract-1" class="pilcrow">¶</a></p> <p id="section-abstract-2">This document defines the file format specification for <strong>TASD</strong> files.<a href="#section-abstract-2" class="pilcrow">¶</a></p> </section> <div id="toc"> @@ -1614,9 +1614,9 @@ li > p:last-of-type:only-child { <h2 id="name-introduction"> <a href="#section-1" class="section-number selfRef">1. </a><a href="#name-introduction" class="section-name selfRef">Introduction</a> </h2> -<p id="section-1-1">The Tool Assisted Speedrun Dump (<strong>TASD</strong>) interchange format is a file format for storing data to allow "Tool Assisted Speedruns" or "Tool Assisted Superplays" to be played on physical video game console hardware using TAS replay devices. Created to be hardware and software agnostic, the <strong>TASD</strong> interchange format uses a key-based, binary, packet format to break up pieces of information into easily-parsable and forward-compatible chunks. The format is extensible by simply defining additional keys or value types as necessary. When parsing the file, software can skip any packets whose key is unknown or unsupported.<a href="#section-1-1" class="pilcrow">¶</a></p> +<p id="section-1-1">The Tool Assisted Speedrun Dump (<strong>TASD</strong>) interchange format is a file format for storing data that enables "Tool Assisted Speedruns" or "Tool Assisted Superplays" to be played on physical video game hardware using TAS replay devices. Created to be hardware and software agnostic, the <strong>TASD</strong> interchange format uses a key-based, binary, packet format to break up pieces of information into easily-parsable and forward-compatible chunks. The format is extensible by simply defining additional keys or value types as necessary. When parsing the file, software can skip any packets whose key is unknown or unsupported.<a href="#section-1-1" class="pilcrow">¶</a></p> <p id="section-1-2">Packets of a given type can be used multiple times or completely omitted as needed. This reusability eliminates the need of a predefined delimiter to separate pieces of data.<a href="#section-1-2" class="pilcrow">¶</a></p> -<p id="section-1-3">While files generated by emulator dump scripts should provide as much information as possible, because packets are optional, the file can be expanded later with any additional data as desired. No intermediary file format is necessary.<a href="#section-1-3" class="pilcrow">¶</a></p> +<p id="section-1-3">While files generated by emulator dump scripts should provide as much information as possible, they may be unable to provide everything. Since packets are optional, the file can be expanded later with any additional data as desired. No intermediary file format is necessary.<a href="#section-1-3" class="pilcrow">¶</a></p> <section id="section-1.1"> <h3 id="name-overview-and-preliminaries"> <a href="#section-1.1" class="section-number selfRef">1.1. </a><a href="#name-overview-and-preliminaries" class="section-name selfRef">Overview and Preliminaries</a> @@ -1641,95 +1641,96 @@ li > p:last-of-type:only-child { <li class="compact ulEmpty" id="section-1.1.1-2.6">([]N) = List of Unsigned Integers<a href="#section-1.1.1-2.6" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-3">We use the terms <strong>byte</strong> and <strong>octet</strong> interchangeably in this document.<a href="#section-1.1.1-3" class="pilcrow">¶</a></p> -<p id="section-1.1.1-4">Unless specified otherwise, all multi-octet integers are big-endian.<a href="#section-1.1.1-4" class="pilcrow">¶</a></p> +<p id="section-1.1.1-3">Unless specified otherwise, all multi-octet integers are big-endian.<a href="#section-1.1.1-3" class="pilcrow">¶</a></p> +<p id="section-1.1.1-4">We use the terms <strong>byte</strong> and <strong>octet</strong> interchangeably in this document.<a href="#section-1.1.1-4" class="pilcrow">¶</a></p> <p id="section-1.1.1-5">We use the terms <strong>Tool Assisted Speedrun</strong>, <strong>Tool Assisted Superplay</strong> and <strong>TAS</strong> interchangeably in this document.<a href="#section-1.1.1-5" class="pilcrow">¶</a></p> <p id="section-1.1.1-6">In subsections of (<a href="#descriptions" class="auto internal xref">Section 4.2</a>), the term "in direct form" is used. That term is defined to mean a packet in a <strong>TASD</strong> file directly (first order packet) rather than a packet inside a TRANSITION or MOVIE_TRANSITION packet (second order packet).<a href="#section-1.1.1-6" class="pilcrow">¶</a></p> -<p id="section-1.1.1-7">String values <span class="bcp14">MUST</span> use UTF-8 encoding. As such, string values <span class="bcp14">MAY</span> contain any number of NUL characters and have no concept of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document.<a href="#section-1.1.1-7" class="pilcrow">¶</a></p> -<p id="section-1.1.1-8">Unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification.<a href="#section-1.1.1-8" class="pilcrow">¶</a></p> -<p id="section-1.1.1-9">Boolean values <span class="bcp14">MUST</span> be a single octet with the value of <code>0</code> for <strong>FALSE</strong> or <code>1</code> for <strong>TRUE</strong>.<a href="#section-1.1.1-9" class="pilcrow">¶</a></p> -<span class="break"></span><dl class="dlParallel" id="section-1.1.1-10"> - <dt id="section-1.1.1-10.1"><code>[N octets]</code></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.2">A sequence of octets with a length of N<a href="#section-1.1.1-10.2" class="pilcrow">¶</a> +<p id="section-1.1.1-7">String values <span class="bcp14">MUST</span> use UTF-8 encoding. As such, string values <span class="bcp14">MAY</span> contain any number of NUL characters and do not make use of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document.<a href="#section-1.1.1-7" class="pilcrow">¶</a></p> +<p id="section-1.1.1-8">Both unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification.<a href="#section-1.1.1-8" class="pilcrow">¶</a></p> +<p id="section-1.1.1-9">Variable-length integer encoding (also known as VarInt or VLQ) is not used in this format. Instead, arbitrarily sized integers, like those used in <a href="#packets" class="auto internal xref">Section 4</a>, are prefixed with a single octet that specifies the number of octets used to contain the integer value. In most cases, this is less space-efficient than VarInt encoding, but it is simpler to understand and to parse.<a href="#section-1.1.1-9" class="pilcrow">¶</a></p> +<p id="section-1.1.1-10">Boolean values <span class="bcp14">MUST</span> be a single octet with the value of <code>0</code> for <strong>FALSE</strong> or <code>1</code> for <strong>TRUE</strong>.<a href="#section-1.1.1-10" class="pilcrow">¶</a></p> +<span class="break"></span><dl class="dlParallel" id="section-1.1.1-11"> + <dt id="section-1.1.1-11.1"><code>[N octets]</code></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.2">A sequence of octets with a length of N<a href="#section-1.1.1-11.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> -<dt id="section-1.1.1-10.3"><code>[00 7F FF]</code></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.4">A sequence of octets <code>00</code>, <code>7F</code>, and <code>FF</code> in that order.<a href="#section-1.1.1-10.4" class="pilcrow">¶</a> +<dt id="section-1.1.1-11.3"><code>[00 7F FF]</code></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.4">A sequence of octets <code>00</code>, <code>7F</code>, and <code>FF</code> in that order.<a href="#section-1.1.1-11.4" class="pilcrow">¶</a> </dd> <dd class="break"></dd> -<dt id="section-1.1.1-10.5"><strong>0-indexed</strong></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.6">When counting sequentially, start counting at 0.<a href="#section-1.1.1-10.6" class="pilcrow">¶</a> +<dt id="section-1.1.1-11.5"><strong>0-indexed</strong></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.6">When counting sequentially, start counting at 0.<a href="#section-1.1.1-11.6" class="pilcrow">¶</a> </dd> <dd class="break"></dd> -<dt id="section-1.1.1-10.7"><strong>1-indexed</strong></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.8">When counting sequentially, start counting at 1.<a href="#section-1.1.1-10.8" class="pilcrow">¶</a> +<dt id="section-1.1.1-11.7"><strong>1-indexed</strong></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.8">When counting sequentially, start counting at 1.<a href="#section-1.1.1-11.8" class="pilcrow">¶</a> </dd> <dd class="break"></dd> </dl> -<p id="section-1.1.1-11">In packet diagrams, a single octet is represented with a box like this:<a href="#section-1.1.1-11" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-12"> +<p id="section-1.1.1-12">In packet diagrams, a single octet is represented with a box like this:<a href="#section-1.1.1-12" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-13"> <pre> +-----+ | Var | <-- Vertical bars MAY be missing +-----+ -</pre><a href="#section-1.1.1-12" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-13" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-13.1"> - <strong>Var</strong> is a variable name.<a href="#section-1.1.1-13.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-14.1"> + <strong>Var</strong> is a variable name.<a href="#section-1.1.1-14.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-14">In packet diagrams, an arbitrary number of octets are represented with a box like this:<a href="#section-1.1.1-14" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-15"> +<p id="section-1.1.1-15">In packet diagrams, an arbitrary number of octets are represented with a box like this:<a href="#section-1.1.1-15" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-16"> <pre> +=====+ | Var | +=====+ -</pre><a href="#section-1.1.1-15" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-16" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-16.1"> - <strong>Var</strong> is a variable name.<a href="#section-1.1.1-16.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-17.1"> + <strong>Var</strong> is a variable name.<a href="#section-1.1.1-17.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-17">In packet diagrams, boxes can be connected like these examples:<a href="#section-1.1.1-17" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-18"> +<p id="section-1.1.1-18">In packet diagrams, boxes can be connected like these examples:<a href="#section-1.1.1-18" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-19"> <pre> +-----------+-----------+ | Var 1 (B) | Var 2 (I) | +-----------+-----------+ -</pre><a href="#section-1.1.1-18" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-19" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-19.1">In this example, <strong>Var 1</strong> is a 1 octet long boolean value and <strong>Var 2</strong> is a 1 octet long signed integer.<a href="#section-1.1.1-19.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-20.1">In this example, <strong>Var 1</strong> is a 1 octet long boolean value and <strong>Var 2</strong> is a 1 octet long signed integer.<a href="#section-1.1.1-20.1" class="pilcrow">¶</a> </li> </ul> -<div class="alignLeft art-text artwork" id="section-1.1.1-20"> +<div class="alignLeft art-text artwork" id="section-1.1.1-21"> <pre> +-----+-----+===========+ | Var 1 (N) | Var 2 (S) | +-----+-----+===========+ -</pre><a href="#section-1.1.1-20" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-21" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-21.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-21.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-22.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-22.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-22">In packet diagrams, boxes <span class="bcp14">MAY</span> have relative offset values above them like in the following example:<a href="#section-1.1.1-22" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-23"> +<p id="section-1.1.1-23">In packet diagrams, boxes <span class="bcp14">MAY</span> have relative offset values above them like in the following example:<a href="#section-1.1.1-23" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-24"> <pre> 0 1 2... +-----+-----+===========+ | Var 1 (N) | Var 2 (S) | +-----+-----+===========+ -</pre><a href="#section-1.1.1-23" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-24" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-24.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-24.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-25.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-25.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-25">Packet diagrams <span class="bcp14">MAY</span> be split into multiple lined sections like in the following example:<a href="#section-1.1.1-25" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-26"> +<p id="section-1.1.1-26">Packet diagrams <span class="bcp14">MAY</span> be split into multiple lined sections like in the following example:<a href="#section-1.1.1-26" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-27"> <pre> 0 1 2 3 +-----------+-----------+-----------+-----------+ @@ -1739,10 +1740,10 @@ li > p:last-of-type:only-child { +-----------+===========+ | Var 5 (N) | Var 6 (S) | +-----------+===========+ -</pre><a href="#section-1.1.1-26" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-27" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-27.1">In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain consistent horizontal spacing in this documentation. The packet diagram is separated by an ellipsis (<code>...</code>) on the same text row as the variable names to signify that the packet diagram is continuing.<a href="#section-1.1.1-27.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-28.1">In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain consistent horizontal spacing in this document. The packet diagram is separated by an ellipsis (<code>...</code>) on the same text row as the variable names to signify that the packet diagram is continuing.<a href="#section-1.1.1-28.1" class="pilcrow">¶</a> </li> </ul> </section> @@ -1751,7 +1752,7 @@ li > p:last-of-type:only-child { <h3 id="name-motivations"> <a href="#section-1.2" class="section-number selfRef">1.2. </a><a href="#name-motivations" class="section-name selfRef">Motivations</a> </h3> -<p id="section-1.2-1">This file format's primary goal is to provide a comprehensive and replay device agnostic TAS movie controller input dump format that is usable for any console. Additional goals include:<a href="#section-1.2-1" class="pilcrow">¶</a></p> +<p id="section-1.2-1">This file format's primary goal is to provide a comprehensive and replay device agnostic TAS input dump format that is usable for any console. Additional goals include:<a href="#section-1.2-1" class="pilcrow">¶</a></p> <ul class="normal"> <li class="normal" id="section-1.2-2.1">No intermediary formats<a href="#section-1.2-2.1" class="pilcrow">¶</a> </li> @@ -1820,7 +1821,7 @@ li > p:last-of-type:only-child { </div> <span class="break"></span><dl class="dlNewline" id="section-3-3"> <dt id="section-3-3.1"><strong>Magic Number</strong></dt> - <dd style="margin-left: 1.5em" id="section-3-3.2">4 octet value that <span class="bcp14">MUST</span> be <code>[54 41 53 44]</code>(ASCII value <code>TASD</code>).<a href="#section-3-3.2" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-3-3.2">4 octet value that <span class="bcp14">MUST</span> be <code>[54 41 53 44]</code> (ASCII value <code>TASD</code>).<a href="#section-3-3.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-3-3.3"><strong>Version</strong></dt> @@ -2273,12 +2274,12 @@ li > p:last-of-type:only-child { <span class="break"></span><dl class="dlNewline" id="section-4.2.5-1"> <dt id="section-4.2.5-1.1"> <code>[FE 01]</code> - INPUT_CHUNK</dt> - <dd style="margin-left: 1.5em" id="section-4.2.5-1.2">Specifies a chunk of input data for the TAS when played on hardware. All data from INPUT_CHUNK packets are concatenated together in order of appearance in the <strong>TASD</strong> file. If the INPUT_CHUNK packet type is used in a TASD file, the PORT_CONTROLLER packet type <span class="bcp14">MUST</span> also be used at least once. If the INPUT_CHUNK packet type is used, the INPUT_MOMENT packet type <span class="bcp14">SHOULD NOT</span> be used. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_chunk" class="auto internal xref">Section 4.3.5.1</a>).<a href="#section-4.2.5-1.2" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.2.5-1.2">Specifies a chunk of input data for the TAS when played on hardware. All data from INPUT_CHUNK packets for each controller port are concatenated together in order of appearance in the <strong>TASD</strong> file. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_chunk" class="auto internal xref">Section 4.3.5.1</a>).<a href="#section-4.2.5-1.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.2.5-1.3"> <code>[FE 02]</code> - INPUT_MOMENT</dt> - <dd style="margin-left: 1.5em" id="section-4.2.5-1.4">Specifies a single instance of input data that is sent from the replay device to the console with specific timing. If the INPUT_MOMENT packet type is used in a TASD file, the PORT_CONTROLLER packet type <span class="bcp14">MUST</span> also be used at least once. If the INPUT_MOMENT packet type is used, the INPUT_CHUNK packet type <span class="bcp14">SHOULD NOT</span> be used. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_moment" class="auto internal xref">Section 4.3.5.2</a>).<a href="#section-4.2.5-1.4" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.2.5-1.4">Specifies a single instance of input data that is sent from the replay device to the console with specific timing. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_moment" class="auto internal xref">Section 4.3.5.2</a>).<a href="#section-4.2.5-1.4" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.2.5-1.5"> @@ -2394,7 +2395,7 @@ li > p:last-of-type:only-child { </div> <span class="break"></span><dl class="dlNewline" id="section-4.3.1.2-3"> <dt id="section-4.3.1.2-3.1"><strong>Video Signal</strong></dt> - <dd style="margin-left: 1.5em" id="section-4.3.1.2-3.2">Specifies the video signal of the game console being emulated while dumping the TAS movie controller inputs.<a href="#section-4.3.1.2-3.2" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.3.1.2-3.2">Specifies the video signal of the game console being emulated while dumping the TAS movie's controller inputs.<a href="#section-4.3.1.2-3.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> </dl> @@ -2889,10 +2890,14 @@ li > p:last-of-type:only-child { <p id="section-4.3.1.19-1">GAME_IDENTIFIER packets <span class="bcp14">MUST</span> be in the following format:<a href="#section-4.3.1.19-1" class="pilcrow">¶</a></p> <div class="alignLeft art-text artwork" id="section-4.3.1.19-2"> <pre> - 0 1 2 3... 3+NLEN... - +----------+--------------+----------+==========+================+ - | Type (A) | Encoding (A) | NLEN (N) | Name (S) | Identifier (A) | - +----------+--------------+----------+==========+================+ + 0 1 2 3... + +----------+--------------+----------+==========+ + | Type (A) | Encoding (A) | NLEN (N) | Name (S) | ... + +----------+--------------+----------+==========+ + 3+NLEN... + +================+ + | Identifier (A) | + +================+ Type (Binary Data): [1 octet] [01] - MD5 Hash @@ -2917,7 +2922,8 @@ li > p:last-of-type:only-child { [04] - Base 64 NLEN (Unsigned Integer) [1 octet] Name (String) [NLEN octets] - Identifier (Binary Data) [PLEN - 2 octets] + Identifier (Binary Data) [PLEN - NLEN - + 3 octets] </pre><a href="#section-4.3.1.19-2" class="pilcrow">¶</a> </div> <span class="break"></span><dl class="dlNewline" id="section-4.3.1.19-3"> @@ -3389,7 +3395,8 @@ li > p:last-of-type:only-child { [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 + [04] - Microseconds + [05] - Nanoseconds Index (Unsigned Integer) [8 octets] Inputs (Binary Data) [PLEN - 11 octets] @@ -3401,7 +3408,7 @@ li > p:last-of-type:only-child { </dd> <dd class="break"></dd> <dt id="section-4.3.5.2-3.3"><strong>Hold</strong></dt> - <dd style="margin-left: 1.5em" id="section-4.3.5.2-3.4">Determines whether the <strong>Input</strong> data <span class="bcp14">MUST</span> continue to be held after the controller state has been read.<a href="#section-4.3.5.2-3.4" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.3.5.2-3.4">If <strong>TRUE</strong>, the <strong>Input</strong> data <span class="bcp14">MUST</span> continue to be held after the controller state has been read. Otherwise if <strong>FALSE</strong>, the <strong>Input</strong> data is held only until the data has been used once.<a href="#section-4.3.5.2-3.4" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.3.5.2-3.5"><strong>Index Type</strong></dt> @@ -3423,6 +3430,7 @@ li > p:last-of-type:only-child { </dl> <p id="section-4.3.5.2-4">Each INPUT_MOMENT packet contains a single instance of controller input data for a specific moment during a TAS replay. The input data's format depends on the PORT_CONTROLLER type corresponding to the <strong>Port</strong> number. Refer to <a href="#controller_inputs" class="auto internal xref">Section 5</a> for each available type. The PORT_CONTROLLER type <span class="bcp14">MAY</span> be changed using TRANSITION packets, which <span class="bcp14">MAY</span> change the interpretation of the input data.<a href="#section-4.3.5.2-4" class="pilcrow">¶</a></p> <p id="section-4.3.5.2-5">If <strong>Hold</strong> is <strong>TRUE</strong>, the controller <span class="bcp14">MUST</span> continually hold the input state until the next INPUT_MOMENT for the same <strong>Port</strong> number. If <strong>Hold</strong> is <strong>FALSE</strong>, the controller <span class="bcp14">MUST</span> hold only until the console reads the input state, or until the next INPUT_MOMENT for the same <strong>Port</strong> number.<a href="#section-4.3.5.2-5" class="pilcrow">¶</a></p> +<p id="section-4.3.5.2-6">If an INPUT_MOMENT overlaps with input data from one or more INPUT_CHUNKs, the INPUT_MOMENT's <strong>Input</strong> data <span class="bcp14">MUST</span> be used instead of the data contained in the INPUT_CHUNKs. INPUT_CHUNK data <span class="bcp14">MUST</span> still be incremented as it normally would. <strong>Hold</strong> <span class="bcp14">MUST</span> still behave as specified.<a href="#section-4.3.5.2-6" class="pilcrow">¶</a></p> </section> </div> <div id="transition"> @@ -3446,8 +3454,9 @@ li > p:last-of-type:only-child { [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 - [05] - INPUT_CHUNK Byte Index + [04] - Microseconds + [05] - Nanoseconds + [06] - INPUT_CHUNK Byte Index Port (Unsigned Integer) [1 octet] Index (Unsigned Integer) [8 octets] Type (Binary Data): [1 octet] @@ -3468,7 +3477,7 @@ li > p:last-of-type:only-child { </dd> <dd class="break"></dd> <dt id="section-4.3.5.3-3.5"><strong>Index</strong></dt> - <dd style="margin-left: 1.5em" id="section-4.3.5.3-3.6">Time or offset value to start transition. If <strong>Index Type</strong> is <code>[05]</code>, <strong>Index</strong> <span class="bcp14">MUST</span> be interpreted as the <strong>byte offset</strong> (<strong>0-indexed</strong>) into the concatenated input data from all <strong>INPUT_CHUNK</strong> packets for the controller port specified by <strong>Port</strong>. If <strong>Index Type</strong> is <code>[05]</code>, the byte offset <span class="bcp14">MUST</span> also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.)<a href="#section-4.3.5.3-3.6" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.3.5.3-3.6">Time or offset value to start transition. If <strong>Index Type</strong> is <code>[06]</code>, <strong>Index</strong> <span class="bcp14">MUST</span> be interpreted as the <strong>byte offset</strong> (<strong>0-indexed</strong>) into the concatenated input data from all <strong>INPUT_CHUNK</strong> packets for the controller port specified by <strong>Port</strong>. If <strong>Index Type</strong> is <code>[06]</code>, the byte offset <span class="bcp14">MUST</span> also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.)<a href="#section-4.3.5.3-3.6" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.3.5.3-3.7"><strong>Type</strong></dt> diff --git a/docs/latest/draft-tasd-spec.txt b/docs/latest/draft-tasd-spec.txt index 6903ec8..33b32ef 100644 --- a/docs/latest/draft-tasd-spec.txt +++ b/docs/latest/draft-tasd-spec.txt @@ -7,7 +7,7 @@ Independent TAS Console Replay Research Group V. Grey Bigbass rasteri - 1 February 2025 + 16 April 2025 TASD File Format Specification Version 1 @@ -16,13 +16,14 @@ Independent TAS Console Replay Research Group V. Grey Abstract The *TASD* file format is used for storing "Tool Assisted Speedrun" - or "Tool Assisted Superplay" (TAS) data for TAS replay devices to - replay on physical video game console hardware. The format is - defined to be expandable for future needs. The format is also - defined to be parsable by programs that do not understand portions of - the format, whether that is due to incomplete support of the format - specification or due to new features being added to later versions of - the specification at a later date. + or "Tool Assisted Superplay" (TAS) input and configuration data for + use with devices (known as "TAS replay devices") that replay inputs + on physical video game hardware. The format is defined to be + expandable for future needs. The format is also defined to be + parsable by programs that do not understand portions of the format, + whether that is due to incomplete support of the format specification + or due to new features being added to later versions of the + specification. This document defines the file format specification for *TASD* files. @@ -133,8 +134,8 @@ Table of Contents 1. Introduction The Tool Assisted Speedrun Dump (*TASD*) interchange format is a file - format for storing data to allow "Tool Assisted Speedruns" or "Tool - Assisted Superplays" to be played on physical video game console + format for storing data that enables "Tool Assisted Speedruns" or + "Tool Assisted Superplays" to be played on physical video game hardware using TAS replay devices. Created to be hardware and software agnostic, the *TASD* interchange format uses a key-based, binary, packet format to break up pieces of information into easily- @@ -148,9 +149,10 @@ Table of Contents predefined delimiter to separate pieces of data. While files generated by emulator dump scripts should provide as much - information as possible, because packets are optional, the file can - be expanded later with any additional data as desired. No - intermediary file format is necessary. + information as possible, they may be unable to provide everything. + Since packets are optional, the file can be expanded later with any + additional data as desired. No intermediary file format is + necessary. 1.1. Overview and Preliminaries @@ -171,10 +173,10 @@ Table of Contents (B) = Boolean ([]N) = List of Unsigned Integers - We use the terms *byte* and *octet* interchangeably in this document. - Unless specified otherwise, all multi-octet integers are big-endian. + We use the terms *byte* and *octet* interchangeably in this document. + We use the terms *Tool Assisted Speedrun*, *Tool Assisted Superplay* and *TAS* interchangeably in this document. @@ -184,18 +186,25 @@ Table of Contents MOVIE_TRANSITION packet (second order packet). String values MUST use UTF-8 encoding. As such, string values MAY - contain any number of NUL characters and have no concept of "null + contain any number of NUL characters and do not make use of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document. - Unsigned and signed integers can have different bit widths. For + Both unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification. + Variable-length integer encoding (also known as VarInt or VLQ) is not + used in this format. Instead, arbitrarily sized integers, like those + used in Section 4, are prefixed with a single octet that specifies + the number of octets used to contain the integer value. In most + cases, this is less space-efficient than VarInt encoding, but it is + simpler to understand and to parse. + Boolean values MUST be a single octet with the value of 0 for *FALSE* or 1 for *TRUE*. @@ -266,7 +275,7 @@ Table of Contents In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain - consistent horizontal spacing in this documentation. The packet + consistent horizontal spacing in this document. The packet diagram is separated by an ellipsis (...) on the same text row as the variable names to signify that the packet diagram is continuing. @@ -274,8 +283,8 @@ Table of Contents 1.2. Motivations This file format's primary goal is to provide a comprehensive and - replay device agnostic TAS movie controller input dump format that is - usable for any console. Additional goals include: + replay device agnostic TAS input dump format that is usable for any + console. Additional goals include: * No intermediary formats @@ -342,7 +351,7 @@ Table of Contents G_KEYLEN (Unsigned Integer) [1 octet] *Magic Number* - 4 octet value that MUST be [54 41 53 44](ASCII value TASD). + 4 octet value that MUST be [54 41 53 44] (ASCII value TASD). *Version* Version of the *TASD* file format. Version currently MUST be a @@ -640,24 +649,17 @@ Table of Contents [FE 01] - INPUT_CHUNK Specifies a chunk of input data for the TAS when played on - hardware. All data from INPUT_CHUNK packets are concatenated - together in order of appearance in the *TASD* file. If the - INPUT_CHUNK packet type is used in a TASD file, the - PORT_CONTROLLER packet type MUST also be used at least once. If - the INPUT_CHUNK packet type is used, the INPUT_MOMENT packet type - SHOULD NOT be used. This packet type is OPTIONAL and a *TASD* - file MAY contain more than 1 of this packet type. Discussed in + hardware. All data from INPUT_CHUNK packets for each controller + port are concatenated together in order of appearance in the + *TASD* file. This packet type is OPTIONAL and a *TASD* file MAY + contain more than 1 of this packet type. Discussed in (Section 4.3.5.1). [FE 02] - INPUT_MOMENT Specifies a single instance of input data that is sent from the - replay device to the console with specific timing. If the - INPUT_MOMENT packet type is used in a TASD file, the - PORT_CONTROLLER packet type MUST also be used at least once. If - the INPUT_MOMENT packet type is used, the INPUT_CHUNK packet type - SHOULD NOT be used. This packet type is OPTIONAL and a *TASD* - file MAY contain more than 1 of this packet type. Discussed in - (Section 4.3.5.2). + replay device to the console with specific timing. This packet + type is OPTIONAL and a *TASD* file MAY contain more than 1 of this + packet type. Discussed in (Section 4.3.5.2). [FE 03] - TRANSITION Specifies when a transition or change occurs during a TAS replay @@ -747,7 +749,7 @@ Table of Contents *Video Signal* Specifies the video signal of the game console being emulated - while dumping the TAS movie controller inputs. + while dumping the TAS movie's controller inputs. 4.3.1.3. GAME_TITLE Packet @@ -1090,35 +1092,40 @@ Table of Contents GAME_IDENTIFIER packets MUST be in the following format: - 0 1 2 3... 3+NLEN... - +----------+--------------+----------+==========+================+ - | Type (A) | Encoding (A) | NLEN (N) | Name (S) | Identifier (A) | - +----------+--------------+----------+==========+================+ - - Type (Binary Data): [1 octet] - [01] - MD5 Hash - [02] - SHA1 Hash - [03] - SHA224 Hash - [04] - SHA256 Hash - [05] - SHA384 Hash - [06] - SHA512 Hash - [07] - SHA512/224 Hash - [08] - SHA512/256 Hash - [09] - SHA3-224 Hash - [0A] - SHA3-256 Hash - [0B] - SHA3-384 Hash - [0C] - SHA3-512 Hash - [0D] - SHAKE-128 Hash - [0E] - SHAKE-256 Hash - [FF] - Other - Encoding (Binary Data): [1 octet] - [01] - Raw Binary - [02] - Base 16 (Case Insensitive) - [03] - Base 32 (Case Insensitive) - [04] - Base 64 - NLEN (Unsigned Integer) [1 octet] - Name (String) [NLEN octets] - Identifier (Binary Data) [PLEN - 2 octets] + 0 1 2 3... + +----------+--------------+----------+==========+ + | Type (A) | Encoding (A) | NLEN (N) | Name (S) | ... + +----------+--------------+----------+==========+ + 3+NLEN... + +================+ + | Identifier (A) | + +================+ + + Type (Binary Data): [1 octet] + [01] - MD5 Hash + [02] - SHA1 Hash + [03] - SHA224 Hash + [04] - SHA256 Hash + [05] - SHA384 Hash + [06] - SHA512 Hash + [07] - SHA512/224 Hash + [08] - SHA512/256 Hash + [09] - SHA3-224 Hash + [0A] - SHA3-256 Hash + [0B] - SHA3-384 Hash + [0C] - SHA3-512 Hash + [0D] - SHAKE-128 Hash + [0E] - SHAKE-256 Hash + [FF] - Other + Encoding (Binary Data): [1 octet] + [01] - Raw Binary + [02] - Base 16 (Case Insensitive) + [03] - Base 32 (Case Insensitive) + [04] - Base 64 + NLEN (Unsigned Integer) [1 octet] + Name (String) [NLEN octets] + Identifier (Binary Data) [PLEN - NLEN - + 3 octets] *Type* Hash, checksum, or identifier algorithm used to create the @@ -1468,7 +1475,8 @@ Table of Contents [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 + [04] - Microseconds + [05] - Nanoseconds Index (Unsigned Integer) [8 octets] Inputs (Binary Data) [PLEN - 11 octets] @@ -1477,8 +1485,9 @@ Table of Contents Controller port number (*Port* number MUST be *1-indexed*). *Hold* - Determines whether the *Input* data MUST continue to be held after - the controller state has been read. + If *TRUE*, the *Input* data MUST continue to be held after the + controller state has been read. Otherwise if *FALSE*, the *Input* + data is held only until the data has been used once. *Index Type* Specifies timing methodology of a specific moment when *Input* @@ -1508,6 +1517,12 @@ Table of Contents reads the input state, or until the next INPUT_MOMENT for the same *Port* number. + If an INPUT_MOMENT overlaps with input data from one or more + INPUT_CHUNKs, the INPUT_MOMENT's *Input* data MUST be used instead of + the data contained in the INPUT_CHUNKs. INPUT_CHUNK data MUST still + be incremented as it normally would. *Hold* MUST still behave as + specified. + 4.3.5.3. TRANSITION Packet TRANSITION packets MUST be in the following format: @@ -1525,8 +1540,9 @@ Table of Contents [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 - [05] - INPUT_CHUNK Byte Index + [04] - Microseconds + [05] - Nanoseconds + [06] - INPUT_CHUNK Byte Index Port (Unsigned Integer) [1 octet] Index (Unsigned Integer) [8 octets] Type (Binary Data): [1 octet] @@ -1544,10 +1560,10 @@ Table of Contents *Index* Time or offset value to start transition. If *Index Type* is - [05], *Index* MUST be interpreted as the *byte offset* + [06], *Index* MUST be interpreted as the *byte offset* (*0-indexed*) into the concatenated input data from all *INPUT_CHUNK* packets for the controller port specified by *Port*. - If *Index Type* is [05], the byte offset MUST also point to the + If *Index Type* is [06], the byte offset MUST also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.) diff --git a/docs/tasd-spec-0001/draft-tasd-spec-0001.html b/docs/tasd-spec-0001/draft-tasd-spec-0001.html index a216583..e3a41cc 100644 --- a/docs/tasd-spec-0001/draft-tasd-spec-0001.html +++ b/docs/tasd-spec-0001/draft-tasd-spec-0001.html @@ -9,7 +9,7 @@ <meta content="Bigbass" name="author"> <meta content="rasteri" name="author"> <meta content=' - The TASD file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) data for TAS replay devices to replay on physical video game console hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification at a later date. + The TASD file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) input and configuration data for use with devices (known as "TAS replay devices") that replay inputs on physical video game hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification. This document defines the file format specification for TASD files. ' name="description"> <meta content="xml2rfc 3.20.0" name="generator"> @@ -1211,7 +1211,7 @@ li > p:last-of-type:only-child { <thead><tr> <td class="left"></td> <td class="center">TASD File Format Specification</td> -<td class="right">February 2025</td> +<td class="right">April 2025</td> </tr></thead> <tfoot><tr> <td class="left">Grey, et al.</td> @@ -1226,7 +1226,7 @@ li > p:last-of-type:only-child { <dd class="workgroup">Independent TAS Console Replay Research Group</dd> <dt class="label-published">Published:</dt> <dd class="published"> -<time datetime="2025-02-01" class="published">1 February 2025</time> +<time datetime="2025-04-16" class="published">16 April 2025</time> </dd> <dt class="label-authors">Authors:</dt> <dd class="authors"> @@ -1245,7 +1245,7 @@ li > p:last-of-type:only-child { <h1 id="title">TASD File Format Specification Version 1</h1> <section id="section-abstract"> <h2 id="abstract"><a href="#abstract" class="selfRef">Abstract</a></h2> -<p id="section-abstract-1">The <strong>TASD</strong> file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) data for TAS replay devices to replay on physical video game console hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification at a later date.<a href="#section-abstract-1" class="pilcrow">¶</a></p> +<p id="section-abstract-1">The <strong>TASD</strong> file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) input and configuration data for use with devices (known as "TAS replay devices") that replay inputs on physical video game hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification.<a href="#section-abstract-1" class="pilcrow">¶</a></p> <p id="section-abstract-2">This document defines the file format specification for <strong>TASD</strong> files.<a href="#section-abstract-2" class="pilcrow">¶</a></p> </section> <div id="toc"> @@ -1614,9 +1614,9 @@ li > p:last-of-type:only-child { <h2 id="name-introduction"> <a href="#section-1" class="section-number selfRef">1. </a><a href="#name-introduction" class="section-name selfRef">Introduction</a> </h2> -<p id="section-1-1">The Tool Assisted Speedrun Dump (<strong>TASD</strong>) interchange format is a file format for storing data to allow "Tool Assisted Speedruns" or "Tool Assisted Superplays" to be played on physical video game console hardware using TAS replay devices. Created to be hardware and software agnostic, the <strong>TASD</strong> interchange format uses a key-based, binary, packet format to break up pieces of information into easily-parsable and forward-compatible chunks. The format is extensible by simply defining additional keys or value types as necessary. When parsing the file, software can skip any packets whose key is unknown or unsupported.<a href="#section-1-1" class="pilcrow">¶</a></p> +<p id="section-1-1">The Tool Assisted Speedrun Dump (<strong>TASD</strong>) interchange format is a file format for storing data that enables "Tool Assisted Speedruns" or "Tool Assisted Superplays" to be played on physical video game hardware using TAS replay devices. Created to be hardware and software agnostic, the <strong>TASD</strong> interchange format uses a key-based, binary, packet format to break up pieces of information into easily-parsable and forward-compatible chunks. The format is extensible by simply defining additional keys or value types as necessary. When parsing the file, software can skip any packets whose key is unknown or unsupported.<a href="#section-1-1" class="pilcrow">¶</a></p> <p id="section-1-2">Packets of a given type can be used multiple times or completely omitted as needed. This reusability eliminates the need of a predefined delimiter to separate pieces of data.<a href="#section-1-2" class="pilcrow">¶</a></p> -<p id="section-1-3">While files generated by emulator dump scripts should provide as much information as possible, because packets are optional, the file can be expanded later with any additional data as desired. No intermediary file format is necessary.<a href="#section-1-3" class="pilcrow">¶</a></p> +<p id="section-1-3">While files generated by emulator dump scripts should provide as much information as possible, they may be unable to provide everything. Since packets are optional, the file can be expanded later with any additional data as desired. No intermediary file format is necessary.<a href="#section-1-3" class="pilcrow">¶</a></p> <section id="section-1.1"> <h3 id="name-overview-and-preliminaries"> <a href="#section-1.1" class="section-number selfRef">1.1. </a><a href="#name-overview-and-preliminaries" class="section-name selfRef">Overview and Preliminaries</a> @@ -1641,95 +1641,96 @@ li > p:last-of-type:only-child { <li class="compact ulEmpty" id="section-1.1.1-2.6">([]N) = List of Unsigned Integers<a href="#section-1.1.1-2.6" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-3">We use the terms <strong>byte</strong> and <strong>octet</strong> interchangeably in this document.<a href="#section-1.1.1-3" class="pilcrow">¶</a></p> -<p id="section-1.1.1-4">Unless specified otherwise, all multi-octet integers are big-endian.<a href="#section-1.1.1-4" class="pilcrow">¶</a></p> +<p id="section-1.1.1-3">Unless specified otherwise, all multi-octet integers are big-endian.<a href="#section-1.1.1-3" class="pilcrow">¶</a></p> +<p id="section-1.1.1-4">We use the terms <strong>byte</strong> and <strong>octet</strong> interchangeably in this document.<a href="#section-1.1.1-4" class="pilcrow">¶</a></p> <p id="section-1.1.1-5">We use the terms <strong>Tool Assisted Speedrun</strong>, <strong>Tool Assisted Superplay</strong> and <strong>TAS</strong> interchangeably in this document.<a href="#section-1.1.1-5" class="pilcrow">¶</a></p> <p id="section-1.1.1-6">In subsections of (<a href="#descriptions" class="auto internal xref">Section 4.2</a>), the term "in direct form" is used. That term is defined to mean a packet in a <strong>TASD</strong> file directly (first order packet) rather than a packet inside a TRANSITION or MOVIE_TRANSITION packet (second order packet).<a href="#section-1.1.1-6" class="pilcrow">¶</a></p> -<p id="section-1.1.1-7">String values <span class="bcp14">MUST</span> use UTF-8 encoding. As such, string values <span class="bcp14">MAY</span> contain any number of NUL characters and have no concept of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document.<a href="#section-1.1.1-7" class="pilcrow">¶</a></p> -<p id="section-1.1.1-8">Unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification.<a href="#section-1.1.1-8" class="pilcrow">¶</a></p> -<p id="section-1.1.1-9">Boolean values <span class="bcp14">MUST</span> be a single octet with the value of <code>0</code> for <strong>FALSE</strong> or <code>1</code> for <strong>TRUE</strong>.<a href="#section-1.1.1-9" class="pilcrow">¶</a></p> -<span class="break"></span><dl class="dlParallel" id="section-1.1.1-10"> - <dt id="section-1.1.1-10.1"><code>[N octets]</code></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.2">A sequence of octets with a length of N<a href="#section-1.1.1-10.2" class="pilcrow">¶</a> +<p id="section-1.1.1-7">String values <span class="bcp14">MUST</span> use UTF-8 encoding. As such, string values <span class="bcp14">MAY</span> contain any number of NUL characters and do not make use of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document.<a href="#section-1.1.1-7" class="pilcrow">¶</a></p> +<p id="section-1.1.1-8">Both unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification.<a href="#section-1.1.1-8" class="pilcrow">¶</a></p> +<p id="section-1.1.1-9">Variable-length integer encoding (also known as VarInt or VLQ) is not used in this format. Instead, arbitrarily sized integers, like those used in <a href="#packets" class="auto internal xref">Section 4</a>, are prefixed with a single octet that specifies the number of octets used to contain the integer value. In most cases, this is less space-efficient than VarInt encoding, but it is simpler to understand and to parse.<a href="#section-1.1.1-9" class="pilcrow">¶</a></p> +<p id="section-1.1.1-10">Boolean values <span class="bcp14">MUST</span> be a single octet with the value of <code>0</code> for <strong>FALSE</strong> or <code>1</code> for <strong>TRUE</strong>.<a href="#section-1.1.1-10" class="pilcrow">¶</a></p> +<span class="break"></span><dl class="dlParallel" id="section-1.1.1-11"> + <dt id="section-1.1.1-11.1"><code>[N octets]</code></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.2">A sequence of octets with a length of N<a href="#section-1.1.1-11.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> -<dt id="section-1.1.1-10.3"><code>[00 7F FF]</code></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.4">A sequence of octets <code>00</code>, <code>7F</code>, and <code>FF</code> in that order.<a href="#section-1.1.1-10.4" class="pilcrow">¶</a> +<dt id="section-1.1.1-11.3"><code>[00 7F FF]</code></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.4">A sequence of octets <code>00</code>, <code>7F</code>, and <code>FF</code> in that order.<a href="#section-1.1.1-11.4" class="pilcrow">¶</a> </dd> <dd class="break"></dd> -<dt id="section-1.1.1-10.5"><strong>0-indexed</strong></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.6">When counting sequentially, start counting at 0.<a href="#section-1.1.1-10.6" class="pilcrow">¶</a> +<dt id="section-1.1.1-11.5"><strong>0-indexed</strong></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.6">When counting sequentially, start counting at 0.<a href="#section-1.1.1-11.6" class="pilcrow">¶</a> </dd> <dd class="break"></dd> -<dt id="section-1.1.1-10.7"><strong>1-indexed</strong></dt> - <dd style="margin-left: 1.5em" id="section-1.1.1-10.8">When counting sequentially, start counting at 1.<a href="#section-1.1.1-10.8" class="pilcrow">¶</a> +<dt id="section-1.1.1-11.7"><strong>1-indexed</strong></dt> + <dd style="margin-left: 1.5em" id="section-1.1.1-11.8">When counting sequentially, start counting at 1.<a href="#section-1.1.1-11.8" class="pilcrow">¶</a> </dd> <dd class="break"></dd> </dl> -<p id="section-1.1.1-11">In packet diagrams, a single octet is represented with a box like this:<a href="#section-1.1.1-11" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-12"> +<p id="section-1.1.1-12">In packet diagrams, a single octet is represented with a box like this:<a href="#section-1.1.1-12" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-13"> <pre> +-----+ | Var | <-- Vertical bars MAY be missing +-----+ -</pre><a href="#section-1.1.1-12" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-13" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-13.1"> - <strong>Var</strong> is a variable name.<a href="#section-1.1.1-13.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-14.1"> + <strong>Var</strong> is a variable name.<a href="#section-1.1.1-14.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-14">In packet diagrams, an arbitrary number of octets are represented with a box like this:<a href="#section-1.1.1-14" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-15"> +<p id="section-1.1.1-15">In packet diagrams, an arbitrary number of octets are represented with a box like this:<a href="#section-1.1.1-15" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-16"> <pre> +=====+ | Var | +=====+ -</pre><a href="#section-1.1.1-15" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-16" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-16.1"> - <strong>Var</strong> is a variable name.<a href="#section-1.1.1-16.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-17.1"> + <strong>Var</strong> is a variable name.<a href="#section-1.1.1-17.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-17">In packet diagrams, boxes can be connected like these examples:<a href="#section-1.1.1-17" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-18"> +<p id="section-1.1.1-18">In packet diagrams, boxes can be connected like these examples:<a href="#section-1.1.1-18" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-19"> <pre> +-----------+-----------+ | Var 1 (B) | Var 2 (I) | +-----------+-----------+ -</pre><a href="#section-1.1.1-18" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-19" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-19.1">In this example, <strong>Var 1</strong> is a 1 octet long boolean value and <strong>Var 2</strong> is a 1 octet long signed integer.<a href="#section-1.1.1-19.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-20.1">In this example, <strong>Var 1</strong> is a 1 octet long boolean value and <strong>Var 2</strong> is a 1 octet long signed integer.<a href="#section-1.1.1-20.1" class="pilcrow">¶</a> </li> </ul> -<div class="alignLeft art-text artwork" id="section-1.1.1-20"> +<div class="alignLeft art-text artwork" id="section-1.1.1-21"> <pre> +-----+-----+===========+ | Var 1 (N) | Var 2 (S) | +-----+-----+===========+ -</pre><a href="#section-1.1.1-20" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-21" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-21.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-21.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-22.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-22.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-22">In packet diagrams, boxes <span class="bcp14">MAY</span> have relative offset values above them like in the following example:<a href="#section-1.1.1-22" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-23"> +<p id="section-1.1.1-23">In packet diagrams, boxes <span class="bcp14">MAY</span> have relative offset values above them like in the following example:<a href="#section-1.1.1-23" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-24"> <pre> 0 1 2... +-----+-----+===========+ | Var 1 (N) | Var 2 (S) | +-----+-----+===========+ -</pre><a href="#section-1.1.1-23" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-24" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-24.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-24.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-25.1">In this example, <strong>Var 1</strong> is a 2 octet long unsigned integer and <strong>Var 2</strong> is an arbitrary octet length string.<a href="#section-1.1.1-25.1" class="pilcrow">¶</a> </li> </ul> -<p id="section-1.1.1-25">Packet diagrams <span class="bcp14">MAY</span> be split into multiple lined sections like in the following example:<a href="#section-1.1.1-25" class="pilcrow">¶</a></p> -<div class="alignLeft art-text artwork" id="section-1.1.1-26"> +<p id="section-1.1.1-26">Packet diagrams <span class="bcp14">MAY</span> be split into multiple lined sections like in the following example:<a href="#section-1.1.1-26" class="pilcrow">¶</a></p> +<div class="alignLeft art-text artwork" id="section-1.1.1-27"> <pre> 0 1 2 3 +-----------+-----------+-----------+-----------+ @@ -1739,10 +1740,10 @@ li > p:last-of-type:only-child { +-----------+===========+ | Var 5 (N) | Var 6 (S) | +-----------+===========+ -</pre><a href="#section-1.1.1-26" class="pilcrow">¶</a> +</pre><a href="#section-1.1.1-27" class="pilcrow">¶</a> </div> <ul class="compact ulEmpty"> -<li class="compact ulEmpty" id="section-1.1.1-27.1">In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain consistent horizontal spacing in this documentation. The packet diagram is separated by an ellipsis (<code>...</code>) on the same text row as the variable names to signify that the packet diagram is continuing.<a href="#section-1.1.1-27.1" class="pilcrow">¶</a> +<li class="compact ulEmpty" id="section-1.1.1-28.1">In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain consistent horizontal spacing in this document. The packet diagram is separated by an ellipsis (<code>...</code>) on the same text row as the variable names to signify that the packet diagram is continuing.<a href="#section-1.1.1-28.1" class="pilcrow">¶</a> </li> </ul> </section> @@ -1751,7 +1752,7 @@ li > p:last-of-type:only-child { <h3 id="name-motivations"> <a href="#section-1.2" class="section-number selfRef">1.2. </a><a href="#name-motivations" class="section-name selfRef">Motivations</a> </h3> -<p id="section-1.2-1">This file format's primary goal is to provide a comprehensive and replay device agnostic TAS movie controller input dump format that is usable for any console. Additional goals include:<a href="#section-1.2-1" class="pilcrow">¶</a></p> +<p id="section-1.2-1">This file format's primary goal is to provide a comprehensive and replay device agnostic TAS input dump format that is usable for any console. Additional goals include:<a href="#section-1.2-1" class="pilcrow">¶</a></p> <ul class="normal"> <li class="normal" id="section-1.2-2.1">No intermediary formats<a href="#section-1.2-2.1" class="pilcrow">¶</a> </li> @@ -1820,7 +1821,7 @@ li > p:last-of-type:only-child { </div> <span class="break"></span><dl class="dlNewline" id="section-3-3"> <dt id="section-3-3.1"><strong>Magic Number</strong></dt> - <dd style="margin-left: 1.5em" id="section-3-3.2">4 octet value that <span class="bcp14">MUST</span> be <code>[54 41 53 44]</code>(ASCII value <code>TASD</code>).<a href="#section-3-3.2" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-3-3.2">4 octet value that <span class="bcp14">MUST</span> be <code>[54 41 53 44]</code> (ASCII value <code>TASD</code>).<a href="#section-3-3.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-3-3.3"><strong>Version</strong></dt> @@ -2273,12 +2274,12 @@ li > p:last-of-type:only-child { <span class="break"></span><dl class="dlNewline" id="section-4.2.5-1"> <dt id="section-4.2.5-1.1"> <code>[FE 01]</code> - INPUT_CHUNK</dt> - <dd style="margin-left: 1.5em" id="section-4.2.5-1.2">Specifies a chunk of input data for the TAS when played on hardware. All data from INPUT_CHUNK packets are concatenated together in order of appearance in the <strong>TASD</strong> file. If the INPUT_CHUNK packet type is used in a TASD file, the PORT_CONTROLLER packet type <span class="bcp14">MUST</span> also be used at least once. If the INPUT_CHUNK packet type is used, the INPUT_MOMENT packet type <span class="bcp14">SHOULD NOT</span> be used. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_chunk" class="auto internal xref">Section 4.3.5.1</a>).<a href="#section-4.2.5-1.2" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.2.5-1.2">Specifies a chunk of input data for the TAS when played on hardware. All data from INPUT_CHUNK packets for each controller port are concatenated together in order of appearance in the <strong>TASD</strong> file. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_chunk" class="auto internal xref">Section 4.3.5.1</a>).<a href="#section-4.2.5-1.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.2.5-1.3"> <code>[FE 02]</code> - INPUT_MOMENT</dt> - <dd style="margin-left: 1.5em" id="section-4.2.5-1.4">Specifies a single instance of input data that is sent from the replay device to the console with specific timing. If the INPUT_MOMENT packet type is used in a TASD file, the PORT_CONTROLLER packet type <span class="bcp14">MUST</span> also be used at least once. If the INPUT_MOMENT packet type is used, the INPUT_CHUNK packet type <span class="bcp14">SHOULD NOT</span> be used. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_moment" class="auto internal xref">Section 4.3.5.2</a>).<a href="#section-4.2.5-1.4" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.2.5-1.4">Specifies a single instance of input data that is sent from the replay device to the console with specific timing. This packet type is <span class="bcp14">OPTIONAL</span> and a <strong>TASD</strong> file <span class="bcp14">MAY</span> contain more than 1 of this packet type. Discussed in (<a href="#input_moment" class="auto internal xref">Section 4.3.5.2</a>).<a href="#section-4.2.5-1.4" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.2.5-1.5"> @@ -2394,7 +2395,7 @@ li > p:last-of-type:only-child { </div> <span class="break"></span><dl class="dlNewline" id="section-4.3.1.2-3"> <dt id="section-4.3.1.2-3.1"><strong>Video Signal</strong></dt> - <dd style="margin-left: 1.5em" id="section-4.3.1.2-3.2">Specifies the video signal of the game console being emulated while dumping the TAS movie controller inputs.<a href="#section-4.3.1.2-3.2" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.3.1.2-3.2">Specifies the video signal of the game console being emulated while dumping the TAS movie's controller inputs.<a href="#section-4.3.1.2-3.2" class="pilcrow">¶</a> </dd> <dd class="break"></dd> </dl> @@ -2889,10 +2890,14 @@ li > p:last-of-type:only-child { <p id="section-4.3.1.19-1">GAME_IDENTIFIER packets <span class="bcp14">MUST</span> be in the following format:<a href="#section-4.3.1.19-1" class="pilcrow">¶</a></p> <div class="alignLeft art-text artwork" id="section-4.3.1.19-2"> <pre> - 0 1 2 3... 3+NLEN... - +----------+--------------+----------+==========+================+ - | Type (A) | Encoding (A) | NLEN (N) | Name (S) | Identifier (A) | - +----------+--------------+----------+==========+================+ + 0 1 2 3... + +----------+--------------+----------+==========+ + | Type (A) | Encoding (A) | NLEN (N) | Name (S) | ... + +----------+--------------+----------+==========+ + 3+NLEN... + +================+ + | Identifier (A) | + +================+ Type (Binary Data): [1 octet] [01] - MD5 Hash @@ -2917,7 +2922,8 @@ li > p:last-of-type:only-child { [04] - Base 64 NLEN (Unsigned Integer) [1 octet] Name (String) [NLEN octets] - Identifier (Binary Data) [PLEN - 2 octets] + Identifier (Binary Data) [PLEN - NLEN - + 3 octets] </pre><a href="#section-4.3.1.19-2" class="pilcrow">¶</a> </div> <span class="break"></span><dl class="dlNewline" id="section-4.3.1.19-3"> @@ -3389,7 +3395,8 @@ li > p:last-of-type:only-child { [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 + [04] - Microseconds + [05] - Nanoseconds Index (Unsigned Integer) [8 octets] Inputs (Binary Data) [PLEN - 11 octets] @@ -3401,7 +3408,7 @@ li > p:last-of-type:only-child { </dd> <dd class="break"></dd> <dt id="section-4.3.5.2-3.3"><strong>Hold</strong></dt> - <dd style="margin-left: 1.5em" id="section-4.3.5.2-3.4">Determines whether the <strong>Input</strong> data <span class="bcp14">MUST</span> continue to be held after the controller state has been read.<a href="#section-4.3.5.2-3.4" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.3.5.2-3.4">If <strong>TRUE</strong>, the <strong>Input</strong> data <span class="bcp14">MUST</span> continue to be held after the controller state has been read. Otherwise if <strong>FALSE</strong>, the <strong>Input</strong> data is held only until the data has been used once.<a href="#section-4.3.5.2-3.4" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.3.5.2-3.5"><strong>Index Type</strong></dt> @@ -3423,6 +3430,7 @@ li > p:last-of-type:only-child { </dl> <p id="section-4.3.5.2-4">Each INPUT_MOMENT packet contains a single instance of controller input data for a specific moment during a TAS replay. The input data's format depends on the PORT_CONTROLLER type corresponding to the <strong>Port</strong> number. Refer to <a href="#controller_inputs" class="auto internal xref">Section 5</a> for each available type. The PORT_CONTROLLER type <span class="bcp14">MAY</span> be changed using TRANSITION packets, which <span class="bcp14">MAY</span> change the interpretation of the input data.<a href="#section-4.3.5.2-4" class="pilcrow">¶</a></p> <p id="section-4.3.5.2-5">If <strong>Hold</strong> is <strong>TRUE</strong>, the controller <span class="bcp14">MUST</span> continually hold the input state until the next INPUT_MOMENT for the same <strong>Port</strong> number. If <strong>Hold</strong> is <strong>FALSE</strong>, the controller <span class="bcp14">MUST</span> hold only until the console reads the input state, or until the next INPUT_MOMENT for the same <strong>Port</strong> number.<a href="#section-4.3.5.2-5" class="pilcrow">¶</a></p> +<p id="section-4.3.5.2-6">If an INPUT_MOMENT overlaps with input data from one or more INPUT_CHUNKs, the INPUT_MOMENT's <strong>Input</strong> data <span class="bcp14">MUST</span> be used instead of the data contained in the INPUT_CHUNKs. INPUT_CHUNK data <span class="bcp14">MUST</span> still be incremented as it normally would. <strong>Hold</strong> <span class="bcp14">MUST</span> still behave as specified.<a href="#section-4.3.5.2-6" class="pilcrow">¶</a></p> </section> </div> <div id="transition"> @@ -3446,8 +3454,9 @@ li > p:last-of-type:only-child { [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 - [05] - INPUT_CHUNK Byte Index + [04] - Microseconds + [05] - Nanoseconds + [06] - INPUT_CHUNK Byte Index Port (Unsigned Integer) [1 octet] Index (Unsigned Integer) [8 octets] Type (Binary Data): [1 octet] @@ -3468,7 +3477,7 @@ li > p:last-of-type:only-child { </dd> <dd class="break"></dd> <dt id="section-4.3.5.3-3.5"><strong>Index</strong></dt> - <dd style="margin-left: 1.5em" id="section-4.3.5.3-3.6">Time or offset value to start transition. If <strong>Index Type</strong> is <code>[05]</code>, <strong>Index</strong> <span class="bcp14">MUST</span> be interpreted as the <strong>byte offset</strong> (<strong>0-indexed</strong>) into the concatenated input data from all <strong>INPUT_CHUNK</strong> packets for the controller port specified by <strong>Port</strong>. If <strong>Index Type</strong> is <code>[05]</code>, the byte offset <span class="bcp14">MUST</span> also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.)<a href="#section-4.3.5.3-3.6" class="pilcrow">¶</a> + <dd style="margin-left: 1.5em" id="section-4.3.5.3-3.6">Time or offset value to start transition. If <strong>Index Type</strong> is <code>[06]</code>, <strong>Index</strong> <span class="bcp14">MUST</span> be interpreted as the <strong>byte offset</strong> (<strong>0-indexed</strong>) into the concatenated input data from all <strong>INPUT_CHUNK</strong> packets for the controller port specified by <strong>Port</strong>. If <strong>Index Type</strong> is <code>[06]</code>, the byte offset <span class="bcp14">MUST</span> also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.)<a href="#section-4.3.5.3-3.6" class="pilcrow">¶</a> </dd> <dd class="break"></dd> <dt id="section-4.3.5.3-3.7"><strong>Type</strong></dt> diff --git a/docs/tasd-spec-0001/draft-tasd-spec-0001.txt b/docs/tasd-spec-0001/draft-tasd-spec-0001.txt index 6903ec8..33b32ef 100644 --- a/docs/tasd-spec-0001/draft-tasd-spec-0001.txt +++ b/docs/tasd-spec-0001/draft-tasd-spec-0001.txt @@ -7,7 +7,7 @@ Independent TAS Console Replay Research Group V. Grey Bigbass rasteri - 1 February 2025 + 16 April 2025 TASD File Format Specification Version 1 @@ -16,13 +16,14 @@ Independent TAS Console Replay Research Group V. Grey Abstract The *TASD* file format is used for storing "Tool Assisted Speedrun" - or "Tool Assisted Superplay" (TAS) data for TAS replay devices to - replay on physical video game console hardware. The format is - defined to be expandable for future needs. The format is also - defined to be parsable by programs that do not understand portions of - the format, whether that is due to incomplete support of the format - specification or due to new features being added to later versions of - the specification at a later date. + or "Tool Assisted Superplay" (TAS) input and configuration data for + use with devices (known as "TAS replay devices") that replay inputs + on physical video game hardware. The format is defined to be + expandable for future needs. The format is also defined to be + parsable by programs that do not understand portions of the format, + whether that is due to incomplete support of the format specification + or due to new features being added to later versions of the + specification. This document defines the file format specification for *TASD* files. @@ -133,8 +134,8 @@ Table of Contents 1. Introduction The Tool Assisted Speedrun Dump (*TASD*) interchange format is a file - format for storing data to allow "Tool Assisted Speedruns" or "Tool - Assisted Superplays" to be played on physical video game console + format for storing data that enables "Tool Assisted Speedruns" or + "Tool Assisted Superplays" to be played on physical video game hardware using TAS replay devices. Created to be hardware and software agnostic, the *TASD* interchange format uses a key-based, binary, packet format to break up pieces of information into easily- @@ -148,9 +149,10 @@ Table of Contents predefined delimiter to separate pieces of data. While files generated by emulator dump scripts should provide as much - information as possible, because packets are optional, the file can - be expanded later with any additional data as desired. No - intermediary file format is necessary. + information as possible, they may be unable to provide everything. + Since packets are optional, the file can be expanded later with any + additional data as desired. No intermediary file format is + necessary. 1.1. Overview and Preliminaries @@ -171,10 +173,10 @@ Table of Contents (B) = Boolean ([]N) = List of Unsigned Integers - We use the terms *byte* and *octet* interchangeably in this document. - Unless specified otherwise, all multi-octet integers are big-endian. + We use the terms *byte* and *octet* interchangeably in this document. + We use the terms *Tool Assisted Speedrun*, *Tool Assisted Superplay* and *TAS* interchangeably in this document. @@ -184,18 +186,25 @@ Table of Contents MOVIE_TRANSITION packet (second order packet). String values MUST use UTF-8 encoding. As such, string values MAY - contain any number of NUL characters and have no concept of "null + contain any number of NUL characters and do not make use of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document. - Unsigned and signed integers can have different bit widths. For + Both unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification. + Variable-length integer encoding (also known as VarInt or VLQ) is not + used in this format. Instead, arbitrarily sized integers, like those + used in Section 4, are prefixed with a single octet that specifies + the number of octets used to contain the integer value. In most + cases, this is less space-efficient than VarInt encoding, but it is + simpler to understand and to parse. + Boolean values MUST be a single octet with the value of 0 for *FALSE* or 1 for *TRUE*. @@ -266,7 +275,7 @@ Table of Contents In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain - consistent horizontal spacing in this documentation. The packet + consistent horizontal spacing in this document. The packet diagram is separated by an ellipsis (...) on the same text row as the variable names to signify that the packet diagram is continuing. @@ -274,8 +283,8 @@ Table of Contents 1.2. Motivations This file format's primary goal is to provide a comprehensive and - replay device agnostic TAS movie controller input dump format that is - usable for any console. Additional goals include: + replay device agnostic TAS input dump format that is usable for any + console. Additional goals include: * No intermediary formats @@ -342,7 +351,7 @@ Table of Contents G_KEYLEN (Unsigned Integer) [1 octet] *Magic Number* - 4 octet value that MUST be [54 41 53 44](ASCII value TASD). + 4 octet value that MUST be [54 41 53 44] (ASCII value TASD). *Version* Version of the *TASD* file format. Version currently MUST be a @@ -640,24 +649,17 @@ Table of Contents [FE 01] - INPUT_CHUNK Specifies a chunk of input data for the TAS when played on - hardware. All data from INPUT_CHUNK packets are concatenated - together in order of appearance in the *TASD* file. If the - INPUT_CHUNK packet type is used in a TASD file, the - PORT_CONTROLLER packet type MUST also be used at least once. If - the INPUT_CHUNK packet type is used, the INPUT_MOMENT packet type - SHOULD NOT be used. This packet type is OPTIONAL and a *TASD* - file MAY contain more than 1 of this packet type. Discussed in + hardware. All data from INPUT_CHUNK packets for each controller + port are concatenated together in order of appearance in the + *TASD* file. This packet type is OPTIONAL and a *TASD* file MAY + contain more than 1 of this packet type. Discussed in (Section 4.3.5.1). [FE 02] - INPUT_MOMENT Specifies a single instance of input data that is sent from the - replay device to the console with specific timing. If the - INPUT_MOMENT packet type is used in a TASD file, the - PORT_CONTROLLER packet type MUST also be used at least once. If - the INPUT_MOMENT packet type is used, the INPUT_CHUNK packet type - SHOULD NOT be used. This packet type is OPTIONAL and a *TASD* - file MAY contain more than 1 of this packet type. Discussed in - (Section 4.3.5.2). + replay device to the console with specific timing. This packet + type is OPTIONAL and a *TASD* file MAY contain more than 1 of this + packet type. Discussed in (Section 4.3.5.2). [FE 03] - TRANSITION Specifies when a transition or change occurs during a TAS replay @@ -747,7 +749,7 @@ Table of Contents *Video Signal* Specifies the video signal of the game console being emulated - while dumping the TAS movie controller inputs. + while dumping the TAS movie's controller inputs. 4.3.1.3. GAME_TITLE Packet @@ -1090,35 +1092,40 @@ Table of Contents GAME_IDENTIFIER packets MUST be in the following format: - 0 1 2 3... 3+NLEN... - +----------+--------------+----------+==========+================+ - | Type (A) | Encoding (A) | NLEN (N) | Name (S) | Identifier (A) | - +----------+--------------+----------+==========+================+ - - Type (Binary Data): [1 octet] - [01] - MD5 Hash - [02] - SHA1 Hash - [03] - SHA224 Hash - [04] - SHA256 Hash - [05] - SHA384 Hash - [06] - SHA512 Hash - [07] - SHA512/224 Hash - [08] - SHA512/256 Hash - [09] - SHA3-224 Hash - [0A] - SHA3-256 Hash - [0B] - SHA3-384 Hash - [0C] - SHA3-512 Hash - [0D] - SHAKE-128 Hash - [0E] - SHAKE-256 Hash - [FF] - Other - Encoding (Binary Data): [1 octet] - [01] - Raw Binary - [02] - Base 16 (Case Insensitive) - [03] - Base 32 (Case Insensitive) - [04] - Base 64 - NLEN (Unsigned Integer) [1 octet] - Name (String) [NLEN octets] - Identifier (Binary Data) [PLEN - 2 octets] + 0 1 2 3... + +----------+--------------+----------+==========+ + | Type (A) | Encoding (A) | NLEN (N) | Name (S) | ... + +----------+--------------+----------+==========+ + 3+NLEN... + +================+ + | Identifier (A) | + +================+ + + Type (Binary Data): [1 octet] + [01] - MD5 Hash + [02] - SHA1 Hash + [03] - SHA224 Hash + [04] - SHA256 Hash + [05] - SHA384 Hash + [06] - SHA512 Hash + [07] - SHA512/224 Hash + [08] - SHA512/256 Hash + [09] - SHA3-224 Hash + [0A] - SHA3-256 Hash + [0B] - SHA3-384 Hash + [0C] - SHA3-512 Hash + [0D] - SHAKE-128 Hash + [0E] - SHAKE-256 Hash + [FF] - Other + Encoding (Binary Data): [1 octet] + [01] - Raw Binary + [02] - Base 16 (Case Insensitive) + [03] - Base 32 (Case Insensitive) + [04] - Base 64 + NLEN (Unsigned Integer) [1 octet] + Name (String) [NLEN octets] + Identifier (Binary Data) [PLEN - NLEN - + 3 octets] *Type* Hash, checksum, or identifier algorithm used to create the @@ -1468,7 +1475,8 @@ Table of Contents [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 + [04] - Microseconds + [05] - Nanoseconds Index (Unsigned Integer) [8 octets] Inputs (Binary Data) [PLEN - 11 octets] @@ -1477,8 +1485,9 @@ Table of Contents Controller port number (*Port* number MUST be *1-indexed*). *Hold* - Determines whether the *Input* data MUST continue to be held after - the controller state has been read. + If *TRUE*, the *Input* data MUST continue to be held after the + controller state has been read. Otherwise if *FALSE*, the *Input* + data is held only until the data has been used once. *Index Type* Specifies timing methodology of a specific moment when *Input* @@ -1508,6 +1517,12 @@ Table of Contents reads the input state, or until the next INPUT_MOMENT for the same *Port* number. + If an INPUT_MOMENT overlaps with input data from one or more + INPUT_CHUNKs, the INPUT_MOMENT's *Input* data MUST be used instead of + the data contained in the INPUT_CHUNKs. INPUT_CHUNK data MUST still + be incremented as it normally would. *Hold* MUST still behave as + specified. + 4.3.5.3. TRANSITION Packet TRANSITION packets MUST be in the following format: @@ -1525,8 +1540,9 @@ Table of Contents [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 - [05] - INPUT_CHUNK Byte Index + [04] - Microseconds + [05] - Nanoseconds + [06] - INPUT_CHUNK Byte Index Port (Unsigned Integer) [1 octet] Index (Unsigned Integer) [8 octets] Type (Binary Data): [1 octet] @@ -1544,10 +1560,10 @@ Table of Contents *Index* Time or offset value to start transition. If *Index Type* is - [05], *Index* MUST be interpreted as the *byte offset* + [06], *Index* MUST be interpreted as the *byte offset* (*0-indexed*) into the concatenated input data from all *INPUT_CHUNK* packets for the controller port specified by *Port*. - If *Index Type* is [05], the byte offset MUST also point to the + If *Index Type* is [06], the byte offset MUST also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.) diff --git a/src/docs/draft-tasd-spec-0001.xml b/src/docs/draft-tasd-spec-0001.xml index 5c8036e..5c184db 100644 --- a/src/docs/draft-tasd-spec-0001.xml +++ b/src/docs/draft-tasd-spec-0001.xml @@ -36,16 +36,16 @@ <area>General</area> <workgroup>Independent TAS Console Replay Research Group</workgroup> <abstract> - <t>The <strong>TASD</strong> file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) data for TAS replay devices to replay on physical video game console hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification at a later date.</t> + <t>The <strong>TASD</strong> file format is used for storing "Tool Assisted Speedrun" or "Tool Assisted Superplay" (TAS) input and configuration data for use with devices (known as "TAS replay devices") that replay inputs on physical video game hardware. The format is defined to be expandable for future needs. The format is also defined to be parsable by programs that do not understand portions of the format, whether that is due to incomplete support of the format specification or due to new features being added to later versions of the specification.</t> <t>This document defines the file format specification for <strong>TASD</strong> files.</t> </abstract> </front> <middle> <section anchor="introduction" numbered="true" toc="default"> <name>Introduction</name> - <t>The Tool Assisted Speedrun Dump (<strong>TASD</strong>) interchange format is a file format for storing data to allow "Tool Assisted Speedruns" or "Tool Assisted Superplays" to be played on physical video game console hardware using TAS replay devices. Created to be hardware and software agnostic, the <strong>TASD</strong> interchange format uses a key-based, binary, packet format to break up pieces of information into easily-parsable and forward-compatible chunks. The format is extensible by simply defining additional keys or value types as necessary. When parsing the file, software can skip any packets whose key is unknown or unsupported.</t> + <t>The Tool Assisted Speedrun Dump (<strong>TASD</strong>) interchange format is a file format for storing data that enables "Tool Assisted Speedruns" or "Tool Assisted Superplays" to be played on physical video game hardware using TAS replay devices. Created to be hardware and software agnostic, the <strong>TASD</strong> interchange format uses a key-based, binary, packet format to break up pieces of information into easily-parsable and forward-compatible chunks. The format is extensible by simply defining additional keys or value types as necessary. When parsing the file, software can skip any packets whose key is unknown or unsupported.</t> <t>Packets of a given type can be used multiple times or completely omitted as needed. This reusability eliminates the need of a predefined delimiter to separate pieces of data.</t> - <t>While files generated by emulator dump scripts should provide as much information as possible, because packets are optional, the file can be expanded later with any additional data as desired. No intermediary file format is necessary.</t> + <t>While files generated by emulator dump scripts should provide as much information as possible, they may be unable to provide everything. Since packets are optional, the file can be expanded later with any additional data as desired. No intermediary file format is necessary.</t> <section numbered="true" toc="default"> <name>Overview and Preliminaries</name> <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t> @@ -60,12 +60,13 @@ <li>(B) = Boolean</li> <li>([]N) = List of Unsigned Integers</li> </ul> - <t>We use the terms <strong>byte</strong> and <strong>octet</strong> interchangeably in this document.</t> <t>Unless specified otherwise, all multi-octet integers are big-endian.</t> + <t>We use the terms <strong>byte</strong> and <strong>octet</strong> interchangeably in this document.</t> <t>We use the terms <strong>Tool Assisted Speedrun</strong>, <strong>Tool Assisted Superplay</strong> and <strong>TAS</strong> interchangeably in this document.</t> - <t>In subsections of (<xref target="descriptions" />), the term "in direct form" is used. That term is defined to mean a packet in a <strong>TASD</strong> file directly (first order packet) rather than a packet inside a TRANSITION or MOVIE_TRANSITION packet (second order packet).</t> - <t>String values <bcp14>MUST</bcp14> use UTF-8 encoding. As such, string values <bcp14>MAY</bcp14> contain any number of NUL characters and have no concept of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document.</t> - <t>Unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification.</t> + <t>In subsections of (<xref target="descriptions"/>), the term "in direct form" is used. That term is defined to mean a packet in a <strong>TASD</strong> file directly (first order packet) rather than a packet inside a TRANSITION or MOVIE_TRANSITION packet (second order packet).</t> + <t>String values <bcp14>MUST</bcp14> use UTF-8 encoding. As such, string values <bcp14>MAY</bcp14> contain any number of NUL characters and do not make use of "null termination". If an example of a string value is given, the example will be between quotation marks. The quotation marks are not included in the string. Not all content between quotations will be string value examples, so be aware of that when continuing through this document.</t> + <t>Both unsigned and signed integers can have different bit widths. For instance, an 8-bit integer can be used in one part of the specification and a 64-bit integer can be used in another part of the specification.</t> + <t>Variable-length integer encoding (also known as VarInt or VLQ) is not used in this format. Instead, arbitrarily sized integers, like those used in <xref target="packets"/>, are prefixed with a single octet that specifies the number of octets used to contain the integer value. In most cases, this is less space-efficient than VarInt encoding, but it is simpler to understand and to parse.</t> <t>Boolean values <bcp14>MUST</bcp14> be a single octet with the value of <tt>0</tt> for <strong>FALSE</strong> or <tt>1</tt> for <strong>TRUE</strong>.</t> <dl> <dt><tt>[N octets]</tt></dt> <dd>A sequence of octets with a length of N</dd> @@ -130,13 +131,13 @@ +-----------+===========+]]> </artwork> <ul spacing="compact" empty="true"> - <li>In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain consistent horizontal spacing in this documentation. The packet diagram is separated by an ellipsis (<tt>...</tt>) on the same text row as the variable names to signify that the packet diagram is continuing.</li> + <li>In this example, the packet diagram contains enough variable boxes to require being split into 2 sections, in order to maintain consistent horizontal spacing in this document. The packet diagram is separated by an ellipsis (<tt>...</tt>) on the same text row as the variable names to signify that the packet diagram is continuing.</li> </ul> </section> </section> <section numbered="true" toc="default"> <name>Motivations</name> - <t>This file format's primary goal is to provide a comprehensive and replay device agnostic TAS movie controller input dump format that is usable for any console. Additional goals include:</t> + <t>This file format's primary goal is to provide a comprehensive and replay device agnostic TAS input dump format that is usable for any console. Additional goals include:</t> <ul> <li>No intermediary formats</li> <li>Forward compatibility</li> @@ -187,7 +188,7 @@ </artwork> <dl newline="true"> <dt><strong>Magic Number</strong></dt> - <dd>4 octet value that <bcp14>MUST</bcp14> be <tt>[54 41 53 44]</tt>(ASCII value <tt>TASD</tt>).</dd> + <dd>4 octet value that <bcp14>MUST</bcp14> be <tt>[54 41 53 44]</tt> (ASCII value <tt>TASD</tt>).</dd> <dt><strong>Version</strong></dt> <dd>Version of the <strong>TASD</strong> file format. Version currently <bcp14>MUST</bcp14> be a value of 1, but <bcp14>SHOULD</bcp14> be incremented in future versions.</dd> <dt><strong>G_KEYLEN</strong></dt> @@ -381,9 +382,9 @@ <name>Input Frame/Timing Key Descriptions</name> <dl newline="true"> <dt><tt>[FE 01]</tt> - INPUT_CHUNK</dt> - <dd>Specifies a chunk of input data for the TAS when played on hardware. All data from INPUT_CHUNK packets are concatenated together in order of appearance in the <strong>TASD</strong> file. If the INPUT_CHUNK packet type is used in a TASD file, the PORT_CONTROLLER packet type <bcp14>MUST</bcp14> also be used at least once. If the INPUT_CHUNK packet type is used, the INPUT_MOMENT packet type <bcp14>SHOULD NOT</bcp14> be used. This packet type is <bcp14>OPTIONAL</bcp14> and a <strong>TASD</strong> file <bcp14>MAY</bcp14> contain more than 1 of this packet type. Discussed in (<xref target="input_chunk"/>).</dd> + <dd>Specifies a chunk of input data for the TAS when played on hardware. All data from INPUT_CHUNK packets for each controller port are concatenated together in order of appearance in the <strong>TASD</strong> file. This packet type is <bcp14>OPTIONAL</bcp14> and a <strong>TASD</strong> file <bcp14>MAY</bcp14> contain more than 1 of this packet type. Discussed in (<xref target="input_chunk"/>).</dd> <dt><tt>[FE 02]</tt> - INPUT_MOMENT</dt> - <dd>Specifies a single instance of input data that is sent from the replay device to the console with specific timing. If the INPUT_MOMENT packet type is used in a TASD file, the PORT_CONTROLLER packet type <bcp14>MUST</bcp14> also be used at least once. If the INPUT_MOMENT packet type is used, the INPUT_CHUNK packet type <bcp14>SHOULD NOT</bcp14> be used. This packet type is <bcp14>OPTIONAL</bcp14> and a <strong>TASD</strong> file <bcp14>MAY</bcp14> contain more than 1 of this packet type. Discussed in (<xref target="input_moment"/>).</dd> + <dd>Specifies a single instance of input data that is sent from the replay device to the console with specific timing. This packet type is <bcp14>OPTIONAL</bcp14> and a <strong>TASD</strong> file <bcp14>MAY</bcp14> contain more than 1 of this packet type. Discussed in (<xref target="input_moment"/>).</dd> <dt><tt>[FE 03]</tt> - TRANSITION</dt> <dd>Specifies when a transition or change occurs during a TAS replay (example: console reset or changing of controller types). This packet type is <bcp14>OPTIONAL</bcp14> and a <strong>TASD</strong> file <bcp14>MAY</bcp14> contain more than 1 of this packet type. Discussed in (<xref target="transition"/>).</dd> <dt><tt>[FE 04]</tt> - LAG_FRAME_CHUNK</dt> @@ -455,7 +456,7 @@ </artwork> <dl newline="true"> <dt><strong>Video Signal</strong></dt> - <dd>Specifies the video signal of the game console being emulated while dumping the TAS movie controller inputs.</dd> + <dd>Specifies the video signal of the game console being emulated while dumping the TAS movie's controller inputs.</dd> </dl> </section> <section numbered="true" toc="default" anchor="game_title"> @@ -785,10 +786,14 @@ <name>GAME_IDENTIFIER Packet</name> <t>GAME_IDENTIFIER packets <bcp14>MUST</bcp14> be in the following format:</t> <artwork><![CDATA[ - 0 1 2 3... 3+NLEN... - +----------+--------------+----------+==========+================+ - | Type (A) | Encoding (A) | NLEN (N) | Name (S) | Identifier (A) | - +----------+--------------+----------+==========+================+ + 0 1 2 3... + +----------+--------------+----------+==========+ + | Type (A) | Encoding (A) | NLEN (N) | Name (S) | ... + +----------+--------------+----------+==========+ + 3+NLEN... + +================+ + | Identifier (A) | + +================+ Type (Binary Data): [1 octet] [01] - MD5 Hash @@ -813,7 +818,8 @@ [04] - Base 64 NLEN (Unsigned Integer) [1 octet] Name (String) [NLEN octets] - Identifier (Binary Data) [PLEN - 2 octets]]]> + Identifier (Binary Data) [PLEN - NLEN - + 3 octets]]]> </artwork> <dl newline="true"> <dt><strong>Type</strong></dt> @@ -1131,7 +1137,8 @@ [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 + [04] - Microseconds + [05] - Nanoseconds Index (Unsigned Integer) [8 octets] Inputs (Binary Data) [PLEN - 11 octets] ]]> @@ -1140,7 +1147,7 @@ <dt><strong>Port</strong></dt> <dd>Controller port number (<strong>Port</strong> number <bcp14>MUST</bcp14> be <strong>1-indexed</strong>).</dd> <dt><strong>Hold</strong></dt> - <dd>Determines whether the <strong>Input</strong> data <bcp14>MUST</bcp14> continue to be held after the controller state has been read.</dd> + <dd>If <strong>TRUE</strong>, the <strong>Input</strong> data <bcp14>MUST</bcp14> continue to be held after the controller state has been read. Otherwise if <strong>FALSE</strong>, the <strong>Input</strong> data is held only until the data has been used once.</dd> <dt><strong>Index Type</strong></dt> <dd>Specifies timing methodology of a specific moment when <strong>Input</strong> data <bcp14>MUST</bcp14> be applied.</dd> <dt><strong>Index</strong></dt> @@ -1152,6 +1159,7 @@ </dl> <t>Each INPUT_MOMENT packet contains a single instance of controller input data for a specific moment during a TAS replay. The input data's format depends on the PORT_CONTROLLER type corresponding to the <strong>Port</strong> number. Refer to <xref target="controller_inputs"/> for each available type. The PORT_CONTROLLER type <bcp14>MAY</bcp14> be changed using TRANSITION packets, which <bcp14>MAY</bcp14> change the interpretation of the input data.</t> <t>If <strong>Hold</strong> is <strong>TRUE</strong>, the controller <bcp14>MUST</bcp14> continually hold the input state until the next INPUT_MOMENT for the same <strong>Port</strong> number. If <strong>Hold</strong> is <strong>FALSE</strong>, the controller <bcp14>MUST</bcp14> hold only until the console reads the input state, or until the next INPUT_MOMENT for the same <strong>Port</strong> number.</t> + <t>If an INPUT_MOMENT overlaps with input data from one or more INPUT_CHUNKs, the INPUT_MOMENT's <strong>Input</strong> data <bcp14>MUST</bcp14> be used instead of the data contained in the INPUT_CHUNKs. INPUT_CHUNK data <bcp14>MUST</bcp14> still be incremented as it normally would. <strong>Hold</strong> <bcp14>MUST</bcp14> still behave as specified.</t> </section> <section numbered="true" toc="default" anchor="transition"> <name>TRANSITION Packet</name> @@ -1170,8 +1178,9 @@ [01] - Frame [02] - Cycle Count [03] - Milliseconds - [04] - Microseconds * 10 - [05] - INPUT_CHUNK Byte Index + [04] - Microseconds + [05] - Nanoseconds + [06] - INPUT_CHUNK Byte Index Port (Unsigned Integer) [1 octet] Index (Unsigned Integer) [8 octets] Type (Binary Data): [1 octet] @@ -1187,7 +1196,7 @@ <dt><strong>Port</strong></dt> <dd>Controller port number (<strong>Port</strong> number <bcp14>MUST</bcp14> be <strong>1-indexed</strong>).</dd> <dt><strong>Index</strong></dt> - <dd>Time or offset value to start transition. If <strong>Index Type</strong> is <tt>[05]</tt>, <strong>Index</strong> <bcp14>MUST</bcp14> be interpreted as the <strong>byte offset</strong> (<strong>0-indexed</strong>) into the concatenated input data from all <strong>INPUT_CHUNK</strong> packets for the controller port specified by <strong>Port</strong>. If <strong>Index Type</strong> is <tt>[05]</tt>, the byte offset <bcp14>MUST</bcp14> also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.)</dd> + <dd>Time or offset value to start transition. If <strong>Index Type</strong> is <tt>[06]</tt>, <strong>Index</strong> <bcp14>MUST</bcp14> be interpreted as the <strong>byte offset</strong> (<strong>0-indexed</strong>) into the concatenated input data from all <strong>INPUT_CHUNK</strong> packets for the controller port specified by <strong>Port</strong>. If <strong>Index Type</strong> is <tt>[06]</tt>, the byte offset <bcp14>MUST</bcp14> also point to the first byte of an instance of controller input data (according to the PORT_CONTROLLER format at that moment in the TAS replay.)</dd> <dt><strong>Type</strong></dt> <dd>Type of transition. If <strong>Type</strong> is <tt>[FF]</tt>, the transition action will be interpreting a <strong>TASD</strong> packet.</dd> <dt><strong>Inner Packet</strong></dt> @@ -1928,6 +1937,8 @@ <t>THIS DOCUMENTATION IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</t> </section> <!-- Change Log +draft 17 - 2025-04-16 Bigbass Improved the wording in the Abstract and Introduction paragraphs. Reordered and expanded on the overview/preliminaries section. Revised wording in a packet diagram example and the Motivations section. Miscellaneous formatting changes. Removed exclusion requirements between INPUT_CHUNK and INPUT_MOMENT packets, as they can be used together now. Clarified what must happen if an INPUT_MOMENT conflicts with INPUT_CHUNK inputs. For INPUT_MOMENT and TRANSITION packets, the Index Type "Microseconds * 10" has been changed to "Microseconds", and a new type "Nanoseconds" has been added. (2^64 nanoseconds is ~584.6 years) + draft 16 - 2025-02-01 Bigbass Revised "Introduction" paragraphs. Clarified NUL characters in strings. Clarified header version should increase in future versions. Clarified INPUT_MOMENT packets contain only a single instance of input data. Clarified how multiple INPUT_CHUNK packets must be interpreted. Clarified INPUT_CHUNK indexes in TRANSITION packets refer to an individual byte (changed index type name.) Added a "Hold" option to INPUT_MOMENT packets to clarify how long the INPUT_MOMENT should be active for (useful for GB/C/A replays which expect the value to be held until the input changes.) Changed Genesis controller input formats. draft 15 - 2023-10-15 Bigbass Reordered SNES controller types |
