Overview
How to create and register a system
If you are unfamiliar with Entity Component System (ECS), we recommend reading Introduction to ECS before proceeding.
If you are unfamiliar with the concept of game loop and tick, we recommend reading Loop-driven Runtime before proceeding.
Systems are where game logic is implemented in Cardinal. Each system is executed once at every tick and is responsible for handling messages and updating the state of the game.
In Cardinal, systems are implemented as regular Go functions with the following signature:
Example:
- A
RegenSystem
that increments the current health of all entities that have theHealth
component. - An
AttackSystem
that handles theAttackPlayerMsg
message and reduces the health of the target player.
Key concepts and principles
Before we implement our systems, there are high-level concepts that you need to know to write idiomatic systems in Cardinal.
Systems are always executed once per tick
In Cardinal, systems are executed once per tick regardless of whether there are user message/transactions.
If you are coming from EVM development background, you might notice that this behavior is in stark contrast to how smart contracts work.
In smart contracts, game state can only be updated when a transaction calls a function of the contract. In Cardinal, game state is updated via systems at every tick regardless of whether there are transactions.
This makes it easy to implement state updates (e.g. regeneration, gravity, etc.) that need to consistently happen at every time step/interval which EVM smart contracts are not able to do seamlessly.
All game state must be stored in components
As a general rule of thumb, systems should not store any game state in global variables as it will not be persisted. Systems should only store & read game state to & from components.
Creating Systems
By convention, systems are defined in the system
directory, with each system being its own separate file.
You can easily create a new system and register it to the world by following these steps:
Implement the system function
A system is defined as a Go function that takes in the WorldContext
and returns an error (or nil, if there is none).
Register the system in the World
System must be registered in the world to be executed. This is done by calling the RegisterSystems
function.