> For the complete documentation index, see [llms.txt](https://maraudical.gitbook.io/status-effects-framework/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://maraudical.gitbook.io/status-effects-framework/type-specifics/scriptable-objects/module.md).

# Module

<figure><picture><source srcset="/files/o76YdBr2kB5SInjnaRqa" media="(prefers-color-scheme: dark)"><img src="/files/phSBr8wM2KC3lmChQz70" alt="" width="188"></picture><figcaption></figcaption></figure>

### Description

[Modules](/status-effects-framework/type-specifics/scriptable-objects/module.md) are a way to add additional functionality to each [StatusEffectData](/status-effects-framework/type-specifics/scriptable-objects/statuseffectdata.md). Create one by simply inheriting from the [Module](/status-effects-framework/type-specifics/scriptable-objects/module.md) class and implementing the necessary methods or using <kbd>Create > Status Effect Framework > Module Script</kbd>.

{% hint style="danger" %}
You **NEED** to use the **StatusEffects.Modules** namespace like in the example below for both [Modules](/status-effects-framework/type-specifics/scriptable-objects/module.md) and [ModuleInstances](/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md).
{% endhint %}

Truthfully anything can be done with them as they are just an inheritable abstract class that calls a method. It is **highly recommended** to take a look at the [samples](https://github.com/maraudical/StatusEffectsFramework-Unity/tree/main/Samples~) for an idea of how to use them.

{% hint style="info" %}
Make sure to checkout [ModuleInstance](/status-effects-framework/type-specifics/scriptable-objects/moduleinstance.md) to see how you can setup unique module data per [StatusEffectData](/status-effects-framework/type-specifics/scriptable-objects/statuseffectdata.md)!
{% endhint %}

### UniTask Support

Note that if you have [UniTask](https://docs.unity3d.com/ScriptReference/Coroutine.html) in your project then the Module will use [UniTasks](https://docs.unity3d.com/ScriptReference/Coroutine.html) over [Awaitable](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.html). This is also included in the samples.

### Legacy Support

Note that if you are using an ealier version than Unity 2023.1 then the Module will use [Coroutines](https://docs.unity3d.com/ScriptReference/Coroutine.html) over [Awaitable](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.html) (as it doesn't exist in previous versions). Like [UniTask](https://docs.unity3d.com/ScriptReference/Coroutine.html) it is also included in the samples and the DisableModule abstract method is can be used used.

### Abstract Methods

<table data-full-width="true"><thead><tr><th width="250">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>EnableModule</code></td><td>An <a href="https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Awaitable.html">Awaitable</a> that is started when the <a href="/pages/OpUFQnv9JKaTU0cxnlHw">StatusEffect</a> begins.</td></tr><tr><td><code>DisableModule</code></td><td>(pre 2023.1 only) A method that is invoked when the <a href="/pages/OpUFQnv9JKaTU0cxnlHw">StatusEffect</a> is stopped.</td></tr></tbody></table>

### Example

{% tabs fullWidth="true" %}
{% tab title="Default" %}
{% code overflow="wrap" %}

```csharp
using System.Threading;
using UnityEngine;
using StatusEffects.Example;

// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    // Setup scriptable object in create menu.
    [CreateAssetMenu(fileName = "Damage Over Time Module", menuName = "Status Effect Framework/Modules/Damage Over Time", order = 1)]
    // This attribute will attach the module instance so 
    // that the interval time can be unique to each effect.
    [AttachModuleInstance(typeof(DamageOverTimeInstance))]
    public class DamageOverTimeModule : Module
    {
        public override async Awaitable EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance, CancellationToken token)
        {
            // Note that for this module it uses a ModuleInstance 
            // to store a unique interval rate.
            DamageOverTimeInstance damageOverTimeInstance = moduleInstance as DamageOverTimeInstance;
            // IExamplePlayer is apart of the samples
            if (manager.TryGetComponent(out IExamplePlayer player))
                // Infinite loop will be cancelled when effect is stopped.
                while (!token.IsCancellationRequested)
                {
                    // Reduce health based on the Statu Effect base value
                    player.Health -= statusEffect.Data.BaseValue * statusEffect.Stacks;
                    // Wait for the interval before applying the damage again
                    await Awaitable.WaitForSecondsAsync(damageOverTimeInstance.IntervalSeconds);
                }
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="UniTask" %}
{% code overflow="wrap" %}

```csharp
using Cysharp.Threading.Tasks;
using System.Threading;
using UnityEngine;
using StatusEffects.Example;

// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    // Setup scriptable object in create menu.
    [CreateAssetMenu(fileName = "Damage Over Time Module", menuName = "Status Effect Framework/Modules/Damage Over Time", order = 1)]
    // This attribute will attach the module instance so 
    // that the interval time can be unique to each effect.
    [AttachModuleInstance(typeof(DamageOverTimeInstance))]
    public class DamageOverTimeModule : Module
    {
        public override async UniTaskVoid EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance, CancellationToken token)
        {
            // Note that for this module it uses a ModuleInstance 
            // to store a unique interval rate.
            DamageOverTimeInstance damageOverTimeInstance = moduleInstance as DamageOverTimeInstance;
            // IExamplePlayer is apart of the samples
            if (manager.TryGetComponent(out IExamplePlayer player))
                // Infinite loop will be cancelled when effect is stopped.
                while (!token.IsCancellationRequested)
                {
                    // Reduce health based on the Statu Effect base value
                    player.Health -= statusEffect.Data.BaseValue * statusEffect.Stacks;
                    // Wait for the interval before applying the damage again
                    await UniTask.WaitForSeconds(damageOverTimeInstance.IntervalSeconds);
                }
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Legacy" %}
{% code overflow="wrap" %}

```csharp
using System.Collections;
using UnityEngine;
using StatusEffects.Example;

// Use StatusEffects.Modules namespace for organization.
namespace StatusEffects.Modules
{
    // Setup scriptable object in create menu.
    [CreateAssetMenu(fileName = "Damage Over Time Module", menuName = "Status Effect Framework/Modules/Damage Over Time", order = 1)]
    // This attribute will attach the module instance so 
    // that the interval time can be unique to each effect.
    [AttachModuleInstance(typeof(DamageOverTimeInstance))]
    public class DamageOverTimeModule : Module
    {
        public override IEnumerator EnableModule(StatusManager manager, StatusEffect statusEffect, ModuleInstance moduleInstance)
        {
            // Note that for this module it uses a ModuleInstance 
            // to store a unique interval rate.
            DamageOverTimeInstance damageOverTimeInstance = moduleInstance as DamageOverTimeInstance;
        
            if (manager.TryGetComponent(out IExamplePlayer player))
                // Infinite loop will be cancelled when effect is stopped.
                for (; ; )
                {
                    // Reduce health based on the Statu Effect base value
                    player.Health -= statusEffect.Data.BaseValue * statusEffect.Stacks;
                    // Wait for the interval before applying the damage again
                    yield return new WaitForSeconds(damageOverTimeInstance.IntervalSeconds);
                }
        }
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}
