From 0f76580fc9b209de7a45deb6ca7fccaf3e28fef3 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 11 Jun 2019 18:46:57 +0200 Subject: [PATCH] Improve the "TSCN file format" page This also mentions the ability to write single-line comments in TSCN/TRES files. --- development/file_formats/tscn.rst | 323 +++++++++++++++--------------- 1 file changed, 165 insertions(+), 158 deletions(-) diff --git a/development/file_formats/tscn.rst b/development/file_formats/tscn.rst index 21a2526ea..2310174a3 100644 --- a/development/file_formats/tscn.rst +++ b/development/file_formats/tscn.rst @@ -1,24 +1,24 @@ TSCN file format ================ -A :code:`.tscn` File format is the "Text SCeNe" file format and represents -a single scene-tree inside Godot. TSCN files have the advantage of being -nearly human-readable and easy for version control systems to manage. During -import the TSCN files are compiled into binary :code:`.scn` files stored -inside the .import folder. This reduces the data size and speed up loading. +The TSCN (text scene) file format represents a single scene tree inside +Godot. TSCN files have the advantage of being mostly human-readable and easy for +version control systems to manage. During import, TSCN files are compiled into +binary ``.scn`` files stored inside the .import folder. This reduces the data +size and speeds up loading. -The :code:`.escn` file format is identical to the TSCN file format, but is used to -indicate to Godot that the file has been exported from another program and -should not be edited by the user from within Godot. +The ESCN (exported scene) file format is identical to the TSCN file format, but +is used to indicate to Godot that the file has been exported from another +program and should not be edited by the user from within Godot. -For those looking for a complete description, the parsing is handled in the -file `resource_format_text.cpp `_ -in the class :code:`ResourceFormatLoaderText` +For those looking for a complete description, the parsing is handled in the file +`resource_format_text.cpp `_ +in the ``ResourceFormatLoaderText`` class. File structure -------------- -There are five main sections inside the TSCN File: +There are five main sections inside the TSCN file: 0. File Descriptor 1. External resources @@ -26,31 +26,33 @@ There are five main sections inside the TSCN File: 3. Nodes 4. Connections -The file descriptor looks like :code:`[gd_scene load_steps=1 format=2]` And -should be the first entry in the file. The load_steps parameter should (in -theory) be the number of resources within the file, though in practice its -value seems not to matter. +The file descriptor looks like ``[gd_scene load_steps=1 format=2]`` and should +be the first entry in the file. The ``load_steps`` parameter should (in theory) +be the number of resources within the file. However, in practice, its value seems +not to matter. -These sections should appear in order, but it can be hard to distinguish -them. The only difference between them is the first element in the heading -for all of the items in the section. -For example, the heading of all external resources should start with -:code:`[ext_resource .....]` +These sections should appear in order, but it can be hard to distinguish them. +The only difference between them is the first element in the heading for all of +the items in the section. For example, the heading of all external resources +should start with ``[ext_resource .....]``. + +A TSCN file may contain single-line comments starting with a semicolon (``;``). +However, comments will be discarded when saving the file using the Godot editor. Entries inside the file ~~~~~~~~~~~~~~~~~~~~~~~ -A heading looks like: -:code:`[ key=value key=value key=value ...]` -Where resource_type is one of: +A heading looks like +``[ key=value key=value key=value ...]`` +where resource_type is one of: -- ext_resource -- sub_resource -- node -- connection +- ``ext_resource`` +- ``sub_resource`` +- ``node`` +- ``connection`` -Underneath every heading comes zero or more :code:`key = value` pairs. The -values can be complex datatypes such as arrays, transformations, colors, and +Below every heading comes zero or more ``key = value`` pairs. The +values can be complex datatypes such as Arrays, Transforms, Colors, and so on. For example, a spatial node looks like: :: @@ -58,27 +60,29 @@ so on. For example, a spatial node looks like: [node name="Cube" type="Spatial" parent="."] transform=Transform( 1.0, 0.0, 0.0 ,0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 ) + The scene tree -------------- -The scene tree is made up of... nodes! The heading of each node consists of +The scene tree is made up of… nodes! The heading of each node consists of its name, parent and (most of the time) a type. For example -:code:`[node type="Camera" name="PlayerCamera" parent="Player/Head"]` +``[node type="Camera" name="PlayerCamera" parent="Player/Head"]`` Other valid keywords include: - - instance - - instance_placeholder - - owner - - index (if two nodes have the same name) - - groups + - ``instance`` + - ``instance_placeholder`` + - ``owner`` + - ``index`` (if two nodes have the same name) + - ``groups`` -The first node in the file should not have the :code:`parent=Path/To/Node` -entry in it's heading, and it is the scene root. All scene files should have -exactly one scene root. It it does not, Godot will fail to import the file. -The parent path of other nodes should be absolute, but without the scene -root's name. If it is a direct child of the scene root, it should be -:code:`"."`. Here is an example scene tree (but without any node content). +The first node in the file, which is also the scene root, must not have a +``parent=Path/To/Node`` entry in its heading. All scene files should have +exactly *one* scene root. If it doesn't, Godot will fail to import the file. +The parent path of other nodes should be absolute, but shouldn't contain +the scene root's name. If the node is a direct child of the scene root, +the path should be ``"."``. Here is an example scene tree +(but without any node content): :: @@ -87,25 +91,26 @@ root's name. If it is a direct child of the scene root, it should be [node name="Hand" parent="Arm" type="Spatial"] [node name="Finger" parent="Arm/Hand" type="Spatial"] + Similar to the internal resource, the document for each node is currently -incomplete. Fortunately it is easy to find out because you can simply +incomplete. Fortunately, it is easy to find out because you can simply save a file with that node in it. Some example nodes are: :: - [node type="CollisionShape" name="SphereCollision" parent="SpherePhysics"] + [node type="CollisionShape" name="SphereCollision" parent="SpherePhysics"] shape = SubResource(8) transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , -4.371138828673793e-08 , 1.0 , -0.0 , -1.0 , -4.371138828673793e-08 ,0.0 ,0.0 ,-0.0 ) - [node type="MeshInstance" name="Sphere" parent="SpherePhysics"] + [node type="MeshInstance" name="Sphere" parent="SpherePhysics"] mesh = SubResource(9) transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , 1.0 , -0.0 , -0.0 , -0.0 , 1.0 ,0.0 ,0.0 ,-0.0 ) - [node type="OmniLight" name="Lamp" parent="."] + [node type="OmniLight" name="Lamp" parent="."] light_energy = 1.0 light_specular = 1.0 @@ -116,7 +121,7 @@ save a file with that node in it. Some example nodes are: light_color = Color( 1.0, 1.0, 1.0, 1.0 ) - [node type="Camera" name="Camera" parent="."] + [node type="Camera" name="Camera" parent="."] projection = 0 near = 0.10000000149011612 @@ -124,14 +129,15 @@ save a file with that node in it. Some example nodes are: transform = Transform( 0.6859206557273865 , -0.32401350140571594 , 0.6515582203865051 , 0.0 , 0.8953956365585327 , 0.44527143239974976 , -0.7276763319969177 , -0.3054208755493164 , 0.6141703724861145 ,14.430776596069336 ,10.093015670776367 ,13.058500289916992 ) far = 100.0 + NodePath ~~~~~~~~ -A tree structure is not enough to represent the whole scene, Godot use -a :code:`NodePath(Path/To/Node)` structure to refer to another node or -attribute of the node anywhere in the scene tree. Some typical usages of -NodePath like mesh node use :code:`NodePath()` to point to its skeleton, -animation track use :code:`NodePath()` points to animated attribute in node. +A tree structure is not enough to represent the whole scene. Godot uses a +``NodePath(Path/To/Node)`` structure to refer to another node or attribute of +the node anywhere in the scene tree. For instance, MeshInstance uses +``NodePath()`` to point to its skeleton. Likewise, Animation tracks use +``NodePath()`` to point to node properties to animate. :: @@ -140,6 +146,7 @@ animation track use :code:`NodePath()` points to animated attribute in node. mesh = SubResource(1) skeleton = NodePath("..:") + :: [sub_resource id=3 type="Animation"] @@ -149,33 +156,30 @@ animation track use :code:`NodePath()` points to animated attribute in node. tracks/0/path = NodePath("Cube:") ... + Skeleton ~~~~~~~~ -Skeleton node inherits Spatial node, besides that it may have a list -of bones described in key, value pair in the format :code:`bones/Id/Attribute=Value`, -attributes of bone consists of +The Skeleton node inherits the Spatial node, but also may have a list of bones +described in key-value pairs in the format ``bones/Id/Attribute=Value``. The +bone attributes consist of: -- name -- parent -- rest -- pose -- enabled -- bound_children +- ``name`` +- ``parent`` +- ``rest`` +- ``pose`` +- ``enabled`` +- ``bound_children`` -1) :code:`name` must put as the first attribute of each bone +1. ``name`` must be the first attribute of each bone. +2. ``parent`` is the index of parent bone in the bone list, with parent index, + the bone list is built to a bone tree. +3. ``rest`` is the transform matrix of bone in its "resting" position. +4. ``pose`` is the pose matrix; use ``rest`` as the basis. +5. ``bound_children`` is a list of ``NodePath()`` which point to + BoneAttachments belonging to this bone. -2) :code:`parent` is the index of parent bone in the bone list, with parent index, - the bone list is built to a bone tree - -3) :code:`rest` is the transform matrix of bone in rest position - -4) :code:`pose` is the pose matrix use :code:`rest` as basis - -5) :code:`bound_children` is a list of NodePath() points to - BoneAttachments belong to this bone - -An example of a skeleton node with two bones: +Here's an example of a skeleton node with two bones: :: @@ -194,13 +198,14 @@ An example of a skeleton node with two bones: bones/1/enabled = true bones/1/bound_children = [ ] + BoneAttachment ~~~~~~~~~~~~~~ BoneAttachment node is an intermediate node to describe some node being parented -to a single bone in Skeleton node. The BoneAttachment has a :code:`bone_name=NameOfBone`, -and the corresponding bone being the parent has the BoneAttachment node -in its :code:`bound_children` list. +to a single bone in a Skeleton node. The BoneAttachment has a +``bone_name=NameOfBone`` attribute, and the corresponding bone being the parent has the +BoneAttachment node in its ``bound_children`` list. An example of one MeshInstance parented to a bone in Skeleton: @@ -225,13 +230,15 @@ An example of one MeshInstance parented to a bone in Skeleton: mesh = SubResource(1) transform = Transform(1.0, 0.0, 0.0, 0.0, 1.86265e-09, 1.0, 0.0, -1.0, 0.0, 0.0219986, -0.0343127, 2.25595) + AnimationPlayer ~~~~~~~~~~~~~~~ -AnimationPlayer works as an animation lib. it has animations listed in the format -:code:`anim/Name=SubResource(ResourceId)`, each refers to a Animation -internal resource. All the animation resources use the root node of AnimationPlayer. -The root node is stored as :code:`root_node=NodePath(Path/To/Node)`. +AnimationPlayer works as an animation library. It stores animations listed in +the format ``anim/Name=SubResource(ResourceId)``; each line refers to an +Animation resource. All the animation resources use the root node of +AnimationPlayer. The root node is stored as +``root_node=NodePath(Path/To/Node)``. :: @@ -245,6 +252,7 @@ The root node is stored as :code:`root_node=NodePath(Path/To/Node)`. anims/default = SubResource( 2 ) blend_times = [ ] + Resources --------- @@ -252,29 +260,24 @@ Resources are components that make up the nodes. For example, a MeshInstance node will have an accompanying ArrayMesh resource. The ArrayMesh resource may be either internal or external to the TSCN file. -References to the resources are handled by id numbers in the resources heading. -External resources and internal resource are referred to with -:code:`ExtResource(id)` and :code:`SubResource(id)`. Because there have -different methods to refer to internal and external resource, you can have +References to the resources are handled by ``id`` numbers in the resource's +heading. External resources and internal resources are referred to with +``ExtResource(id)`` and ``SubResource(id)``, respectively. Because there +have different methods to refer to internal and external resources, you can have the same ID for both an internal and external resource. -For example, to refer to the resource -:code:`[ext_resource id=3 type="PackedScene" path=....]` you would use -:code:`ExtResource(3)` +For example, to refer to the resource ``[ext_resource id=3 type="PackedScene" +path=....]``, you would use ``ExtResource(3)``. External resources ~~~~~~~~~~~~~~~~~~ External resources are links to resources not contained within the TSCN file -itself. An external resource consists of: - - - A path - - A type - - An ID +itself. An external resource consists of a path, a type and an ID. Godot always generates absolute paths relative to the resource directory and -thus prefixed with :code:`res://`, but paths relative to the TSCN file's -location are also valid. +thus prefixed with ``res://``, but paths relative to the TSCN file's location +are also valid. Some example external resources are: @@ -283,14 +286,19 @@ Some example external resources are: [ext_resource path="res://characters/player.dae" type="PackedScene" id=1] [ext_resource path="metal.tres" type="Material" id=2] + +Like TSCN files, a TRES file may contain single-line comments starting with a +semicolon (``;``). However, comments will be discarded when saving the resource +using the Godot editor. + Internal resources ~~~~~~~~~~~~~~~~~~ -A TSCN file can contain meshes, materials and other data, and these are -contained in the internal resources section of the file. The heading -for an internal resource looks similar to those of external resources, but -does not have a path. Internal resources also have :code:`key=value` pairs -under each heading. For example, a capsule collision shape looks like: +A TSCN file can contain meshes, materials and other data. These are contained in +the *internal resources* section of the file. The heading for an internal +resource looks similar to those of external resources, except that it doesn't +have a path. Internal resources also have ``key=value`` pairs under each +heading. For example, a capsule collision shape looks like: :: @@ -299,45 +307,46 @@ under each heading. For example, a capsule collision shape looks like: radius = 0.5 height = 3.0 -Some internal resource contain links to other internal resources (such as a -mesh having a material). In this case, the referring resource must appear -before the reference to it. Thus, in the internal resources section of the -file, order does matter. -Unfortunately, documentation on the formats for these subresources is not -complete, and while some can be found through inspecting resources of -saved files, others can only be found by looking through Godot's source. +Some internal resources contain links to other internal resources (such as a +mesh having a material). In this case, the referring resource must appear +*before* the reference to it. This means that order matters in the file's +internal resources section. + +Unfortunately, documentation on the formats for these subresources isn't +complete. Some examples can be found by inspecting saved resource files, but +others can only be found by looking through Godot's source. ArrayMesh ~~~~~~~~~ -ArrayMesh consists of several surfaces, each in the format :code:`surface\Index={}`, -each surface is a set of vertex and a material. +ArrayMesh consists of several surfaces, each in the format ``surface\Index={}``. +Each surface is a set of vertices and a material. -TSCN support two format of surface, +TSCN files support two surface formats: -1) for the old format, each surface has three essential keys: +1. For the old format, each surface has three essential keys: -- primitive -- arrays -- morph_arrays +- ``primitive`` +- ``arrays`` +- ``morph_arrays`` - i) :code:`primitive` is an enumerate variable, :code:`primitive=4` which is - PRIMITIVE_TRIANGLES is frequently used. + i. ``primitive`` is an enumerate variable, ``primitive=4`` which is + ``PRIMITIVE_TRIANGLES`` is frequently used. - ii) :code:`arrays` as the name suggests is an array of array, it contains: + ii. ``arrays`` is a two-dimensional array, it contains: - 1) An array of vertex position - 2) Tangents array - 3) Vertex color array - 4) UV array 1 - 5) UV array 2 - 6) Bone index array - 7) Bone weight array - 8) Vertex index array + 1. Vertex positions array + 2. Tangents array + 3. Vertex colors array + 4. UV array 1 + 5. UV array 2 + 6. Bone indexes array + 7. Bone weights array + 8. Vertex indexes array - iii) :code:`morph_arrays` is an array of morph, each morph is exactly an - :code:`arrays` without vertex index array. + iii. ``morph_arrays`` is an array of morphs. Each morph is exactly an + ``arrays`` without the vertex indexes array. An example of ArrayMesh: @@ -361,54 +370,52 @@ An example of ArrayMesh: "morph_arrays":[] } + Animation ~~~~~~~~~ -An animation resource consists of tracks. Besides, it has 'length', 'loop' and -'step' applied to all the tracks. +An animation resource consists of tracks. Besides, it has ``length``, ``loop`` +and ``step`` applied to all the tracks. -- length -- loop -- step +1. ``length`` and ``step`` are both durations in seconds. -1) :code:`length` and :code:`step` are both time in seconds +Each track is described by a list of key-value pairs in the format +``tracks/Id/Attribute``. Each track includes: -Each track is described by a list of (key, value) pairs in the format :code:`tracks/Id/Attribute`, -it includes: +- ``type`` +- ``path`` +- ``interp`` +- ``keys`` +- ``loop_wrap`` +- ``imported`` +- ``enabled`` -- type -- path -- interp -- keys -- loop_wrap -- imported -- enabled +1. The ``type`` must be the first attribute of each track. + The value of ``type`` can be: -1) The :code:`type` must be put as the first attribute of each track. - The value of :code:`type` can be: + - ``transform`` + - ``value`` + - ``method`` - - 'transform' - - 'value' - - 'method' +2. The ``path`` has the format ``NodePath(Path/To/Node:attribute)``. + It's the path to the animated node or attribute, relative to the root node + defined in the AnimationPlayer. -2) The :code:`path` has the format :code:`NodePath(Path/To/Node:Attribute)`. - It is the path from animation root node (property of AnimationPlayer) to the - animated node or attribute. - -3) The :code:`interp` is the method to interpolate frames from the keyframes. +3. The ``interp`` is the method to interpolate frames from the keyframes. it is a enum variable and can has value: - 0 (constant) - 1 (linear) - 2 (cubic) -4) The :code:`keys` is the keyframes, it appears as a PoolRealArray() - but have different structure for track with different type +4. The ``keys`` correspond to the keyframes. It appears as a ``PoolRealArray()``, + but may have a different structure for tracks with different types. - - A transform track use every 12 real number in the :code:`keys` to describte a keyframe. - The first number is the timestamp, the second number is the transition (default 1.0 - in transform track), followed by a three number translation vector, followed by - four number rotation quaternion (x,y,z,w) and finally a three number scale vector. + - A Transform track uses every 12 real numbers in the ``keys`` to describe + a keyframe. The first number is the timestamp. The second number is the + transition followed by a 3-number translation vector, followed by a + 4-number rotation quaternion (X, Y, Z, W) and finally a 3-number + scale vector. The default transition in a Transform track is 1.0. ::