Components
github.com/mechanical-lich/ml-rogue-lib/pkg/rlcomponents
All ECS component types used by ML Rogue Lib systems. Add these to *ecs.Entity instances to opt them into the relevant behaviors.
Component Type Constants
All constants are of type ecs.ComponentType (a string).
const (
Health = "Health"
Stats = "Stats"
Energy = "Energy"
Initiative = "Initiative"
MyTurn = "MyTurn"
TurnTaken = "TurnTaken"
Dead = "Dead"
Description = "Description"
Solid = "Solid"
Inanimate = "Inanimate"
NeverSleep = "NeverSleep"
Nocturnal = "Nocturnal"
WanderAI = "WanderAI"
HostileAI = "HostileAI"
DefensiveAI = "DefensiveAI"
AIMemory = "AIMemory"
Alerted = "Alerted"
Poisoned = "Poisoned"
Poisonous = "Poisonous"
Burning = "Burning"
Haste = "Haste"
Slowed = "Slowed"
DamageCondition = "DamageCondition"
StatCondition = "StatCondition"
Regeneration = "Regeneration"
LightSensitive = "LightSensitive"
Light = "Light"
Door = "Door"
Food = "Food"
Inventory = "Inventory"
Item = "Item"
Armor = "Armor"
Weapon = "Weapon"
Body = "Body"
BodyInventory = "BodyInventory"
)
Position and Direction are defined in their own files but follow the same convention.
Core Components
PositionComponent
type PositionComponent struct {
X, Y, Z int
Level int
}
Tracks an entity’s grid coordinates. Level is an optional floor/level index for multi-level dungeons.
Methods:
| Method | Signature | Description |
|---|---|---|
GetX | () int | Returns the X coordinate |
GetY | () int | Returns the Y coordinate |
GetZ | () int | Returns the Z coordinate |
SetPosition | (x, y, z int) | Updates all three coordinates at once |
HealthComponent
type HealthComponent struct {
MaxHealth int
Health int
Energy int
}
Tracks hit points and energy. When Health drops to ≤ 0, rlai.HandleDeath (or DeadComponent) marks the entity as dead.
StatsComponent
type StatsComponent struct {
AC int
Str int
Dex int
Int int
Wis int
BasicAttackDice string
BaseDamageType string
Resistances []string
Weaknesses []string
}
D&D-style combat statistics. BasicAttackDice uses MLGE’s dice expression format (e.g. "1d6", "2d8+2"). Resistances and Weaknesses hold damage type strings (e.g. "fire", "slashing").
DescriptionComponent
type DescriptionComponent struct {
Name string
Faction string
}
Display name and optional faction. Entities sharing the same non-empty Faction are considered friendly by rlcombat.IsFriendly.
EnergyComponent
type EnergyComponent struct {
Speed int
Energy int
LastActionCost int
}
Tick-up action point system. Each tick, Energy increases by Speed. The entity can act whenever Energy > 0. Actions set LastActionCost, which is deducted by SpendTurn. Leftover energy carries over, enabling multi-action turns. See rlenergy for the turn management helpers that drive this component.
Methods:
| Method | Signature | Description |
|---|---|---|
CanAct | () bool | Returns true if Energy > 0 |
SpendTurn | () int | Deducts LastActionCost from Energy, resets LastActionCost, returns the cost |
TurnTakenComponent
Marker component added by game systems when an entity has consumed its turn. ResolveTurn (in rlenergy) checks for both MyTurn and TurnTaken before deducting cost and stripping markers.
func GetTurnTaken() *TurnTakenComponent
InitiativeComponent
type InitiativeComponent struct {
DefaultValue int
OverrideValue int
Ticks int
}
Controls turn timing. Ticks decrements each frame by InitiativeSystem.Speed. When it reaches 0 the entity receives MyTurn. Lower DefaultValue means more frequent turns. OverrideValue > 0 replaces DefaultValue for the next reset.
MyTurnComponent
A marker component added by InitiativeSystem or rlenergy.AdvanceEnergy when an entity’s turn arrives. Removed by cleanup logic at the end of each frame. Systems that should act once per turn check for this component.
// GetMyTurn returns a pooled *MyTurnComponent.
func GetMyTurn() *MyTurnComponent
DeadComponent
Marker component added when an entity’s Health reaches zero. CleanUpSystem removes entities carrying this component from the level each frame.
AI Components
WanderAIComponent
Marker component. Entities carrying this component move randomly via AISystem.
HostileAIComponent
type HostileAIComponent struct {
SightRange int
TargetX int
TargetY int
Path []path.Pather
}
Causes the entity to pursue and attack the nearest valid target within SightRange. Path caches the current A* route.
DefensiveAIComponent
type DefensiveAIComponent struct {
Attacked bool
AttackerX int
AttackerY int
}
Set by rlcombat.TriggerDefenses when the entity is hit. Causes the entity to turn toward and flee from or retaliate against the attacker position.
AIMemoryComponent
type AIMemoryComponent struct {
Attacked bool
AttackerX int
AttackerY int
}
Persistent attack memory that survives across turns, unlike DefensiveAIComponent.
NeverSleepComponent
Marker component. Entities carrying this always receive MyTurn regardless of time of day.
NocturnalComponent
Marker component. Entities only receive MyTurn when level.IsNight() returns true (unless also Alerted).
Status Effect Components
All status effects implement DecayingComponent — a shared interface that decrements a duration counter and returns true when the effect has expired.
type DecayingComponent interface {
Decay() bool
}
Effects that modify entity stats while active also implement ConditionModifier. The StatusConditionSystem calls ApplyOnce on the first tick and Revert when the component is removed.
type ConditionModifier interface {
ApplyOnce(entity *ecs.Entity)
Revert(entity *ecs.Entity)
}
AlertedComponent
type AlertedComponent struct { Duration int }
Overrides nocturnal/diurnal scheduling: an alerted entity always acts. Decays over Duration turns.
PoisonedComponent
type PoisonedComponent struct { Duration int }
Deals 1 HP damage per turn via StatusConditionSystem. Decays over Duration turns.
PoisonousComponent
type PoisonousComponent struct { Duration int }
Applied to attackers. When they hit a target, rlcombat.ApplyStatusEffects transfers a PoisonedComponent to the defender.
BurningComponent
type BurningComponent struct { Duration int }
Deals 2 HP damage per turn via StatusConditionSystem. Decays over Duration turns.
HasteComponent
type HasteComponent struct { Duration int }
Doubles the entity’s EnergyComponent.Speed while active. Implements ConditionModifier — speed is doubled on the first tick and restored exactly when the component expires. Decays over Duration turns.
SlowedComponent
type SlowedComponent struct { Duration int }
Halves the entity’s EnergyComponent.Speed while active (minimum 1). Implements ConditionModifier — speed is halved on the first tick and restored exactly when the component expires. Decays over Duration turns.
DamageConditionComponent
type DamageConditionComponent struct {
Name string
Duration int
DamageDice string
DamageType string
}
A general-purpose damage-over-time effect. Each turn StatusConditionSystem calls Roll() and routes the result through the standard damage path (random body part if BodyComponent is present, otherwise HealthComponent).
DamageDice uses MLGE’s dice expression format (e.g. "1d6", "2d4+1", "3"). DamageType is informational (e.g. "poison", "fire").
Name is displayed in status UIs.
Method:
| Method | Signature | Description |
|---|---|---|
Roll | () int | Evaluates DamageDice and returns the result (minimum 1). Returns 1 on a parse error. |
Example:
// 1d4 venom damage for 6 turns
entity.AddComponent(&rlcomponents.DamageConditionComponent{
Name: "Venom",
Duration: 6,
DamageDice: "1d4",
DamageType: "poison",
})
StatConditionComponent
type StatMod struct {
Stat string
Delta int
}
type StatConditionComponent struct {
Name string
Duration int
Mods []StatMod
}
A general-purpose temporary stat modifier. Implements ConditionModifier — all Mods are applied on the first tick and reverted exactly when the component expires.
Supported Stat values: "ac", "str", "dex", "con", "int", "wis", "melee_attack_bonus", "ranged_attack_bonus".
Name is displayed in status UIs.
Examples:
// +2 AC for 5 turns ("Hardened")
entity.AddComponent(&rlcomponents.StatConditionComponent{
Name: "Hardened",
Duration: 5,
Mods: []rlcomponents.StatMod,
})
// +3 STR, −1 DEX for 8 turns ("Hormonal Surge")
entity.AddComponent(&rlcomponents.StatConditionComponent{
Name: "Hormonal Surge",
Duration: 8,
Mods: []rlcomponents.StatMod{
{Stat: "str", Delta: 3},
{Stat: "dex", Delta: -1},
},
})
RegenerationComponent
type RegenerationComponent struct { Amount int }
Restores Amount HP per turn (capped at MaxHealth) via StatusConditionSystem.
LightSensitiveComponent
Marker component. Handled by StatusConditionSystem if a game registers logic for it via OnStatusEffect.
Item & Equipment Components
InventoryComponent
type InventoryComponent struct {
LeftHand *ecs.Entity
RightHand *ecs.Entity
Head *ecs.Entity
Torso *ecs.Entity
Legs *ecs.Entity
Feet *ecs.Entity
Bag []*ecs.Entity
StartingInventory []string
}
Holds equipped items in named slots and a list of carried items in Bag. StartingInventory contains blueprint names to give the entity on spawn.
Methods:
| Method | Signature | Description |
|---|---|---|
AddItem | (item *ecs.Entity) | Appends item to Bag |
RemoveItem | (item *ecs.Entity) bool | Removes item from Bag by pointer |
RemoveItemByName | (name string) bool | Removes first item in Bag matching Blueprint |
RemoveAll | (name string) bool | Removes all items matching DescriptionComponent.Name |
HasItem | (name string) bool | Returns true if Bag contains an item with that name |
Equip | (item *ecs.Entity) | Equips item to the appropriate slot based on ItemComponent.Slot |
GetAttackModifier | () int | Sum of attack modifiers from equipped weapons |
GetDefenseModifier | () int | Sum of defense modifiers from equipped armor |
GetAttackDice | () string | Returns the attack dice of the equipped weapon, or "" |
ItemComponent
type ItemComponent struct {
Slot string // e.g. "RightHand", "Head", "Torso"
}
Marks an entity as an equippable item. Slot determines which InventoryComponent slot it occupies when equipped.
WeaponComponent
type WeaponComponent struct {
AttackDice string
AttackBonus int
DamageType string
}
ArmorComponent
type ArmorComponent struct {
DefenseBonus int
Resistances []string
}
BodyComponent
type BodyPart struct {
Name string
Description string
AttachedTo []string // parts this part connects to (informational)
HP int
MaxHP int
Broken bool
Amputated bool
KillsWhenBroken bool
KillsWhenAmputated bool
CompatibleItemSlots []ItemSlot
}
type BodyComponent struct {
Parts map[string]BodyPart
}
Replaces (or supplements) HealthComponent with a per-part damage model. Each named part tracks its own HP, break state, and amputation state.
Methods:
| Method | Signature | Description |
|---|---|---|
AddPart | (part BodyPart) | Registers a body part by part.Name; initialises Parts if nil |
Part lifecycle:
- A part becomes Broken when
HPdrops to zero or below. - A part becomes Amputated when a single hit deals
damage >= MaxHP * 2. - If
KillsWhenBrokenorKillsWhenAmputatedistrue, aDeadComponentis added to the entity when that condition is met.
Death detection with BodyComponent:
rlentity.HandleDeath checks vital part conditions first (broken/amputated with KillsWhen*). If none are met it falls through to the HealthComponent check, so both systems can coexist on the same entity.
Status effect damage with BodyComponent:
StatusConditionSystem routes poison/burning damage to a random non-amputated body part. If all parts are amputated it falls back to HealthComponent.
BodyInventoryComponent
type BodyInventoryComponent struct {
Equipped map[string]*ecs.Entity // keyed by BodyPart.Name
Bag []*ecs.Entity
StartingInventory []string
}
An inventory whose equipment slots map directly to body-part names. Use alongside BodyComponent. A body part accepts an item when the item’s ItemComponent.Slot is listed in BodyPart.CompatibleItemSlots.
Bag methods (mirror InventoryComponent):
| Method | Signature | Description |
|---|---|---|
AddItem | (item *ecs.Entity) | Appends to Bag |
RemoveItem | (item *ecs.Entity) bool | Removes by pointer |
RemoveItemByName | (name string) bool | Removes first match by Blueprint name |
RemoveAll | (name string) bool | Removes all matching DescriptionComponent.Name |
HasItem | (name string) bool | Returns true if Bag contains a matching item |
Equip methods:
| Method | Signature | Description |
|---|---|---|
EquipToBodyPart | (item *ecs.Entity, partName string) | Places item in the named part slot; bumps existing item to Bag |
AutoEquip | (item *ecs.Entity, bc *BodyComponent) bool | Finds the first compatible, non-amputated slot; prefers empty slots |
Unequip | (partName string) *ecs.Entity | Returns equipped item to Bag; returns nil if empty |
UnequipAll | () | Returns all equipped items to Bag |
HandleAmputation | (partName string) *ecs.Entity | Unequips the amputated part’s item |
EquipBest | (slot ItemSlot, bc *BodyComponent) | Re-equips the highest-value bag item for the given slot |
EquipAllBest | (bc *BodyComponent) | Calls EquipBest for every slot accepted by any body part |
Combat stat methods:
| Method | Signature | Description |
|---|---|---|
GetAttackModifier | () int | Sum of WeaponComponent.AttackBonus from all equipped weapons |
GetAttackDice | () string | Combined dice string for all equipped weapons |
GetDefenseModifier | () int | Sum of ArmorComponent.DefenseBonus from all equipped armor |
GetDamageType | () string | Damage type of the first equipped weapon, or "" |
GetResistances | () []string | All resistance types from all equipped armor |
FoodComponent
type FoodComponent struct { Amount int }
Tracks remaining nutrition. rlai.Eat decrements Amount by one. CleanUpSystem skips removal of dead food entities while Amount > 0.
Environment Components
SolidComponent
Marker component. Entities carrying this block movement.
InanimateComponent
Marker component. Tells the ECS that this entity never acts (static objects). Sets ecs.InanimateComponentType automatically via init().
DoorComponent
type DoorComponent struct {
Open bool
Locked bool
OpenedSpriteX int
OpenedSpriteY int
ClosedSpriteX int
ClosedSpriteY int
OwnedBy string
}
OwnedBy is a faction or settlement name. Entities belonging to that faction may pass through regardless of Locked. DoorSystem syncs sprite coordinates to the Open state each frame.
LightComponent
Marker component for light-emitting entities. Specific properties depend on game implementation.
DirectionComponent
type DirectionComponent struct { Direction int }
Tracks facing direction: 0 = right, 1 = down, 2 = up, 3 = left. Updated by rlai.Face.