# Morpheus Array

{% hint style="warning" %}
This feature is currently in Beta.
{% endhint %}

### Introduction <a href="#howto-morpheusarray-introduction" id="howto-morpheusarray-introduction"></a>

This document covers when and how to use a `UMorpheusArray` in Blueprints and the current limitations it has.

### Morpheus Array <a href="#howto-morpheusarray-morpheusarray" id="howto-morpheusarray-morpheusarray"></a>

A `MorpheusArray` is a generic replicated container that can be used to efficiently **replicate** array updates.

`MorpheusArray` is only replicated in **Foreground** and supports **any type that a replicated TArray supports**.

### When to use a Morpheus Array vs normal Arrays? <a href="#howto-morpheusarray-morpheusarrayvstarray" id="howto-morpheusarray-morpheusarrayvstarray"></a>

A `Morpheus Array` is preferred to be used when:

* You expect your array to contain 1000s of elements with frequent changes.
* You need to know when a specific index has been updated in the array.

An example use case can be when you want to keep track of some data for each actor in the game and that data can change during runtime. (e.g Player scores)

### Garbage Collection

Similar to Unreal's `TArray` , any `UObject` reference stored inside the `MorpheusArray` will **NOT** be garbage collected.

These `UObject` references will be collected from each element in the `MorpheusArray`, however deep in the hierarchy (e.g. a struct containing a struct containing a UObject).

This is to guarantee `UObject` liveness as long as it remains inside the `MorpheusArray`

### Using a Morpheus Array in Blueprints <a href="#howto-morpheusarray-definingumorpheusarray" id="howto-morpheusarray-definingumorpheusarray"></a>

In order to start using a `Morpheus Array` in Blueprints you do the following:

* Open your Blueprint that derives from either a `MorpheusActor` or a `MorpheusActorComponent`
* Add a variable to your Blueprint and give it the type `Morpheus Array`

<div align="center" data-full-width="false"><figure><img src="/files/XjWzxwMtKcbGLcMbTJ6w" alt="" width="375"><figcaption></figcaption></figure></div>

* In the variable Details Panel on the right, select the `Morpheus Array Inner Type` to be the desired type that the `Morpheus Array` will hold.

<div data-full-width="false"><figure><img src="/files/ChUekf2kHjuGh1F5fipn" alt="" width="375"><figcaption></figcaption></figure></div>

* Don't forget to set the `Morpheus Array` variable to be `Replicated`
* Now drag and drop the variable into the BP graph to start using your `Morpheus Array` using the `Morpheus Array` specific nodes shown under the `Morpheus Array` category.

<figure><img src="/files/MoOWk4ZWYDPB5sRQPyP8" alt="" width="375"><figcaption></figcaption></figure>

### Example Blueprint Usages <a href="#howto-morpheusarray-onrepumorpheusarray" id="howto-morpheusarray-onrepumorpheusarray"></a>

<figure><img src="/files/6Rbm3htxZd1zfm2L4Rzz" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/J4uu1pjlXnf3okl3394K" alt=""><figcaption></figcaption></figure>

Since `UMorpheusArray` is a replicated type it also supports rep notifies and they do fire even if a single element was updated.

But additionally `UMorpheusArray` has a couple of helper functions that you can use in the OnRep to know the exact replication changes that we received.

* `UMorpheusArray::OnRepUpdatedIndices()` which returns an array of the indices that have been updated by the last replication event.
* `UMorpheusArray::OnRepDeletedIndices()` which returns an array of the indices that have been deleted by the last replication event.

With these functions, users can be aware of the changes that happened to the array, rather than having to figure out any changes manually

Example usage:

<figure><img src="/files/Z1f02HMxBrj0YG6h5pAS" alt=""><figcaption></figcaption></figure>

### On About to Apply Update Delegate <a href="#howto-morpheusarray-limitations" id="howto-morpheusarray-limitations"></a>

Morpheus Arrays has a delegate `OnAboutToApplyUpdate` that is fired before the `OnRep` . This delegate can be used to react to incoming element updates/deletions before they are applied to the `Morpheus Array` itself and losing the old values.\
\
See example below:

{% @blueprintue-embed/embed url="<https://nextjs-boilerplate-jl63.vercel.app/ca081f39-81e6-4d44-b022-22f8956dfb1b>" %}

Notice that the delegate gets called with `Keys` instead of `Indices` so you will need to use `GetIndexFromKey` to retrieve the about to be updated/deleted index in the Morpheus Array.

There is also another helper function `GetKeyOfIndex` that retrieves the Key of a given index.

#### Keys vs Indices

A `Key` in a Morpheus Array is a unique identifier for a Morpheus Array element.

Since elements in the Morpheus Array can get added or removed the `Index` becomes insufficient to represent the element as it could now be pointing to a different element.

Every `Key` is mapped to an `Index` in the array and whenever an `Index` is removed, its `Key` will also get removed but the remaining keys will still point to the same elements despite having their indices changed.

An update to an element doesn't affect the `Key` nor the `Index` of that element.

### Limitations <a href="#howto-morpheusarray-limitations" id="howto-morpheusarray-limitations"></a>

1. `AMorpheusActors` that own a `UMorpheusArray` and aren’t in **Foreground** will still need to checkout the whole array once they enter **Foreground**. In which case, a `UMorpheusArray` will **not** be replicated efficiently.
2. Using the `Get` node and the `ToArray` nodes in Blueprints will currently return **copies** of the values inside the `UMorpheusArray` so bear in that in mind if performance is a concern.
3. Debugging a `UMorpheusArray` may not be trivial as the data is stored internally as a raw byte buffer so you might need to write extra code to view the contents of the `UMorpheusArray` while debugging it.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.msquared.io/creation/unreal-development/getting-started/networking/how-to-morpheus-array.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
