Class Ability
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
templateAbilityTemplateThe ability template to use.
abilityEventsList<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
abilityIDlongThe unique ability instance ID.
templateAbilityTemplateThe ability template to use.
abilityEventsList<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
abilityIDlongThe unique ability instance ID.
templateIDintThe template ID to look up.
abilityEventsList<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
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
Cooldown
Total cooldown for this ability, including all modifiers.
public float Cooldown
Field Value
ID
Unique identifier for this ability instance.
public long ID
Field Value
LifeTime
Total lifetime of the ability effect, including all modifiers.
public float LifeTime
Field Value
OnDestroyEvents
All OnDestroy events, indexed by event ID.
public SortedDictionary<int, AbilityOnDestroyEvent> OnDestroyEvents
Field Value
OnHitEvents
All OnHit events, indexed by event ID.
public SortedDictionary<int, AbilityOnHitEvent> OnHitEvents
Field Value
OnPreSpawnEvents
All OnPreSpawn events, indexed by event ID.
public SortedDictionary<int, AbilityOnPreSpawnEvent> OnPreSpawnEvents
Field Value
OnSpawnEvents
All OnSpawn events, indexed by event ID.
public SortedDictionary<int, AbilityOnSpawnEvent> OnSpawnEvents
Field Value
OnTickEvents
All OnTick events, indexed by event ID.
public SortedDictionary<int, AbilityOnTickEvent> OnTickEvents
Field Value
Speed
Total speed of the ability effect, including all modifiers.
public float Speed
Field Value
Version
Version number for this ability instance, used for client synchronization and updates.
public long Version
Field Value
Properties
CachedTooltip
Cached tooltip string for this ability, for UI display.
public string CachedTooltip { get; }
Property Value
EffectiveType
Returns the effective ability type, accounting for any TypeOverride.
public AbilityType EffectiveType { get; }
Property Value
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
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
PersistenceDirty
Whether this ability has changed since the database last confirmed it.
public bool PersistenceDirty { get; }
Property Value
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
public float Range { get; }
Property Value
Template
The template from which this ability was constructed.
public AbilityTemplate Template { get; }
Property Value
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
TypeOverride
Optional override for the ability type, set by certain events.
public AbilityTypeOverrideEventType TypeOverride { get; }
Property Value
Methods
AddEvent(AbilityEvent)
Adds a single ability event to the appropriate event dictionaries and applies its stat modifiers.
public void AddEvent(AbilityEvent abilityEvent)
Parameters
abilityEventAbilityEventThe 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
abilityEventsList<T>The list of events to add.
Type Parameters
TThe 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
characterICharacterThe character using the ability.
resourceConversionTriggerAbilityEventOptional 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
tickuintThe reconcile tick. Objects spawned after this tick are destroyed.
includeTickboolAlso destroy objects spawned exactly ON
tick. Off by default, and it must stay that way for the ordinary mismatch path: FishNet replays fromtick + 1, so an object spawned attickis 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 — seeAbilityController.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
eventIDintThe 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
characterICharacterThe character to check.
resourceConversionTriggerAbilityEventOptional 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
persistedVersionlongThe 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
characterICharacterThe character to check.
checkDataEventDataReusable 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
eventIDintThe 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
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
eventIDintThe event ID to look up.
abilityEventAbilityEventThe found ability event, or null if not found.
Returns
- bool
True if found, false otherwise.