Alacrity Entities
In the realm of game development, managing entities is a fundamental task. Entities are the core building blocks that breathe life into your game world. In Alacrity library, entities take center stage, and understanding them is crucial for crafting immersive gaming experiences. This chapter delves deep into Alacrity entities, dissecting their structure and exploring their significance in game development.
Unveiling the Entity
At its core, an entity represents a game object within your virtual world. A player a weapon or an enemy can be modeled as an Alacrity entity. These entities are not mere static elements; they are dynamic evolving entities that can be create, updated and even destroyed as your game unfolds.
Entities serve as a canvas upon which you paint the rich tapestry of your game's interactions, attributes and behaviors. Each entity is defined by a set of properties, attributes, tags and buffs.
Anatomy of an Entity
Entities are composed of several fields that define their properties and behavior in the simulation.
| Field | Type | Mandatory? |
|---|---|---|
| id | UUID | yes |
| blueprint | String | no |
| name | String | yes |
| description | String | yes |
| tags | HashMap<String, Tag> | no |
| attributes | HashMap<String, Attribute> | yes |
| properties | HashMap<String, Property> | no |
| buffs | HashMap<Uuid, Buff> | no |
| version | String | no |
We will review all of this fields in detail below
Identification and Description
ID
Each entity has a unique ID that identifies it within the game world. IDs are UUIDs and they must be guaranteed to be unique. Users of the library are responsible from creating and providing these unique IDs, if you need guidance about how to properly achieve that take a look to the Generating UUIDs section.
An entity ID looks like this:
38a29473-1678-46b2-a7a8-ba9df7621faf
Blueprint
When an entity is instantiated from a template or blueprint, this field will contain the ID that refers to said template or blueprint.
Name
This is a human-readable name for the entity that can be used for display purposes, debugging, and other similar.
Description
A brief description of the entity, which can be used for documentation, tooltips and other similar purposes.
Version
The entity's version. It can be used to track entities versions or to update or migrate entities data when a version change is detected. Each entity blueprint has to be in an specific version (0.0.1 by default).
Tags: Classifying Entities
Tags are key-value pairs that provide additional information about the entity. They can be used to categorize entities, associate them with specific game systems or mechanics, or provide other types of metadata. They are also used by the buff's propagation system to determine if a buff must propagate from an entity to another one by looking at specific tags on propagation maps rules.
Tags values can be of any supported type by Alacrity's Value type
🚨 tags with i64 values are used in bitwise operations. That means that the only valid values they can hold are powers of 2 (1, 2, 4, 8, 16, 32...) so basically they can hold up to 64 different values. Use these as masks for bitwise comparisons
Some examples of tags could be
| Tag Key | Tag Value |
|---|---|
| controlled_by | player |
| type | enemy |
| faction | 161 |
1: This value could be assigned to a constant like FACTION_CAMELOT 1 << 4
Attributes: Defining Behavior
Attributes holds numerical values that represent the state of an entity. They are modified by buffs and are calculated to provide the entity with its final attribute's state values. Attributes can not be mutated trough any other means, they are completely immutable from the API perspective. They are always taken into account on buffs and buff's modifiers condition checks, you can not opt out them from being passed into the entity's scope when a condition is being evaluated. We will extend about this topic in the conditions section in later chapters.
Examples of attributes might include the following
| Attribute Name | Attribute Value | Type |
|---|---|---|
| health | 90 | i64 |
| speed | 200.0 | f64 |
| damage_multiplier | 1.5 | f64 |
Properties: Storing Information
Properties holds numerical, string or boolean values that represent properties or non modifiable (by buffs) state of an entity. Properties are used to store data that is less frequently accessed and/or modified during gameplay. Properties are not modified by buffs and/or buff's modifiers but they can be managed, including update, creation and deletion using both Rust and Lua APIs. Properties are taken into account for conditions checks but it can be opt out.
Examples of properties might include
| Property Name | Property Value | Type |
|---|---|---|
| color | blue | String |
| level | 10 | i64 |
| is_aggressive | true | bool |
Buffs: The Effects of Change
The "buffs" field on an entity represents the collections of buffs that can be applied to the entity it is attached to. Buffs are temporary effects that modify the attributes of an entity. They can enhance or weaken the entity's stats or abilities, alter its behavior, or introduce specific conditions for its actions.
Example of a buff spec blueprint to be used with an entity:
{
id = "5a0b8a00-ed2d-4120-839a-595df4b7fe30", -- Unique ID for the buff (all instances of this buff will share this ID)
name = "hero_strength_boost_01_001_a", -- Name of the buff
description = "Increase the entity's strength attribute by 10%", -- Human friendly description of the buff
effect_id = 65536, -- Mask for the effect associated with the buff (base 2 value for masking)
-- Modifiers define the changes to apply to the entity's attributes
modifiers = {
name = "str_base_10_percent_multiplier", -- Modifier name
description = "Multiplies the target's strength base attribute by 10%", -- Modifier description
max_stacks = 1, -- The modifier's max number of possible stacks
kind = "default", -- The modifier's kind or behavior
value = 0.1, -- The modifier's value or strength
operator = "percent", -- The modifier's operator (can be flat, percent, flatbase, percentbase, flatcalculated or percentcalculated)
-- Modifier's conditions that must need to be met for the modifier to be applied
conditions = {
{
description = "Entity class must be warrior, berserk or paladin", -- Condition's human friendly description
expression = "self.class == 'warrior' or self.class == 'berserk' or self.class == 'paladin'", -- Conditional expression
logical_operator = true, -- The outcome of the above expression must be true for the condition to be met
}
},
},
-- Conditions define the conditions that need to be met in order to activate the buff in the entity
conditions = {
{
description = "Entity level must be equal or superior than 5", -- Condition human friendly description
expression = "self.level >= 5", -- Conditional expression
logical_operator = true, -- The outcome of the above expression must be true for the condition to pass
}
},
effect_stack_policy = "no_stack", -- Impedes the buff to stack with other buffs that shares the same effect_id mask
effect_stack_limit = 1, -- Stack limit for the effect (if it could be stacked up)
expiration = 0, -- Duration of the buff in seconds (0 for permanent)
stack_policy = "no_stack", -- Stack policy for modifiers of this buff (modifiers can honor this or override with their own policies)
stack_limit = 1, -- The limit of stacks for modifiers of this buff (can also be override by modifiers)
}
Buffs are the bread and butter of Alacrity, they will be presented in great detail in the buffs section in later chapters.
Alacrity Entities in Action
Alacrity entities are not stagnant entities; they are brought to life through interactions, modification and application of various game mechanics. In the chapters that follow, we will explore how to create, modify and manage entities using both programmatic and declarative approaches.