Many modern game engines use the Entity Component System (ECS) way of defining behaviour and logic. Many modern game engines also use GLTF for storing assets - their geometry, animations and materials. One thing that has been lacking is the ability to combine these things. If you wish to assign logic to a particular node in a scene, how do you do so? Do you search through the GLTF scene for particular object names? Do you use suffixes? Or perhaps if your game engine supports it, you look through the "extras" field and define the behaviour there.
This repository aims to create a small standard for how this information is conveyed through GLTF. It does this in two ways:
- Defining a standard for how this data is stored
- Implementing a blender addon that allows exporting components
Another repository (yet to be developed) will implement the importing of this data into Bevy, as a proof of concept of how this system can work.
This does not define the specifics of any particular components. It does not guarantee interoperability between assets and engines - but it may form the start of some levels of compatibility.
In the future I would love to see a world where collision information (eg friction, collision margins) accompany most GLTF assets, and where many more ad-hoc will transition to GLTF.
The spec is tiny. It goes like this:
- A node may contain the field
ECS_Components_v1
in theextras
field - The
ECS_Components_v1
field is aList
ofComponentObjects
. - A
ComponentObject
must contain the fields:type: string
Contains the name/type of the component. If this component represents a box collider, then maybe the value oftype
isbox_collider
. Maybe the value oftype
isplayer
orenemy
- A
ComponentObject
may contain any other field required to set up the component in the target system. - The
ECS_Components_v1
field must not contain twoCompoentObjects
with the sametype
.
This is designed to be easy to parse by a static type system (such as serde's Enum representation), which is why it is an Array
rather than an Object
Here's a cube with a mesh that is tagged with the component player
{
"nodes" : [
{
"extras" : {
"ECS_Components_v1": [
{"type": "player"}
]
},
"mesh" : 0,
"name" : "Cube"
}
],
.... # Rest of GLTF file
}
Maybe our player also has a health
component:
Here's a cube with a mesh that is tagged with the component player
{
"nodes" : [
{
"extras" : {
"ECS_Components_v1": [
{"type": "player"},
{"type": "health", "initial_health": 100, "max_health": 150},
]
},
"mesh" : 0,
"name" : "Cube"
}
],
.... # Rest of GLTF file
}
Here's an invalid file. It contains two of the same components. Parsers should reject (or at least throw warnings) on encountering this file:
{
"nodes" : [
{
"extras" : {
"ECS_Components_v1": [
{"type": "player"},
{"type": "health", "initial_health": 100, "max_health": 150},
{"type": "health", "initial_health": 120, "max_health": 180},
]
},
"mesh" : 0,
"name" : "Cube"
}
],
.... # Rest of GLTF file
}
Yes, the following is also invalid:
{
"nodes" : [
{
"extras" : {
"ECS_Components_v1": [
{"type": "player"},
{"type": "player"},
]
},
"mesh" : 0,
"name" : "Cube"
}
],
.... # Rest of GLTF file
}