---
description: Abstract Scriptable Object
---

# Module

<figure><picture><source srcset="https://content.gitbook.com/content/sszhq0oU5VbBUcBr6f13/blobs/c9iBbYMV2YCfIjt9kXUw/d_Module%20Icon.png" media="(prefers-color-scheme: dark)"><img src="https://content.gitbook.com/content/sszhq0oU5VbBUcBr6f13/blobs/ibAssQfS5oIUHGIiV4Wy/Module%20Icon.png" alt="" width="188"></picture><figcaption></figcaption></figure>

### Description

[Modules](module) are a way to add additional functionality to each [StatusEffectData](statuseffectdata). Create one by simply inheriting from the [Module](module) 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](module) and [ModuleInstances](moduleinstance).
{% 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](moduleinstance) to see how you can setup unique module data per [StatusEffectData](statuseffectdata)!
{% 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="../classes/statuseffect">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="../classes/statuseffect">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 %}
