Table of Contents

Class BaseBuffTemplate

Namespace
FishMMO.Shared
Assembly
FishMMO.Shared.dll

Abstract base class for all buff templates, defining shared properties, tooltip logic, and effect hooks. Stack and tick hooks are virtual with sensible defaults: stacking delegates to apply/remove, and ticking is a no-op. Derived classes only override what they need (OCP).

public abstract class BaseBuffTemplate : CachedScriptableObject<BaseBuffTemplate>, ICachedObject, ITooltip
Inheritance
Object
ScriptableObject
BaseBuffTemplate
Implements
Derived
Inherited Members
ScriptableObject.SetDirty()
ScriptableObject.CreateInstance<T>()
Object.GetEntityId()
Object.GetInstanceID()
Object.GetHashCode()
Object.InstantiateAsync<T>(T)
Object.InstantiateAsync<T>(T, Transform)
Object.InstantiateAsync<T>(T, Vector3, Quaternion)
Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion)
Object.Instantiate(Object, Vector3, Quaternion, Transform)
Object.Instantiate(Object)
Object.Instantiate(Object, Scene)
Object.Instantiate<T>(T, InstantiateParameters)
Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)
Object.Instantiate(Object, Transform)
Object.Instantiate<T>(T)
Object.Instantiate<T>(T, Vector3, Quaternion)
Object.Instantiate<T>(T, Vector3, Quaternion, Transform)
Object.Instantiate<T>(T, Transform)
Object.Destroy(Object)
Object.DestroyImmediate(Object)
Object.DontDestroyOnLoad(Object)
Object.DestroyObject(Object)
Object.FindObjectsOfType<T>()
Object.FindObjectsByType<T>(FindObjectsSortMode)
Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)
Object.FindObjectOfType<T>()
Object.FindFirstObjectByType<T>()
Object.FindAnyObjectByType<T>()
Object.FindFirstObjectByType<T>(FindObjectsInactive)
Object.FindAnyObjectByType<T>(FindObjectsInactive)
Object.FindObjectsByType<T>()
Object.FindObjectsByType<T>(FindObjectsInactive)
Object.ToString()
Object.name
Object.hideFlags

Fields

Description

The description of the buff, shown in tooltips.

public string Description

Field Value

string

Duration

The duration of the buff in seconds. If 0, the buff may be permanent or event-driven.

public float Duration

Field Value

float

FXPrefabReference

Addressable reference to the visual effect prefab to instantiate when the buff is applied.

public AssetReferenceGameObject FXPrefabReference

Field Value

AssetReferenceGameObject

IsDebuff

True if this buff is a debuff (negative effect).

public bool IsDebuff

Field Value

bool

IsPermanent

True if the buff is permanent and does not expire.

public bool IsPermanent

Field Value

bool

MaxStacks

The maximum number of stacks this buff can have.

public uint MaxStacks

Field Value

uint

OnTickEvents

[Header("Event-Condition-Action (ECA) Triggers")]
[Tooltip("Triggers fired each tick. A DoT is an ApplyDamageAction here; a HoT is an ApplyHealAction.")]
public List<BuffTickEvent> OnTickEvents

Field Value

List<BuffTickEvent>

TickRate

The interval in seconds between OnTick calls while the buff is active.

public float TickRate

Field Value

float

Properties

Icon

The icon for this buff template (loaded at runtime on client).

public Sprite Icon { get; }

Property Value

Sprite

Name

The name of this buff template (from the ScriptableObject's name).

public string Name { get; }

Property Value

string

Methods

ApplyResourceTick(Buff, ICharacter, List<BuffAttributeTemplate>, DamageAttributeTemplate)

Applies one round of periodic resource changes, routing health through the damage pipeline so a tick behaves like any other hit.

protected static void ApplyResourceTick(Buff buff, ICharacter target, List<BuffAttributeTemplate> tickAttributes, DamageAttributeTemplate damageAttribute)

Parameters

buff Buff

The buff instance, supplying stacks, attribution and replay state.

target ICharacter

The character the tick lands on.

tickAttributes List<BuffAttributeTemplate>

Per-tick resource modifiers. Positive heals, negative damages.

damageAttribute DamageAttributeTemplate

Damage type used to resolve resistance when a tick reduces health. Null means the tick bypasses resistance entirely.

Remarks

Why not write the resource directly. Both tick templates used to call CharacterResourceAttribute.AddToCurrentValue, which clamps the value and raises an attribute-changed notification and nothing else. That skipped every consequence of being hurt: resistances were not applied, Immortal was ignored, neither party entered combat, no OnDamaged event was raised — so a damage-over-time effect generated no threat at all — and, worst of all, nothing could die of it. Kill(ICharacter) is only ever reached from inside Damage, so a DoT drained its victim to zero health and stopped there; the early-out at the top of Damage then rejected every subsequent hit as "already dead", leaving a character permanently alive at nothing.

Health only. Damage and Heal operate on the health resource. A tick against mana, stamina or any other resource has no damage semantics to borrow and keeps writing the resource directly.

Both sides, side effects on one. The resource mutation runs on the owning client as well as the server, which is what keeps predicted health in step with the server's. The triggers hanging off Damage/Heal are passed as suppressed on every client — replayed or not — and only ever fire on the server. Before this, the flag tracked replay alone, so the owner's first pass over a tick fired achievements and combat triggers a second time alongside the server. See ShouldSuppressTickSideEffects(Buff).

BuildTooltip(TooltipBuilder)

Populates the tooltip builder with this buff's tooltip lines. Override in derived classes to add additional lines.

public virtual void BuildTooltip(TooltipBuilder builder)

Parameters

builder TooltipBuilder

The tooltip builder to populate.

InvokeTickEvents(Buff, ICharacter)

Fires this buff's ECA tick triggers against the character carrying it.

protected void InvokeTickEvents(Buff buff, ICharacter target)

Parameters

buff Buff

The buff instance.

target ICharacter

The character carrying the buff.

Remarks

Initiator is the caster, target is the carrier. That split is what makes an ApplyDamageAction on a tick event behave like a hit rather than like self-harm: the damage lands on the carrier and is credited to whoever applied the buff, which is what generates threat and grants the kill.

When the caster is gone — disconnected, despawned — the carrier stands in as initiator so the trigger still has a character to resolve values and conditions against. The effect continues to land, because a lingering poison is part of the simulation whether or not whoever cast it is still in the scene; it simply credits nobody, and ApplyDamageAction is content with that.

Server only. With state forwarding off, the owner still ticks its own buffs for prediction, but an ECA trigger is a side effect — damage credit, threat, chained effects, achievements — and must run exactly once. The owner's health is corrected by the attribute reconcile; nothing here needs to run on a client.

OnApply(Buff, ICharacter)

Called when the buff is applied to a character. Must be implemented by derived classes. When reached through OnApplyStack(Buff, ICharacter), Stacks still contains the pre-increment stack count; stack-aware templates should account for that ordering or override OnApplyStack(Buff, ICharacter) directly.

public abstract void OnApply(Buff buff, ICharacter target)

Parameters

buff Buff

The buff instance being applied.

target ICharacter

The character receiving the buff.

OnApplyFX(Buff, ICharacter)

Instantiates the FXPrefab on the target when the buff becomes visible on it (client-side only).

public virtual GameObject OnApplyFX(Buff buff, ICharacter target)

Parameters

buff Buff

The simulated buff instance, or null for an observed buff.

target ICharacter

The character receiving the buff.

Returns

GameObject

The instantiated FX, or null when there is nothing to show.

Remarks

Returns the instance so the caller can own its lifetime. BuffController tracks one instance per template per character and hands it back to OnRemoveFX(GameObject, ICharacter) when the buff leaves; before that the instance was fire-and-forget and outlived the buff it was meant to show — on the owner and on every observer.

buff is null when the FX is driven by the observer-facing list rather than a simulated buff: observers no longer hold Buff instances for other characters, only ObservedBuffEntry. Overrides must tolerate that.

Parented under MeshRoot so it follows the model. That root is cleared when the race model (re)loads, which destroys the instance; the controller re-creates it from OnModelReady().

OnApplyStack(Buff, ICharacter)

Called when a stack of the buff is applied. Defaults to delegating to OnApply. Stacks is incremented after this hook returns, so this hook observes the previous stack count. Override in derived classes for custom stacking behavior.

public virtual void OnApplyStack(Buff buff, ICharacter target)

Parameters

buff Buff

The buff instance being stacked.

target ICharacter

The character receiving the stack.

OnLoad(string, string, int)

Called when the buff template is loaded into cache. Loads the icon and FX prefab on the client.

public override void OnLoad(string typeName, string resourceName, int resourceID)

Parameters

typeName string

The type name of the resource.

resourceName string

The resource name.

resourceID int

The resource ID.

OnRemove(Buff, ICharacter)

Called when the buff is removed from a character. Must be implemented by derived classes.

public abstract void OnRemove(Buff buff, ICharacter target)

Parameters

buff Buff

The buff instance being removed.

target ICharacter

The character losing the buff.

OnRemoveFX(GameObject, ICharacter)

Tears down an FX instance previously returned by OnApplyFX(Buff, ICharacter) (client-side only).

public virtual void OnRemoveFX(GameObject fxInstance, ICharacter target)

Parameters

fxInstance GameObject

The instance to remove. May already be destroyed.

target ICharacter

The character the buff left. May be null during teardown.

OnRemoveStack(Buff, ICharacter)

Called when a stack of the buff is removed. Defaults to delegating to OnRemove. Override in derived classes for custom unstacking behavior.

public virtual void OnRemoveStack(Buff buff, ICharacter target)

Parameters

buff Buff

The buff instance being unstacked.

target ICharacter

The character losing the stack.

OnTick(Buff, ICharacter)

Called on each tick while the buff is active. Fires OnTickEvents.

public virtual void OnTick(Buff buff, ICharacter target)

Parameters

buff Buff

The buff instance.

target ICharacter

The character affected.

Remarks

Derived classes that add their own periodic behaviour must call base.OnTick(buff, target), or the buff's authored tick events are silently dropped for that template type.

OnUnload(string, string, int)

Called when the buff template is unloaded from cache. Releases the icon and FX prefab on the client.

public override void OnUnload(string typeName, string resourceName, int resourceID)

Parameters

typeName string

The type name of the resource.

resourceName string

The resource name.

resourceID int

The resource ID.

SecondaryTooltip(TooltipBuilder)

Appends additional information to the tooltip (e.g., secondary effects). Override in derived classes.

public virtual void SecondaryTooltip(TooltipBuilder builder)

Parameters

builder TooltipBuilder

The tooltip builder to populate.

Tooltip()

Returns the tooltip string for this buff, including name, description, and secondary details.

public virtual string Tooltip()

Returns

string