Skip to main content

Entities

Entities are the backbone of an Easel program. Most things in Easel must be attached to an entity. One of the primary purposes of entities is controlling lifespans. When an entity despawns, everything attached to it is removed.

World entity

The World entity represents the world itself. The World entity lives for the entire duration of the program, and can be accessed by calling the World function. It can be used to own things that should last for the duration of the program.

pub prop this.NightTime
pub fn Example() {
World.NightTime = true // assign a property to the World
}

Creating an entity

Entities are created using the Spawn function. The Spawn function optionally takes a subblock which should be used to describe the main behavior of the entity. The behavior runs concurrently with the rest of the game, and will be terminated when the entity despawns.

Commonly, the new entity is given a name which identifies the entity such as projectile or hero. Regardless of what name is given to the parameter, the new entity also always assigned to the this context variable within the subblock. This is useful because many functions take a parameter this from context, and so they will automatically use the new entity this.

pub fn Example() {
Spawn projectile { // Spawn a new entity named `projectile`
// Initialization code goes here
}
}

Despawning an entity

The Despawn function despawns an entity immediately. The entity it despawns is determined by its this parameter, which will be taken from context if not provided explicitly. When an entity despawns, everything that is owned by the entity will be removed.

pub fn Example() {
Spawn projectile {
// Initialization code goes here
await Tick(5s) // Wait for 5 seconds
Despawn // Despawn the projectile
}
}

The Expire function enqueues the despawn of the entity until the next Reap phase, which is one of the last stages of the tick. The entity it despawns is determined by its this parameter, which will be taken from context if not provided explicitly.

tip

Accessing an entity after it has despawned will cause an error, and so it is recommended to normally use Expire to despawn an entity rather than Despawn in order to enqueue the despawn until the reap phase and minimize the chance of errors.

For example, during the physics phase if a projectile entity calls Despawn on itself immediately when it collides with an entity, then if it collided with multiple entities in the same tick, the second collision would receive a non-existent entity which may cause errors. using Expire instead avoids this problem.

Variables of type Entity actually only contain a handle to an entity, and so after an Entity is despawned, they will now be pointing to an entity that no longer exists. The Exists can be used to determine if an entity still exists.

Despawning with parents

The Subspawn is the same as Spawn except it takes a parent entity as its subject parameter. If not provided explicitly, the parent is taken from the this context variable. Before a parent despawns, all of its children are despawned first.

pub fn Example() {
Spawn hero {
Subspawn projectile { // despawn `projectile` when `hero` is despawned
// Initialization code goes here
}
}
}

An entity can be assigned additional parent entities using DespawnBefore.

pub fn scene.Example() {
Spawn hero {
Subspawn projectile { // despawn `projectile` when `hero` is despawned
DespawnBefore(scene) // also despawn `projectile` when `scene` is despawned
}
}
}
tip

If an entity depends on another one and will error when it stops existing, use Subspawn or DespawnBefore to make sure it is despawned. For example, an effect entity that applies a slow to a hero entity should be despawned before the hero entity is despawned. This is the perfect use case for Subspawn or DespawnBefore.

Executing code before despawn

To execute code before an entity despawns, use the await BeforeDespawn function. Like all await functions, this would either be called with an await keyword or a once block. This function returns just before the entity despawns, and if the entity has already despawned, it will return immediately.

pub fn Example() {
Spawn projectile {
once BeforeDespawn {
// Code to execute before despawning
}
}
}

Multi-purpose entities

The same entity can and should be used for many purposes at once. For example, a projectile entity can be used to represent a projectile in the game world, but also at the same time may be applying a slowing buff to its caster. It is both a projectile and an effect at the same time. There is no need to spawn a separate entity for each purpose. In Easel, one entity can be many things at once.

Querying entities

A number of functions exist to query all entities.

  • Query returns an array of all entities that match the criteria.
  • QueryAny returns the first entity that matches the criteria. This is useful when you only want to find one entity, and it does not matter which one.
  • QueryCount returns the number of entities that match the criteria.