STF Format¶
Introduction¶
STF is a binary file format, containing a binary header, a Json definition and a set of binary buffers.
The Json definition contains meta information, arbitrary resources and buffer references.
Resources have a type
property, and are identified by a unique ID as a string.
Based on a resources type, a module gets selected which provides support to import & export it.
The minimum required set of supported modules is specified in Core Modules.
STF implementations must provide an easy to use plugin system for modules. If in any way possible, modules should be hot-loadable at runtime.
Key Facts¶
The file extension for stf binary files is
.stf
.The media-type for stf binary files is
model/stf+binary
.The STF binary header is stored in
little endian
byte order.The Json definition is encoded as
utf8
.STF uses the same coordinate system as glTF 2.0. (See glTF-2.0. coordinate-system-and-units)
Binary Format¶
An STF binary file consists of a binary header, a json-definition, and zero or more binary buffers.
Length (Bytes) |
Content |
---|---|
4 |
Magic number: |
4 |
STF binary format version major |
4 |
STF binary format version minor |
4 |
Number of buffers, including the Json definiton buffer |
8 * {number of buffers} |
Buffer lengths in bytes |
{length of all buffers} |
Buffers |
The Json definition is the first and only required buffer.
Json Definition¶
The root Json element is an object. It contains 3 properties: stf
, resources
and buffers
.
stf
object¶
The stf
object holds meta information.
Properties:
Key |
Required |
Type |
Description |
---|---|---|---|
version_major |
Yes |
Int |
Major version of STF |
version_minor |
Yes |
Int |
Minor version of STF |
root |
Yes |
resource-ID |
ID of the root resource |
meta |
No |
Map<String, String> |
Meta information such as authors, license or documentation link. |
generator |
No |
String |
The name of the STF implementation that created this file. |
timestamp |
No |
String |
Timestamp as a String in the ISO format. |
metric_multiplier |
No |
Float |
Which number represents one meter. The default value is |
The root resource must be a stf.prefab
. It represents the assets scene-hierarchy.
stf
object example
"stf": {
"version_major": 0,
"version_minor": 0,
"meta": {
"asset_name": "STF Example 1"
},
"metric_multiplier": 1.0,
"root": "5f1ea7e8-ee26-46c9-91dc-cd002cb9b0a5"
}
resources
object¶
The resources
object is a map of resource objects identified by an ID.
The various resource objects describe the files actual content. Any further properties are defined by each resources module.
Resource object base properties:
Key |
Required |
Type |
Description |
---|---|---|---|
type |
Yes |
String |
Type of the resource. |
referenced_resources |
No |
List |
IDs of resources this resource references. |
referenced_buffers |
No |
List |
IDs of buffers this resource references. |
name |
No |
String |
Display name of the resource. |
version_major |
No |
Int |
Major version of this resource. The default value is |
version_minor |
No |
Int |
Major version of this resource. The default value is |
degraded |
No |
Boolean |
Has this resource lost information at some point, but retained the same ID. The default is |
If a referenced resource is not contained within the Json keys children
, root_nodes
, components
or instance
, it must be additionally stored in the referenced_resources
field. This is only required for non-default modules.
A referenced buffer must be additionally stored in the referenced_buffers
field. This is only required for non-default modules.
Resource Kinds¶
Resources can be Data
, Node
, Instance
and Component
kinds.
Each of these kinds has additional properties.
The information about what kind
a resource is, must be known by the resource-type’s implementation and is not contained in STF files itself.
Data¶
Suppport for module plugins of this kind is required.
Data resource base properties:
Key |
Required |
Type |
Description |
---|---|---|---|
fallback |
No |
Resource-ID |
ID of a resource that should be used in case this one’s type is not supported in this implementation |
components |
No |
List |
Component resource IDs |
Node¶
For now only stf.node
and stf.bone
exist.
Suppport for module plugins of this kind is not required.
Node resource base properties:
Key |
Required |
Type |
Description |
---|---|---|---|
enabled |
No |
boolean |
True by default |
children |
No |
List |
IDs of child-nodes |
components |
No |
List |
Component resource IDs |
Instance¶
They represent an instance of a data
resource in the scene hierarchy.
These include for example mesh or armature instances.
Instances can provide data relevant for the instance of the resource, such as an armatures pose or meshes blendshape value or material assignments.
An instance resource can be referenced only once by a Node
resource.
Suppport for module plugins of this kind is required.
Instance resource properties:
Key |
Required |
Type |
Description |
---|---|---|---|
enabled |
No |
boolean |
True by default |
Component¶
They Represents additional functionality or information for Data
and Node
resources.
A component resource can be referenced only once by a Data
or Node
resource.
Suppport for module plugins of this kind is required.
Component resource properties:
Key |
Required |
Type |
Description |
---|---|---|---|
enabled |
No |
boolean |
True by default |
overrides |
No |
List |
References |
resources
object example
"resources": {
"b5f96f63-d5ce-4210-b4d6-8f43fbf557dd": {
"type": "stf.material",
"name": "Body Material",
"properties": {
"albedo.texture": {
"type": "image",
"values": [
{
"image": "f518a35d-d788-4692-a2dd-84d036d259e8"
}
]
}
}
},
"60b9192c-0c82-434b-b1cf-27d8add2c071": {
"type": "stf.image",
"name": "Awesome Texture.png",
"format": "png",
"buffer": "d07b09a0-3184-4a39-8650-d1fc90c64df2",
"data_type": "color"
},
"3ca7f62c-b2a8-4315-bb1d-e4c6118ead70": {
"type": "stf.texture",
"resolution": [2048, 2048],
"quality": 0.7,
"texture_type": "color",
"downscale_priority": 0
}
}
buffers
object¶
The buffers
object is a map of buffer objects identified by an ID.
Each buffer object has a type
property. Any further properties are defined in the buffer-type’s definition.
For now, stf.buffer.included
is the only supported buffer type. Support for hot-loading different buffer-types is not required.
stf.buffer.included
¶
This type represents a buffer contained in the same file.
stf.buffer.included
properties:
Key |
Required |
Type |
Description |
---|---|---|---|
index |
Yes |
Int |
Index of the binary buffer in the file. An index of 0 means the first buffer after the Json definition buffer. |
buffers
object example
"buffers": {
"2c04d7f9-96cd-4867-baf3-2a54d4d31a67": {
"type": "stf.buffer.included",
"index": 666
}
}
Minimal Definition Example¶
Default Cube.stf
{
"stf": {
"version_major": 0,
"version_minor": 0,
"root": "979c1726-222d-4184-89b1-72f9b2c82d60",
"asset_info": {
"asset_name": "Default Cube"
},
"generator": "stf_blender",
"generator_version": "0.0.7",
"timestamp": "2025-08-04T16:43:03.324405+00:00",
"metric_multiplier": 1
},
"resources": {
"5ced8683-2dff-49de-aefe-3f02c4856e86": {
"type": "stf.material",
"name": "Material",
"properties": {
"albedo.color": {
"type": "color",
"values": [
[
0.800000011920929,
0.800000011920929,
0.800000011920929,
1.0
]
]
},
"roughness.value": {
"type": "float",
"values": [
0.5
]
},
"metallic.value": {
"type": "float",
"values": [
0.0
]
}
},
"style_hints": [
"realistic",
"pbr"
],
"shader_targets": {
"stfblender": [
"ShaderNodeBsdfPrincipled"
]
}
},
"89abf95c-575c-4033-adbc-fffe3f59cdb9": {
"type": "stf.mesh",
"name": "Cube",
"material_slots": [
"5ced8683-2dff-49de-aefe-3f02c4856e86"
],
"float_width": 4,
"indices_width": 1,
"vertices": "c69104d6-55a9-4460-a8fc-e2f3a70da3eb",
"face_corners": "214dd09d-b2eb-4b1f-83bb-c1650222a897",
"splits": "a7ca9d09-169f-4f65-8af5-265a3e1c1128",
"split_normals": "497cd907-6bbf-4017-bbf4-bdb57f34a6b4",
"uvs": [
{
"name": "UVMap",
"uv": "f88f80c6-4b95-4103-88d6-056af49e454b"
}
],
"tris": "f705415c-93c5-48d1-8c12-fa6fc6a976b1",
"material_indices_width": 1,
"faces": "42b4c79a-12b9-4fc9-97b0-518bcdef6043",
"material_indices": "e443faf5-38d0-485a-8f5f-30735c49bf2c",
"sharp_face_indices": "9c25f6ef-f33b-4aa7-9860-da7427d01bdb",
"lines": "3d232b23-6deb-41ad-b09e-5805869fff1c",
"sharp_edges": "cc4206c5-2ff7-4d28-9e90-f4d3c6a8130a",
"components": [
"4ab71531-2a97-4d63-b574-3ab760290f4a"
]
},
"4ab71531-2a97-4d63-b574-3ab760290f4a": {
"type": "stfexp.mesh.seams",
"indices_width": 1,
"referenced_buffers": [
"29e557ab-6f20-4302-9396-a2287cda0b6e"
],
"seams": "29e557ab-6f20-4302-9396-a2287cda0b6e"
},
"9742257e-e1b3-424f-882f-33c44c746d98": {
"type": "stf.instance.mesh",
"name": "",
"mesh": "89abf95c-575c-4033-adbc-fffe3f59cdb9"
},
"25f8b224-46a3-404c-a15a-8594f2c9e8fc": {
"type": "stf.node",
"name": "Cube",
"children": [],
"trs": [
[
0.0,
0.0,
-0.0
],
[
0.0,
0.0,
-0.0,
1.0
],
[
1.0,
1.0,
1.0
]
],
"instance": "9742257e-e1b3-424f-882f-33c44c746d98"
},
"53650c64-eb81-4873-a4f0-4e274c02597f": {
"type": "stf.node",
"name": "Light",
"children": [],
"trs": [
[
4.076245307922363,
5.903861999511719,
-1.0054539442062378
],
[
0.16907574236392975,
0.7558803558349609,
-0.27217137813568115,
0.570947527885437
],
[
1.0,
1.0,
0.9999999403953552
]
]
},
"57d85e39-1994-4604-b4fc-4acd76a5f635": {
"type": "stf.node",
"name": "Camera",
"children": [],
"trs": [
[
7.358891487121582,
4.958309173583984,
6.925790786743164
],
[
0.483536034822464,
0.33687159419059753,
-0.20870360732078552,
0.7804827094078064
],
[
1.0,
1.0,
1.0
]
]
},
"979c1726-222d-4184-89b1-72f9b2c82d60": {
"type": "stf.prefab",
"name": "Collection",
"root_nodes": [
"25f8b224-46a3-404c-a15a-8594f2c9e8fc",
"53650c64-eb81-4873-a4f0-4e274c02597f",
"57d85e39-1994-4604-b4fc-4acd76a5f635"
],
"animations": []
}
},
"buffers": {
"c69104d6-55a9-4460-a8fc-e2f3a70da3eb": {
"type": "stf.buffer.included",
"index": 0
},
"214dd09d-b2eb-4b1f-83bb-c1650222a897": {
"type": "stf.buffer.included",
"index": 1
},
"a7ca9d09-169f-4f65-8af5-265a3e1c1128": {
"type": "stf.buffer.included",
"index": 2
},
"497cd907-6bbf-4017-bbf4-bdb57f34a6b4": {
"type": "stf.buffer.included",
"index": 3
},
"f88f80c6-4b95-4103-88d6-056af49e454b": {
"type": "stf.buffer.included",
"index": 4
},
"f705415c-93c5-48d1-8c12-fa6fc6a976b1": {
"type": "stf.buffer.included",
"index": 5
},
"42b4c79a-12b9-4fc9-97b0-518bcdef6043": {
"type": "stf.buffer.included",
"index": 6
},
"e443faf5-38d0-485a-8f5f-30735c49bf2c": {
"type": "stf.buffer.included",
"index": 7
},
"9c25f6ef-f33b-4aa7-9860-da7427d01bdb": {
"type": "stf.buffer.included",
"index": 8
},
"3d232b23-6deb-41ad-b09e-5805869fff1c": {
"type": "stf.buffer.included",
"index": 9
},
"cc4206c5-2ff7-4d28-9e90-f4d3c6a8130a": {
"type": "stf.buffer.included",
"index": 10
},
"29e557ab-6f20-4302-9396-a2287cda0b6e": {
"type": "stf.buffer.included",
"index": 11
}
}
}