Table of Contents

Class EntityStats

Namespace
ElectricDrill.AstraRpgFramework.Stats
Assembly
com.electricdrill.astra-rpg-framework.Runtime.dll

Component that manages the statistics of an entity in the game. It handles base stats, flat stat modifiers, stat to stat modifiers, and percentage stat modifiers.
Base stats can either be fixed or come from the entity's class (if one is available on the Game Object). When stats change because of a modifier of any kind, the assigned StatChangedGameEvent is raised.

[DisallowMultipleComponent]
[RequireComponent(typeof(EntityCore))]
public class EntityStats : MonoBehaviour, IHasStatSet, IValueProvider<StatSO, long>, IStatReader, IValueContainer<StatSO>, IHasEntity, IEventRegistrar
Inheritance
object
EntityStats
Implements
Extension Methods

Fields

_entityClass

protected IClassSource _entityClass

Field Value

IClassSource

_flatModifiers

protected StatSetInstance _flatModifiers

Field Value

StatSetInstance

_percentageModifiers

protected StatSetInstance _percentageModifiers

Field Value

StatSetInstance

Properties

Entity

The primary EntityCore associated with this object. For entity components this is the owning entity; for context payloads this is the primary affected subject (e.g. the event target).

public EntityCore Entity { get; }

Property Value

EntityCore

EntityClass

The class source of the entity. In most cases, this is the EntityClass component attached to the entity.

public IClassSource EntityClass { get; }

Property Value

IClassSource

EntityCore

The entity core associated with this stats component.

public EntityCore EntityCore { get; }

Property Value

EntityCore

FixedStatValuesAsset

Gets or sets the asset-backed fixed stat source used when UseFixedStatValuesAsset is true.

public FixedStatValuesSO FixedStatValuesAsset { get; set; }

Property Value

FixedStatValuesSO

OnStatChanged

Event raised when a Stat changes.

public StatChangedGameEvent OnStatChanged { get; }

Property Value

StatChangedGameEvent

StatSet

The stat set used to calculate the entity's stats.

public virtual StatSetSO StatSet { get; }

Property Value

StatSetSO

If _useBaseStatsFromClass is true, it returns the stat set of the entity's class. Otherwise, it returns the fixed base stats stat set.

UseClassBaseStats

Gets or sets whether to use the base stats from the entity's class. If true, the base stats are taken from the EntityClass. If false, the base stats are taken from the fixed base stats defined in this component.

public bool UseClassBaseStats { get; set; }

Property Value

bool

Remarks

Publicly settable so a save system can restore which base-stat source an entity was using, matching its twin UseBaseAttributesFromClass. Switching source does not raise stat-changed events by itself; the next read reflects the new source. Restore it to false before calling SetFixedStatSource(IFixedStatSource), which warns while this is true because the values it writes stay unused until the entity is back on fixed base stats.

UseFixedStatValuesAsset

Gets or sets whether fixed base stats are sourced from FixedStatValuesAsset instead of the inline values. Only meaningful when UseClassBaseStats is false.

public bool UseFixedStatValuesAsset { get; set; }

Property Value

bool

Methods

AddFlatModifier(StatSO, long)

Adds a flat modifier to a stat. Dependent stats (those that use stat as a stat-to-stat source) are captured via the reverse index and their old values stored in a stack-allocated or pooled buffer — no per-call dictionary allocation.

public void AddFlatModifier(StatSO stat, long value)

Parameters

stat StatSO

The stat to add the flat modifier to.

value long

The value of the flat modifier.

AddPercentageModifier(StatSO, Percentage)

Adds a Percentage modifier to a stat. Such modifiers consider the base value of the stat, the flat modifiers, and the stat-to-stat modifiers.

public void AddPercentageModifier(StatSO stat, Percentage value)

Parameters

stat StatSO

The stat to add the percentage modifier to.

value Percentage

The value of the percentage modifier.

AddStatToStatModifier(StatSO, StatSO, Percentage)

Adds a stat-to-stat modifier. Such modifiers add a percentage of the source stat to the target stat. Such modifiers consider the base value and the flat modifiers of the source stat.

public void AddStatToStatModifier(StatSO target, StatSO source, Percentage percentage)

Parameters

target StatSO

The target stat.

source StatSO

The source stat.

percentage Percentage

The Percentage of the source stat to add to the target stat.

BeginBulk()

Opens a bulk-update bracket. While the bracket is open, stat-changed events are deferred: each affected stat is recorded in a dirty set with its pre-mutation snapshot, and a single OnStatChanged event (plus callback) is raised per genuinely-changed stat when the outermost bracket disposes. Nested brackets are supported; flush happens only on the outermost dispose.

public EntityStats.BulkUpdateScope BeginBulk()

Returns

EntityStats.BulkUpdateScope

Remarks

Intended for broad mutations such as level-up/down, class swap, or RefundAll cascades. The dirty set and snapshot dictionary are reused across brackets — no per-bracket heap allocation.

ComputeFinalAt(StatSO, int)

Computes the stat's final value as it would be at the specified entity level, without touching the runtime cache. Used to snapshot old/new values around level changes and by any consumer that needs a per-level projection.

public long ComputeFinalAt(StatSO stat, int level)

Parameters

stat StatSO

The stat to compute.

level int

The level at which to evaluate the stat.

Returns

long

The clamped final value at the given level, or 0 if the component is disabled.

Remarks

Pure and cache-free: safe to interleave with Get(StatSO). Disabled components always return 0. Dependent flat values (for stat-to-stat modifiers) are also evaluated at the same level so the cascade stays internally consistent.

Contains(StatSO)

Returns whether stat is tracked by this component's stat set.

public bool Contains(StatSO stat)

Parameters

stat StatSO

Returns

bool

Get(StatSO)

The final value of a stat, considering all the modifiers. Calculation is done in the following order:

  1. Base value
  2. Flat modifiers
  3. Stat to stat modifiers
  4. Percentage modifiers
public virtual long Get(StatSO stat)

Parameters

stat StatSO

The stat to get the final value of.

Returns

long

The final value of the stat if the component is enabled (clamped to min/max values); otherwise, 0

GetBase(StatSO)

The base value is the value of the stat without any modifiers. If UseClassBaseStats is true, it returns the value from the entity's class. Otherwise, it returns the value from the fixed base stats.

public long GetBase(StatSO stat)

Parameters

stat StatSO

The stat to get the base value of.

Returns

long

The base value of the stat (clamped to the stat's min and max values) if enabled; otherwise, 0

GetFixedBaseStatValues()

Reads back every fixed base stat value, in the shape SetFixedStatSource(IReadOnlyDictionary<StatSO, long>) expects — the bulk getter that pairs with the bulk setter, so a save system does not have to walk StatSet and call GetBase(StatSO) itself. Allocates a copy.

public IReadOnlyDictionary<StatSO, long> GetFixedBaseStatValues()

Returns

IReadOnlyDictionary<StatSO, long>

A read-only snapshot of the fixed base stat values.

Remarks

Keyed on the stats of the fixed base stat set, and read through the source currently backing them: the values in FixedStatValuesAsset when UseFixedStatValuesAsset is on, the inline values otherwise. Unaffected by UseClassBaseStats — class-derived base values are design-time data owned by the ClassSO, and are not this component's state to hand out.

OnLevelDown(EntityLevelChangedContext)

Callback method called when the entity levels down. Symmetric to OnLevelUp(EntityLevelChangedContext): snapshots old values at the pre-change level, invalidates the cache inside a bulk scope, and defers event raising until the bracket closes.

protected virtual void OnLevelDown(EntityLevelChangedContext context)

Parameters

context EntityLevelChangedContext

The context of the level down event.

OnLevelUp(EntityLevelChangedContext)

Callback method called when the entity levels up. Opens a bulk scope, pre-snapshots every stat's final value at the previous level via ComputeFinalAt(StatSO, int), then invalidates the cache so the flush recomputes against the new level. One OnStatChanged event is raised per stat whose value actually changed across the level transition.

protected virtual void OnLevelUp(EntityLevelChangedContext context)

Parameters

context EntityLevelChangedContext

The context of the level up event.

RebuildDependencyIndex()

Forces the reverse dependency indices (attribute -> dependent stats, source stat -> dependent stats) to be rebuilt on the next access. Call after mutating scaling maps or the StatSet at runtime so cascade propagation stays correct.

public void RebuildDependencyIndex()

SetFixed(StatSO, long)

Sets the value of a fixed base stat. This is only applicable when UseClassBaseStats is false.

public void SetFixed(StatSO stat, long value)

Parameters

stat StatSO

The stat to set.

value long

The value to set.

SetFixedStatSet(StatSetSO)

Replaces the StatSetSO used for fixed (non-class) base stats at runtime. Reconciles ElectricDrill.AstraRpgFramework.Stats.EntityStats._fixedStatValues to the new set's stats (preserving values for stats present in both) and invalidates the cache. Does not raise per-stat change events, matching the existing schema-change path taken when ElectricDrill.AstraRpgFramework.Stats.EntityStats.OnValidate() itself detects a set change.

public void SetFixedStatSet(StatSetSO newStatSet)

Parameters

newStatSet StatSetSO

The stat set to switch to.

SetFixedStatSource(IFixedStatSource)

Replaces every fixed base stat value from source, applied immediately. Only meaningful when UseClassBaseStats is false. Always writes into the inline ElectricDrill.AstraRpgFramework.Stats.EntityStats._fixedStatValues — never into FixedStatValuesAsset, since that asset may be shared by other entities and a per-entity runtime override should not leak into it. source must cover every stat in the current StatSet. Snapshots every affected stat's current value before mutating any of them — required because stat-to-stat modifiers make a stat's value depend on another stat's, so an interleaved read/write loop could let a later stat's "old" snapshot observe an already-mutated earlier stat — then raises one OnStatChanged event per stat whose final value actually changed.

public void SetFixedStatSource(IFixedStatSource source)

Parameters

source IFixedStatSource

The fixed stat source to copy values from. Must not be null.

SetFixedStatSource(IReadOnlyDictionary<StatSO, long>)

Convenience overload of SetFixedStatSource(IFixedStatSource) for consumers supplying values as a plain dictionary (e.g. deserialized save data or imported balance data), without needing to implement IFixedStatSource themselves.

public void SetFixedStatSource(IReadOnlyDictionary<StatSO, long> values)

Parameters

values IReadOnlyDictionary<StatSO, long>

The fixed base stat values to apply.

Subscribe<TEvent>(TEvent)

Registers gameEvent on the channel matching TEvent.

public void Subscribe<TEvent>(TEvent gameEvent) where TEvent : ScriptableObject

Parameters

gameEvent TEvent

Type Parameters

TEvent

Exceptions

ArgumentException

Thrown when no channel is registered for TEvent.

TryGet(StatSO, out long)

Tries to get the final value of a stat. Returns true if the stat is contained in the stat set; otherwise, false.

public bool TryGet(StatSO stat, out long value)

Parameters

stat StatSO

The stat to get.

value long

When this method returns, contains the final value of the stat if the stat is contained in the stat set; otherwise, 0.

Returns

bool

true if the stat is contained in the stat set; otherwise, false.

TryGetBase(StatSO, out long)

Tries to get the base value of a stat (before any modifiers are applied). Returns true if the stat is contained in the stat set; otherwise, false.

public bool TryGetBase(StatSO stat, out long value)

Parameters

stat StatSO

The stat to get the base value of.

value long

When this method returns, contains the base value of the stat if the stat is contained in the stat set; otherwise, 0.

Returns

bool

true if the stat is contained in the stat set; otherwise, false.

Unsubscribe<TEvent>(TEvent)

Removes gameEvent from the channel matching TEvent.

public void Unsubscribe<TEvent>(TEvent gameEvent) where TEvent : ScriptableObject

Parameters

gameEvent TEvent

Type Parameters

TEvent

Exceptions

ArgumentException

Thrown when no channel is registered for TEvent.

Events

OnStatChangedCallback

Entity-local C# event raised whenever a stat value changes on this component. Fired alongside OnStatChanged (SO-based) for each stat change. Use this for direct code subscriptions where a ScriptableObject event reference is inconvenient (Currently reserved for future use with EntityModifiers stat-driven max stacks trimming).

public event Action<StatChangeInfo> OnStatChangedCallback

Event Type

Action<StatChangeInfo>