Table of Contents

Class Ability

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Represents an in-game ability instance, constructed from an AbilityTemplate and containing all runtime state and events. Resource costs and requirements are determined by ECA conditions on the template's ActivationConditions and each event's Conditions via the IResourceCost interface. Implements ITooltip for consistent UI tooltip display.

public class Ability : ITooltip
Inheritance
Ability
Implements
Inherited Members

Constructors

Ability(AbilityTemplate, List<int>)

Constructs an ability from a template and optional event list.

public Ability(AbilityTemplate template, List<int> abilityEvents = null)

Parameters

template AbilityTemplate

The ability template to use.

abilityEvents List<int>

Optional list of event IDs to add to the ability.

Remarks

Server-only crafting path. ID is set to -1 until the database assigns a persistent ID via the crafting persistence call. Never use this constructor for network-replicated ability instances — use Ability(long, AbilityTemplate, List<int>) with the DB-assigned ID instead.

Ability(long, AbilityTemplate, List<int>)

Constructs an ability from an ability ID, template, and optional event list.

public Ability(long abilityID, AbilityTemplate template, List<int> abilityEvents = null)

Parameters

abilityID long

The unique ability instance ID.

template AbilityTemplate

The ability template to use.

abilityEvents List<int>

Optional list of event IDs to add to the ability.

Ability(long, int, List<int>)

Constructs an ability from an ability ID, template ID, and optional event list.

public Ability(long abilityID, int templateID, List<int> abilityEvents = null)

Parameters

abilityID long

The unique ability instance ID.

templateID int

The template ID to look up.

abilityEvents List<int>

Optional list of event IDs to add to the ability.

Fields

AbilityEvents

All ability events, indexed by event ID, for quick access.

public SortedDictionary<int, AbilityEvent> AbilityEvents

Field Value

SortedDictionary<int, AbilityEvent>

Remarks

SortedDictionary<TKey, TValue> is used intentionally for all event dictionaries so that iteration order is deterministic (ascending event ID). This guarantees identical execution order on client and server during CSP prediction/reconciliation, which Dictionary<TKey, TValue> cannot ensure. The O(log n) cost per lookup is acceptable because event counts per ability are small.

ActivationTime

Total activation time for this ability, including all modifiers.

public float ActivationTime

Field Value

float

Cooldown

Total cooldown for this ability, including all modifiers.

public float Cooldown

Field Value

float

ID

Unique identifier for this ability instance.

public long ID

Field Value

long

LifeTime

Total lifetime of the ability effect, including all modifiers.

public float LifeTime

Field Value

float

OnDestroyEvents

All OnDestroy events, indexed by event ID.

public SortedDictionary<int, AbilityOnDestroyEvent> OnDestroyEvents

Field Value

SortedDictionary<int, AbilityOnDestroyEvent>

OnHitEvents

All OnHit events, indexed by event ID.

public SortedDictionary<int, AbilityOnHitEvent> OnHitEvents

Field Value

SortedDictionary<int, AbilityOnHitEvent>

OnPreSpawnEvents

All OnPreSpawn events, indexed by event ID.

public SortedDictionary<int, AbilityOnPreSpawnEvent> OnPreSpawnEvents

Field Value

SortedDictionary<int, AbilityOnPreSpawnEvent>

OnSpawnEvents

All OnSpawn events, indexed by event ID.

public SortedDictionary<int, AbilityOnSpawnEvent> OnSpawnEvents

Field Value

SortedDictionary<int, AbilityOnSpawnEvent>

OnTickEvents

All OnTick events, indexed by event ID.

public SortedDictionary<int, AbilityOnTickEvent> OnTickEvents

Field Value

SortedDictionary<int, AbilityOnTickEvent>

Speed

Total speed of the ability effect, including all modifiers.

public float Speed

Field Value

float

Version

Version number for this ability instance, used for client synchronization and updates.

public long Version

Field Value

long

Properties

CachedTooltip

Cached tooltip string for this ability, for UI display.

public string CachedTooltip { get; }

Property Value

string

EffectiveType

Returns the effective ability type, accounting for any TypeOverride.

public AbilityType EffectiveType { get; }

Property Value

AbilityType

Icon

Gets the icon sprite from the ability template.

public Sprite Icon { get; }

Property Value

Sprite

Name

The display name of the ability.

public string Name { get; set; }

Property Value

string

Objects

Cache of all active ability objects, organized as a dictionary mapping container IDs to dictionaries of ability object IDs and their corresponding AbilityObject instances.

public Dictionary<int, Dictionary<int, AbilityObject>> Objects { get; }

Property Value

Dictionary<int, Dictionary<int, AbilityObject>>

PersistenceDirty

Whether this ability has changed since the database last confirmed it.

public bool PersistenceDirty { get; }

Property Value

bool

Remarks

The periodic save wrote every known ability of every resident character on every pass, because it had no way to tell which had changed. Almost none ever do: what is stored is the template and the set of event IDs, and those move only when a player crafts, learns or forgets something. Cooldowns are deliberately not persisted, so an ability in constant use produces exactly the same row as one that has sat in a hotbar untouched for a week.

Set true on construction. That over-writes each ability once after a character loads, which is deliberate: it costs one redundant write per ability per login instead of one every save, and it does not depend on knowing which constructor the load path uses. An ability is never missed, only occasionally written when it need not have been.

Set again by FishMMO.Shared.Ability.MarkChanged(), which every mutation of the event set goes through, and cleared only by MarkPersisted(long) once a write has landed.

Range

The effective range of the ability, calculated as Speed * LifeTime.

public float Range { get; }

Property Value

float

Template

The template from which this ability was constructed.

public AbilityTemplate Template { get; }

Property Value

AbilityTemplate

TotalResourceCost

The total resource cost for this ability, summing all IResourceCost amounts. Uses the cached cost dictionary from GetResourceCosts().

public int TotalResourceCost { get; }

Property Value

int

TypeOverride

Optional override for the ability type, set by certain events.

public AbilityTypeOverrideEventType TypeOverride { get; }

Property Value

AbilityTypeOverrideEventType

Methods

AddEvent(AbilityEvent)

Adds a single ability event to the appropriate event dictionaries and applies its stat modifiers.

public void AddEvent(AbilityEvent abilityEvent)

Parameters

abilityEvent AbilityEvent

The ability event to add.

AddEvents<T>(List<T>)

Adds a list of ability events to the appropriate event dictionaries and applies their stat modifiers. Delegates to AddEvent(AbilityEvent) for each element, ensuring consistent modifier application and resource cost invalidation.

public void AddEvents<T>(List<T> abilityEvents) where T : AbilityEvent

Parameters

abilityEvents List<T>

The list of events to add.

Type Parameters

T

The type of ability event.

ConsumeResources(ICharacter, AbilityEvent)

Consumes the required resources from the given character to use this ability. Aggregates all IResourceCost conditions from the template and events.

public void ConsumeResources(ICharacter character, AbilityEvent resourceConversionTrigger = null)

Parameters

character ICharacter

The character using the ability.

resourceConversionTrigger AbilityEvent

Optional event that allows resource conversion (e.g., health for mana).

DestroyAbilityObjectsAfterTick(uint, bool)

Destroys all spawned ability objects whose SpawnTick is greater than the specified tick. Used during reconcile rollback to remove client-predicted objects that the server has not confirmed. Routes each object through DestroyAbilityObjectInternal(bool, bool) so that the destroyed-flag, OnTick unsubscription, and OnDestroy events are executed. Ability is nulled before the internal call to prevent RemoveAbilityObject(int, int) from modifying the Objects dictionary while we are iterating it; the outer loop handles dictionary cleanup instead.

public void DestroyAbilityObjectsAfterTick(uint tick, bool includeTick = false)

Parameters

tick uint

The reconcile tick. Objects spawned after this tick are destroyed.

includeTick bool

Also destroy objects spawned exactly ON tick. Off by default, and it must stay that way for the ordinary mismatch path: FishNet replays from tick + 1, so an object spawned at tick is one the replay cannot recreate, and removing a spawn the server actually performed would delete it permanently. Only the caller that has established the server did NOT spawn at this tick may pass true — see AbilityController.ShouldDestroySpawnsAtReconcileTick.

DestroyAllAbilityObjects()

Destroys all spawned ability objects for this ability and clears the Objects dictionary. Routes each object through DestroyAbilityObjectInternal(bool, bool) so that the destroyed-flag, OnTick unsubscription, and OnDestroy events are executed. Ability is nulled before the internal call to prevent RemoveAbilityObject(int, int) from modifying the Objects dictionary while we are iterating it; the dictionary is cleared in bulk after the loop. Call this when the owning character disconnects, dies, or is otherwise cleaned up.

public void DestroyAllAbilityObjects()

DetachAllAbilityObjects()

Detaches all spawned ability objects from this ability without destroying them. The objects continue to exist in the world using their AbilityObjectSnapshot for data-driven behavior. The Ability and Caster references are nulled out, and the Objects dictionary is cleared. Call this when the owning character disconnects or dies to allow in-flight projectiles to persist visually while gracefully degrading ECA events.

public void DetachAllAbilityObjects()

GetResourceCosts()

Aggregates all resource costs from the template's ActivationConditions and each event's Conditions by scanning for IResourceCost implementations.

public Dictionary<CharacterAttributeTemplate, int> GetResourceCosts()

Returns

Dictionary<CharacterAttributeTemplate, int>

A dictionary mapping resource attribute templates to their total required amounts.

HasAbilityEvent(int)

Checks if this ability contains an event with the given event ID.

public bool HasAbilityEvent(int eventID)

Parameters

eventID int

The event ID to check.

Returns

bool

True if the event exists, false otherwise.

HasResource(ICharacter, AbilityEvent)

Checks if the given character has enough resources to use this ability. Aggregates all IResourceCost conditions from the template and events.

public bool HasResource(ICharacter character, AbilityEvent resourceConversionTrigger = null)

Parameters

character ICharacter

The character to check.

resourceConversionTrigger AbilityEvent

Optional event that allows resource conversion (e.g., health for mana).

Returns

bool

True if the character has enough resources, false otherwise.

MarkPersisted(long)

Clears PersistenceDirty if this ability has not changed since the version that was written.

public void MarkPersisted(long persistedVersion)

Parameters

persistedVersion long

The version that was successfully written.

Remarks

The version check is what makes the save safe to run in the background: an ability that changed while the write was in flight has moved past the version written and stays dirty. A write that fails never calls this, so the next pass carries it.

MeetsActivationConditions(ICharacter, ref EventData)

Evaluates the template's activation conditions using a cached EventData. The checkData reference is created or updated if the initiator changes, avoiding a per-call allocation on hot paths (e.g., every tick in Replicate).

public bool MeetsActivationConditions(ICharacter character, ref EventData checkData)

Parameters

character ICharacter

The character to check.

checkData EventData

Reusable event data; created if null, recreated if initiator changed.

Returns

bool

True if all non-resource activation conditions are met, false otherwise.

RemoveAbilityEvent(int)

Removes an ability event by its event ID and updates stat modifiers accordingly.

public bool RemoveAbilityEvent(int eventID)

Parameters

eventID int

The event ID to remove.

Returns

bool

True if the event was removed, false otherwise.

RemoveAbilityObject(int, int)

Removes an ability object from the cache by container and object ID. If the container becomes empty after removal, it is also removed.

public void RemoveAbilityObject(int containerID, int objectID)

Parameters

containerID int

The container ID.

objectID int

The object ID to remove.

Tooltip()

Returns the tooltip string for this ability, using the template and type override if present. Caches the result to avoid repeated string allocations.

public string Tooltip()

Returns

string

Formatted tooltip string for the ability.

TryGetAbilityEvent(int, out AbilityEvent)

Attempts to get an ability event by its event ID.

public bool TryGetAbilityEvent(int eventID, out AbilityEvent abilityEvent)

Parameters

eventID int

The event ID to look up.

abilityEvent AbilityEvent

The found ability event, or null if not found.

Returns

bool

True if found, false otherwise.