# Principle of Operation

## Overview

Before explaining the detailed features of ActionSequence, this section first covers how ActionSequence works internally. This helps you understand how it operates at runtime and identify technical considerations when using its features.

## Runtime Behavior

ActionSequence is an object **defined based on static data** and cannot be directly created at runtime using Instance.new or Clone.

When execution is requested through the Play method, the original instance is **duplicated under Humanoid.ActionRunner**, and the action is executed based on this duplicated instance.

<div align="left"><figure><img src="https://2064130887-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhrvYlLq1mQAq0V0vwPsb%2Fuploads%2Fakosav0aGqKp4Q6AMJpP%2FActionSequencer-Runtime-Clone.png?alt=media&#x26;token=29e534fc-5262-4fd9-8f7f-470441ab8c20" alt="" width="343"><figcaption></figcaption></figure></div>

Due to this structure, when c**onnecting events within ActionSequence scripts**, you must reference the runtime duplicated instance rather than the original instance. Therefore, instead of using absolute paths, you should **reference based on script.Parent**.

```lua
local ActionSequence = script.Parent

ActionSequence:Hit("Hit"):Connect(function(self, other)
    local caster = self.Humanoid
    local target = other.Humanoid
    -- ...
end)
```

## Execution Flow

```mermaid
flowchart TD
    A["Play method is called<br>(Client or Server)"] --> B["Processed on the server"]

    B --> C["Sequence execution starts (Server)"]

    C --> D1["Client 1"]
    C --> D2["Client 2"]
    C --> D3["Client 3"]

    D1 --> E1["Direction is executed on each client (Client)"]
    D2 --> E2["Direction is executed on each client (Client)"]
    D3 --> E3["Direction is executed on each client (Client)"]
```

When an action execution request occurs, the sequence execution always s**tarts on the server**, regardless of whether it was called from the Client or Server. **Script events within the ActionSequence are then connected**, and the sequence along with its child objects is **replicated to all clients**.

Once replication is complete, **the timeline is played on each client**, and direction elements such as animations, effects, and sounds are executed.

In other words, ActionSequence does not operate by being dynamically created or directly cloned via scripts at runtime. Instead, **it runs by duplicating predefined data at execution time** to perform the direction.

The server synchronizes the overall progression based on the sequence execution timing, and any **time differences between clients are automatically corrected**. Additionally, to maintain gameplay consistency, **core logic such as attack collision detection is handled on the serve**r.

## Creation and Destruction Flow

```mermaid
flowchart TD
    A["Action execution request"]
    B["Script events are connected"]
    C["ActionSequence is replicated<br>(Server → Client)"]
    D["Timeline is executed<br>(animation, sound, etc.)"]
    E["Direction ends"]
    F["Replicated ActionSequence instance is removed"]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
```

ActionSequence runs until the defined playback duration is completed. **Once playback ends, the duplicated ActionSequence instance used for execution is automatically removed**, and any events connected to the ActionSequence are also cleaned up.

### Notes on Playback Duration

To clearly define the creation and destruction timing of duplicated instances generated during ActionSequence execution, it is recommended to also clean up the playback duration when the action ends. **If the playback duration is unnecessarily long, the removal of instances may be delayed.**

* Bad Example

  <figure><img src="https://2064130887-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhrvYlLq1mQAq0V0vwPsb%2Fuploads%2FlwYG3SFffhOtZS9r0zwI%2FActionSequencer-Timeline-GoodCase.png?alt=media&#x26;token=c03a1d52-89bb-4830-98f4-92837fff4c4f" alt=""><figcaption></figcaption></figure>
* Good Example

  <figure><img src="https://2064130887-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhrvYlLq1mQAq0V0vwPsb%2Fuploads%2F1PU8QH5DVALMarEiRfwt%2FActionSequencer-Timeline-BadCase.png?alt=media&#x26;token=99f1c6c7-a86e-43d6-94c8-69f40c139343" alt=""><figcaption></figcaption></figure>

The playback duration can be adjusted by entering values in the **start/end time fields** at the top of the timeline, or by moving the scrubber to the desired position and using the **set end position button**.

<figure><img src="https://2064130887-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhrvYlLq1mQAq0V0vwPsb%2Fuploads%2F9dwiyUCqeGIY1NNaQ0Ge%2FActionSequencer-Timeline-SetPlayRangeButton.png?alt=media&#x26;token=f4a91996-d474-4b5c-9b07-55f5f1e64ba4" alt=""><figcaption></figcaption></figure>
