TSCN file format

    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 in the ResourceFormatLoaderText class.

    There are five main sections inside the TSCN file:

    1. File Descriptor
    2. External resources
    3. Internal resources
    4. Nodes
    5. Connections

    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 [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.

    A heading looks like [<resource_type> key=value key=value key=value ...] where resource_type is one of:

    • ext_resource
    • sub_resource
    • node
    • connection

    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:

    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 [node type="Camera" name="PlayerCamera" parent="Player/Head"]

    Other valid keywords include:

    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):

    1. [node name="Player" type="Spatial"] ; The scene root
    2. [node name="Arm" parent="." type="Spatial"] ; Parented to the scene root
    3. [node name="Hand" parent="Arm" type="Spatial"]
    4. [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 save a file with that node in it. Some example nodes are:

    1. [node type="CollisionShape" name="SphereCollision" parent="SpherePhysics"]
    2. shape = SubResource(8)
    3. 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 )
    4. [node type="MeshInstance" name="Sphere" parent="SpherePhysics"]
    5. mesh = SubResource(9)
    6. 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 )
    7. [node type="OmniLight" name="Lamp" parent="."]
    8. light_energy = 1.0
    9. light_specular = 1.0
    10. transform = Transform( -0.29086464643478394 , -0.7711008191108704 , 0.5663931369781494 , -0.05518905818462372 , 0.6045246720314026 , 0.7946722507476807 , -0.9551711678504944 , 0.199883371591568 , -0.21839118003845215 ,4.076245307922363 ,7.3235554695129395 ,-1.0054539442062378 )
    11. omni_range = 30
    12. shadow_enabled = true
    13. light_negative = false
    14. light_color = Color( 1.0, 1.0, 1.0, 1.0 )
    15. [node type="Camera" name="Camera" parent="."]
    16. projection = 0
    17. near = 0.10000000149011612
    18. fov = 50
    19. 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 )
    20. far = 100.0

    NodePath

    1. [node name="mesh" type="MeshInstance" parent="Armature001"]
    2. skeleton = NodePath("..:")

    Skeleton

    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
    1. 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.

    Here’s an example of a skeleton node with two bones:

    1. [node name="Skeleton" type="Skeleton" parent="Armature001" index="0"]
    2. bones/0/name = "Bone.001"
    3. bones/0/parent = -1
    4. bones/0/rest = Transform( 1, 0, 0, 0, 0, -1, 0, 1, 0, 0.038694, 0.252999, 0.0877164 )
    5. bones/0/pose = 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 )
    6. bones/0/enabled = true
    7. bones/0/bound_children = [ ]
    8. bones/1/name = "Bone.002"
    9. bones/1/parent = 0
    10. bones/1/rest = Transform( 0.0349042, 0.99939, 0.000512929, -0.721447, 0.0248417, 0.692024, 0.691589, -0.0245245, 0.721874, 0, 5.96046e-08, -1.22688 )
    11. bones/1/pose = 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 )
    12. bones/1/enabled = true
    13. bones/1/bound_children = [ ]

    BoneAttachment node is an intermediate node to describe some node being parented 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:

    1. [node name="Armature" type="Skeleton" parent="."]
    2. transform = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -0.0219986, 0.0125825, 0.0343127)
    3. bones/0/name = "Bone"
    4. bones/0/parent = -1
    5. bones/0/rest = Transform(1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0)
    6. bones/0/pose = 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)
    7. bones/0/enabled = true
    8. bones/0/bound_children = [NodePath("BoneAttachment:")]
    9. [node name="BoneAttachment" type="BoneAttachment" parent="Armature"]
    10. bone_name = "Bone"
    11. [node name="Cylinder" type="MeshInstance" parent="Armature/BoneAttachment"]
    12. mesh = SubResource(1)
    13. 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 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).

    1. [node name="AnimationPlayer" type="AnimationPlayer" parent="." index="1"]
    2. root_node = NodePath("..")
    3. autoplay = ""
    4. playback_process_mode = 1
    5. playback_default_blend_time = 0.0
    6. playback_speed = 1.0
    7. anims/default = SubResource( 2 )
    8. blend_times = [ ]

    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 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 [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 and an ID.

    Godot always generates absolute paths relative to the resource directory and thus prefixed with res://, but paths relative to the TSCN file’s location are also valid.

    Some example external resources are:

    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.

    1. [sub_resource type="CapsuleShape" id=2]
    2. radius = 0.5
    3. height = 3.0

    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 surface\Index={}. Each surface is a set of vertices and a material.

    TSCN files support two surface formats:

    1. For the old format, each surface has three essential keys:
    • primitive

    • arrays

    • morph_arrays

    An example of ArrayMesh:

    1. [sub_resource id=1 type="ArrayMesh"]
    2. surfaces/0 = {
    3. "primitive":4,
    4. "arrays":[
    5. Vector3Array(0.0, 1.0, -1.0, 0.866025, -1.0, -0.5, 0.0, -1.0, -1.0, 0.866025, 1.0, -0.5, 0.866025, -1.0, 0.5, 0.866025, 1.0, 0.5, -8.74228e-08, -1.0, 1.0, -8.74228e-08, 1.0, 1.0, -0.866025, -1.0, 0.5, -0.866025, 1.0, 0.5, -0.866025, -1.0, -0.5, -0.866025, 1.0, -0.5),
    6. Vector3Array(0.0, 0.609973, -0.792383, 0.686239, -0.609973, -0.396191, 0.0, -0.609973, -0.792383, 0.686239, 0.609973, -0.396191, 0.686239, -0.609973, 0.396191, 0.686239, 0.609973, 0.396191, 0.0, -0.609973, 0.792383, 0.0, 0.609973, 0.792383, -0.686239, -0.609973, 0.396191, -0.686239, 0.609973, 0.396191, -0.686239, -0.609973, -0.396191, -0.686239, 0.609973, -0.396191),
    7. null, ; No Tangents,
    8. null, ; no Vertex Colors,
    9. null, ; No UV1,
    10. null, ; No UV2,
    11. null, ; No Bones,
    12. null, ; No Weights,
    13. IntArray(0, 2, 1, 3, 1, 4, 5, 4, 6, 7, 6, 8, 0, 5, 9, 9, 8, 10, 11, 10, 2, 1, 10, 8, 0, 1, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 5, 0, 3, 0, 9, 11, 9, 5, 7, 9, 10, 11, 11, 2, 0, 10, 1, 2, 1, 6, 4, 6, 1, 8)
    14. ],
    15. "morph_arrays":[]
    16. }

    Animation

    An animation resource consists of tracks. Besides, it has length, loop and step applied to all the tracks.

    1. length and step are both durations in seconds.

    Each track is described by a list of key-value pairs in the format tracks/Id/Attribute. Each track includes:

    • 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:

    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.

    3. The keys correspond to the keyframes. It appears as a PoolRealArray(), but may have a different structure for tracks with different types.

    1. [sub_resource type="Animation" id=2]
    2. length = 4.95833
    3. loop = false
    4. step = 0.1
    5. tracks/0/type = "transform"
    6. tracks/0/path = NodePath("Armature001")
    7. tracks/0/interp = 1
    8. tracks/0/loop_wrap = true
    9. tracks/0/imported = true
    10. tracks/0/enabled = true
    11. tracks/0/keys = PoolRealArray( 0, 1, -0.0358698, -0.829927, 0.444204, 0, 0, 0, 1, 0.815074, 0.815074, 0.815074, 4.95833, 1, -0.0358698, -0.829927, 0.444204, 0, 0, 0, 1, 0.815074, 0.815074, 0.815074 )
    12. tracks/1/type = "transform"
    13. tracks/1/path = NodePath("Armature001/Skeleton:Bone.001")
    14. tracks/1/interp = 1
    15. tracks/1/loop_wrap = true
    16. tracks/1/imported = true