From 27beee59f4789fb5642a98e8c9917dd4bc157396 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Fri, 11 Aug 2023 21:50:28 +0100 Subject: [PATCH] schematics spec: finish initial draft --- .docs/specs/WorldEditAdditionsSchematic_v1.md | 108 ++++++++++++++++-- 1 file changed, 98 insertions(+), 10 deletions(-) diff --git a/.docs/specs/WorldEditAdditionsSchematic_v1.md b/.docs/specs/WorldEditAdditionsSchematic_v1.md index 1151c51..29aed9b 100644 --- a/.docs/specs/WorldEditAdditionsSchematic_v1.md +++ b/.docs/specs/WorldEditAdditionsSchematic_v1.md @@ -11,7 +11,9 @@ Implementers MUST clearly specify which version(s) of this specific they support Explanations and descriptions have both a technical description and a formal BNF description. Where the two differ, the formal BNF will always take precedence. ## Purpose -The WorldEditAdditions Schematic file format is designed to store schematics of structures in the Minetest world in an efficient text-based format. It is also designed to store just the changes from one copy of the world to another (deltas). +The WorldEditAdditions Schematic file format is designed to store schematics of structures in the Minetest world in an efficient text-based format. It is also designed to optionally store just the changes from one state of the world to another (deltas). + +In an example situation, a structure in a Minetest world is copied into a WorldEditAdditions Schematic file and saved to disk. At some later time, the resulting schematic file may be parsed and the structure written to a given Minetest world (not necessarily the same world) once more. The rationale behind this format are as follows: @@ -31,9 +33,21 @@ WorldEditAdditions Schematics MAY be gzip-compressed. In such cases, the file ex The voxel-based sandbox building game [Minetest](https://minetest.net/). +> Schematic file + +A WorldEdit Additions schematic file. + +> Full schematic file(s) + +A WorldEdit Additions schematic file with a header value `type` equal to `full`. See [types of schematic](#types-of-schematic). + +> Delta schematic file(s) + +A WorldEdit Additions schematic file with a header value `type` equal to `delta`. See [types of schematic](#types-of-schematic) and [delta schematics](#delta-schematic-files). + > Deltas -The differences between a given region of the world at a given time and the same region some time later. +The differences between a given region of the world in some previous state and the current state. > Schematic origin @@ -58,7 +72,7 @@ Stands for the ASCII character new line U+0A. Wherever this symbol appears, subs ## Overview The format can be divided into 4 sequential parts: -1. **Magic bytes:** The string `WEASCHEM\n` is always the beginning of the file. +1. **Magic bytes:** The string `WEASCHEM1\n` is always the beginning of the file. 2. **Header:** Contains metadata about the schematic. 3. **ID map:** The map of node ids to their respective node names. 4. **Data tables:** The actual data itself. @@ -66,7 +80,7 @@ The format can be divided into 4 sequential parts: As an example: ``` -WEASCHEM +WEASCHEM1 @@ -80,7 +94,11 @@ WEASCHEM ::= "\n" - ::= WEASCHEM + ::= WEASCHEM + + ::= + ::= | + ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ::= | @@ -94,9 +112,14 @@ A full (trivial) example file is given below: WEASCHEM {"name":"Test schematic","description": "Some description","size":{"x":5,"y":3,"z":4},"offset":{"x":1,"y":0,"z":2},"type":"full","generator": "WorldEditAdditions v1.14"} {"0":"default:air","5":"default:stone","14":"default:dirt"} -TODO: Add the data tables +10x5,40x14,0,5,14,5,14,5x0 ``` +## Magic bytes +The string `WEASCHEM` is always present at the beginning of a WorldEditAdditions schematic file, followed directly by an integer version number. + +This specification, as noted above, described WorldEditAdditions schematic files version `1`. It is RECOMMENDED that implementers reject schematic files with a version number that they do not support parsing with a useful error message. + ## Header The header of the file contains all the metadata about the schematic required to restore it into the world. The header is defined as a JSON object on a single line, followed by a new line (`\n` U+0A): @@ -180,7 +203,6 @@ A specific example of a header JSON object is noted below. This example is prett **Note:** Implementers MUST ignore any additional unexpected properties in the header JSON object. - ### Size and positioning Schematic size and positioning are controlled by 2 properties in the header JSON object: @@ -199,11 +221,27 @@ Implementers MAY choose to add a disabled-by-default option to disable the appli ### Types of schematic WorldEditAdditions Schematic files support two types of schematic: -1. **`full`:** Full schematics that contain a static snapshot of the world. +1. **`full`:** Full schematic files that contain a static snapshot of the world. 2. **`delta`:** A schematic that contains only the changes between some previous state of the world and the current state of the world. -TODO: Explain the differences more fully. +From here on, these differing types of WorldEditAdditions schematic files will be referred to as follows: +- **`full`:** Full schematic file(s) +- **`delta`:** Delta schematic file(s) + +Specifically, the node id value of `-2` represents the fact that no change was made between the previous state and the current state of the world. + +### Delta schematic files +Delta schematic files, as described above, store only the changes made to a given Minetest world between 2 different states. The format of delta schematic files differs slightly in that they store both the node id of the previous state *and* the node id of the current state. + +**Writing:** When writing out a delta schematic file, the node ID in the previous state *and* the node ID of the current state must be written as described in [the section on data tables](#data-tables). + +**Reading:** When reading and parsing a delta schematic file, nodes with a node id of `-2` MUST NOT be changed in the target world. Depending on the operation desired, the implementer may choose to discard either the node id of the previous or the current state: + +- **Undo operations:** Node ids of the **previous** state should be kept and used, and node ids of the current state discarded. +- **Redo operations:** Node ids of the **current** state should be kept and used, with node ids of the previous state discarded. + +See also the specific notes in the sections below. ## ID map Like the [header](#header), the ID map is also defined as a JSON object on a single line, followed by a new line character (`\n` U+0A): @@ -257,4 +295,54 @@ It is not required that Node IDs in the schematic file be sequential. ## Data tables -TODO: Describe data tables here. \ No newline at end of file +The data tables store the actual data in the schematic. This data is stored in flat arrays with optional run-length encoding. Using the `size` given in the header, it is possible to read the data and understand where in the array each block is located. Each data table occupies a single line (delimited with `\n` U+0A as with everything else above). + +```bnf + ::= + | "," + + ::= + | x + + ::= + | + + ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 +``` + +There are currently 2 data tables that are stored in schematics, that MUST be present in the following orders. + +For **full** schematic files: + +1. **`data`:** The list of node IDs +2. **`param2`:** The list of [`param2`](https://github.com/minetest/minetest/blob/master/doc/lua_api.md#nodes) values + +For [**delta** schematic files](#delta-schematic-files): + +1. **`data` (previous state):** The list of node IDs for the **previous** state +2. **`data` (current state):** The list of node IDs for the **current** state +3. **`param2`:** The list of [`param2`](https://github.com/minetest/minetest/blob/master/doc/lua_api.md#nodes) values + +**Note:** Either type of schematic file MAY contain additional data tables beyond those described here. In such cases, implementers MUST ignore them, and any such tables MUST be present only *after* the data tables described above. + +Here's a specific example of the data tables for a sample **full** schematic file: + +``` +10x5,40x14,0,5,14,5,14,5x0 +51x0,255,8x0 +``` + +The first line is the node IDs table (`data`), and the second line are the `param2` values. + +Implementers MAY choose to optimise filesize by compacting the node IDs used (e.g. mapping the node id 456 to an id of 5). + +**Note:** Node IDs in a schematic file need to be mapped to the node IDs of the target world when writing a schematic to a Minetest world, as they are unlikely to match. + +### Special node ids +The following node id values have specific meaning: + +Node ID | Purpose +--------|----------------- +-1 | Represents a value of null/nil. This node id value indicates that no node is stored in this cell. When reading a schematic and writing it to the world, implementers MUST NOT alter the pre-existing node in the world that corresponds with this cell. +-2 | **In a delta schematic only,** This node id value indicates that no change was made between the time the schematic was written and the previous time it was compared against. Using this value as a node in a schematic with a `type` of `full` is **invalid**, and in such a case implementers MUST raise an error message and abort reading of the schematic. +