I'm a gameplay programmer
focused on developing
engaging and unique experiences!

My Resume Learn more

Entity-Component-System (ECS) : A Data-Oriented Gameplay Framework in C++ - Part 3

Another part of my gameplay framework is the definition of entities and components in a human-readable file that will build out to binary files. In game engines like Unity and Unreal, these take form as Prefabs and Blueprints respectively. Unity has the same approach of human-readable prefab files that build out to binary files, however Blueprints and Unreal assets in general are all stored as binary files. The latter is a pain point when working in large teams as binary files lack a meaningful merging process.

Unity Prefab File

Since Unity's prefab files are stored as human-readable files in development, I decided to take a look at one of the most basic examples of one. This is a prefab file generated by simply making a prefab out of an empty game object and an empty script:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
  m_ObjectHideFlags: 1
  serializedVersion: 2
  m_Modification:
    m_TransformParent: {fileID: 0}
    m_Modifications: []
    m_RemovedComponents: []
  m_ParentPrefab: {fileID: 0}
  m_RootGameObject: {fileID: 1043714864145116}
  m_IsPrefabParent: 1
--- !u!1 &1043714864145116
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  serializedVersion: 5
  m_Component:
  - component: {fileID: 4131896248613688}
  - component: {fileID: 114409185936674780}
  m_Layer: 0
  m_Name: GameObject 1
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &4131896248613688
Transform:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 1043714864145116}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 2.121, y: 0, z: 0}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_Children: []
  m_Father: {fileID: 0}
  m_RootOrder: 0
  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &114409185936674780
MonoBehaviour:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 1043714864145116}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 904e1b67d05428f45b54269344ca563f, type: 3}
  m_Name: 
  m_EditorClassIdentifier:

There's a lot to take in here, but the section I want to focus on is lines 20-22. m_Component appears to define components that are attached to this particular game object with fileIDs. When you look below at the Transform on line 31 and MonoBehaviour on line 44, it seems the same IDs are defined above them. It looks as if this prefab consists of a game object with Transform and MonoBehavior components that have their parameters defined underneath them.

ECS Prefab File

As my ECS gameplay framework doesn't have the extensive feature set that Unity does, my prefab file is much simpler. There is an isActive parameter that sets whether an entity initializes as active, which is similar to m_isActive in the Unity prefab file on line 29. Mine also contains a list of components that is similar to m_Component in Unity on line 20. However, one thing I'm doing different is simply including the component's parameters directly underneath where it is listed.

return
{
    isActive = true,
    components =
    {
        {
            class = "Mesh",
            path_mesh = "meshes/cube.mesh",
        },
        {
            class = "Effect",
            path_effect = "effects/red.effect",
        },
    },
}

Custom Components

Out of the box my framework will have components for a Mesh and an Effect, but I'd like to add support for custom components that can be added to the file without the need for changing how prefabs are built and loaded as binary files. In Unity prefab files, it seems custom components are simply saved as MonoBehaviors with an m_Script property. I'm looking to accomplish something similar with the ECS gameplay framework.

Custom Components in Unity

MonoBehaviour:
  m_ObjectHideFlags: 1
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 100100000}
  m_GameObject: {fileID: 1043714864145116}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: 904e1b67d05428f45b54269344ca563f, type: 3}
  m_Name: 
  m_EditorClassIdentifier:

Custom Components in this ECS

return
{
    isActive = true,
    components =
    {
        {
            class = "Component",
            path_script = "scripts/custom.lua",
        },
    },
}

 

No Comments Yet.

Leave a comment