Deconstructing Primitives
Learn about the ECS architecture in A-Frame and explore the internals of A-Frame primitives.
We'll cover the following
In this lesson, we’ll explore the fundamental building blocks of ECS, including entities, components, and systems, to better understand this powerful architectural pattern that underpins many interactive software systems.
Entity-component-system
Let’s revisit the components of ECS:
Entities: Containers whose behavior and appearance are defined by components.
Components: Logical modules attached to entities, defining their behavior and appearance.
Systems: Global scope managers and services for classes of components.
Let’s now learn about the application of the ECS architecture by deconstructing some A-Frame primitives.
Let’s say we have two different entities:
Player
Enemy
These entities share some components, such as rendering, position, and health.
While “Player” has all three components, “Enemy” has an additional spawning component to help spawn the enemy at different locations. The rendering, health, and spawning systems are independently responsible for tackling their related jobs. We further notice that both rendering and spawning systems involve positioning. This perspective offers a broader understanding of how entities, components, and systems interact within A-Frame development.
Primitives are entities
In the last few lessons, we learned to use primitives such as <a-box>
and <a-sphere>
for creating 3D shapes. These primitives are an abstraction layer above entities, and they help us get started with A-Frame development. Primitives can be considered similar to <a-box>
primitive, which maps or proxies HTML attributes to component data. This allows for a shorthand method of creating complex and common entities while maintaining a familiar HTML interface for beginners to A-Frame.
Let’s understand this with an example.
We have a box in the scene using the <a-box>
primitive. We can create this box by using an entity and giving it geometry and material components.
First, we create an empty
<a-entity>
primitive and give it theposition
component. Theposition
component in A-Frame defines the exact location of an entity within the 3D virtual environment; we can specify the position along the x-, y-, and z-axes. We observe that nothing happens until this step.To give the entity some shape, we add the
geometry
component. Theprimitive
property determines the type of its geometry. We set theprimitive
property tobox
.Reloading the scene, we see the box given a random color on every reload.
Now, we change the
height
andcolor
properties for the box by directly adding theheight
andcolor
properties in the primitive. However, it’s essential to understand how these properties map to the entity’s components. In the below example, we focus on theheight
property, which is a component of the entity’sgeometry
property. Similarly, thecolor
property we specify in the primitive corresponds to the underlyingmaterial.color
property, creating a direct link between the primitive’s property and the entity’s material’scolor
property.
In the example below, we’ve set up two cuboids with identical height and color properties, once using the <a-box>
primitive and once using an <a-entity>
entity.
This example demonstrates how components act as data containers for entities, modifying their appearance and behavior.
Conclusion
Primitives are entities with a semantic name and a preset bundle of components with default values. A-Frame’s functionality can be extended by creating external components executed during the render loop and used to create custom elements and behaviors according to the scene’s current state.