Entity-Component System

Source: resources/modules/xs/ec.wren


Class Component ↗

Base class for components that can be added to entities

Components should inherit from this class and override initialize(), update(), and/or finalize()

Each entity can only have one component of each type

construct new() ↗

Creates a new component

IMPORTANT: Always call super() first when creating a new component subclass constructor

Note: Other components might not be available yet - use initialize() to query them

initialize() ↗

Called right before the first update

This is the ideal place to query and cache references to other components on the same entity

Example: _transform = owner.get(Transform)

finalize() ↗

Called when the component/entity is deleted

Clean up any references to other entities and components by setting them to null

This prevents memory leaks from circular references

update(dt: Num) ↗

Called once per frame with delta time in seconds

Put your game logic here - this is only called when the component is enabled

dt is typically 1/60 (0.0166...) for 60 FPS

owner -> Entity ↗

Gets the Entity object that owns this component

owner=(o: Entity) ↗

Sets the owner (used internally by Entity)

enabled -> Bool ↗

Checks if the component is enabled

If not enabled, the update() function will not be called

enabled=(e: Bool) ↗

Sets the enabled state of the component

initialized_ -> Bool ↗

Gets the initialized state (used internally by Entity)

initialized_=(i: Bool) ↗

Sets the initialized state (used internally by Entity)


Class Entity ↗

Represents a game object that can contain multiple components

Entities are managed by the Entity-Component system and should be created with Entity.new()

Call Entity.initialize() and Entity.update(dt) in your game's initialize() and update() methods

construct new() ↗

Creates a new entity that will be visible to the rest of the game in the next update

The entity won't appear in Entity.entities until the next frame

add(component: Component) -> Component ↗

Adds a component to the entity

The component must be a subclass of Component

If a component of the same type already exists, it will be finalized and replaced

Components are initialized and updated in the order they were added

get(type) ↗

Gets a component of the matching type, or null if not found

Example: var transform = entity.get(Transform)

remove(type) ↗

Marks a component for removal at the end of the current update frame

The component's finalize() method will be called before removal

components -> Sequence ↗

Gets all components attached to this entity

deleted -> Bool ↗

Checks if the entity is marked for deletion

If true, you should set any references to this entity to null to avoid accessing deleted entities

delete() ↗

Marks the entity for removal at the end of the current update frame

All components will have their finalize() methods called before the entity is removed

name -> String ↗

Gets the name of the entity (useful for debugging)

name=(n: String) ↗

Sets the name of the entity

tag -> Num ↗

Gets the tag (used as a bitflag when filtering entities)

tag=(t: Num) ↗

Sets the tag

enabled=(e: Bool) ↗

Sets the enabled state of all components

static initialize() ↗

Initializes the entity system - MUST be called once at game startup

Call this from your game's initialize() method before creating any entities

Example: Entity.initialize()

static update(dt: Num) ↗

Updates all entities and their components - MUST be called every frame

Call this from your game's update(dt) method

Handles adding new entities, removing deleted ones, and updating all component logic

Example: Entity.update(dt)

static withTag(tag: Num) -> List ↗

Gets all entities where the tag matches exactly with the given tag (using bitwise AND)

Use this when you need entities with ALL specified tag bits set

static withTagOverlap(tag: Num) -> List ↗

Gets all entities where the tag has ANY bit overlap with the given tag

Use this when you need entities with at least one matching tag bit

static withoutTagOverlap(tag: Num) -> List ↗

Gets all entities where the tag does not have bit overlap with the given tag

static setEnabled(tag: Num, enabled: Bool) ↗

Sets the enabled state for all entities with matching tag overlap

static entities -> List ↗

Gets all entities active in the system

static inspect(filter: String) ↗

Displays entity inspector UI with filtering (called from C++ inspector)

filter: string to filter entities by name or tag

toString -> String ↗

Returns a string representation of this entity

static print() ↗

Prints a formatted list of all entities and their components (for debugging)

static inspectComponent_(component, compIndex) ↗

Inspects a single component, showing its properties via attributes

static displayEditableProperty_(componentName, propName, value, metadata) ↗

Displays an editable property and returns the new value

static getInspectableProperties_(component) ↗

Gets all inspectable properties from a component using attributes

static getPropertyValue_(component, propName) ↗

Gets a property value from a component using reflection

static setPropertyValue_(component, propName, value) ↗

Sets a property value on a component using reflection

static hasSetter_(component, propName) ↗

Checks if a component has a setter for a property

static formatValue_(value) ↗

Formats a value for display

removeDeletedComponents_() ↗

Removes components marked for deletion (used internally)