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.

FieldTypeMandatory?
idUUIDyes
blueprintStringno
nameStringyes
descriptionStringyes
tagsHashMap<String, Tag>no
attributesHashMap<String, Attribute>yes
propertiesHashMap<String, Property>no
buffsHashMap<Uuid, Buff>no
versionStringno

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 KeyTag Value
controlled_byplayer
typeenemy
faction161

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 NameAttribute ValueType
health90i64
speed200.0f64
damage_multiplier1.5f64

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 NameProperty ValueType
colorblueString
level10i64
is_aggressivetruebool

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.