View Source Tutorial Project
Now that we have an Elixir project with Phoenix, we can get started on building a game with Entity-Component-System architecture. We're going to use the classic Snake as inspiration.
design-plan
Design plan
First, let's start with a single entity. In ECS, an entity is nothing by itself, so we must start by defining the aspects which will make up the entity. What makes a Snake?
- Has a physical position in the game world
- Moves forward constantly
- Can change direction
- Tail grows longer over time
- Kills other snakes when they touch its tail
For each of these requirements, we will create an aspect:
Position
Moving
Direction
Length
OnContact
For each of these aspects, we'll define a schema which contains the ID of the entity, and any relevant data:
- Position:
{entity_id, x, y}
ex:{123, 0, -50}
- Moving:
{entity_id, speed}
ex:{123, 1}
- Direction:
{entity_id, direction}
ex:{123, :north}
- Length:
{entity_id, length}
ex:{123, 10}
- OnContact:
{entity_id, result_of_contact}
ex:{123, :death}
We can use the ECSx generators to quickly create the files needed for these aspects:
$ mix ecsx.gen.aspect Position entity_id x y
Following the above pattern, run mix ecsx.gen.aspect
for the remaining four aspects.
Next we have to think about the Systems which will organize game logic. What makes a Snake game work?
- Snakes move forwards every game tick
- Snakes change direction when a player gives input
- Snakes get longer over time (or based on other game conditions)
- When a collision is detected, one or both snakes are removed from the game
Each one of these will be the responsibility of a different System:
ForwardMovement
PlayerInput
GrowTail
Collision
We will generate modules for each of these Systems with mix ecsx.gen.system
. For example:
$ mix ecsx.gen.system ForwardMovement
After generating all four of our Systems, it's time to write the game logic for each one - COMING SOON