> For the complete documentation index, see [llms.txt](https://dante-3.gitbook.io/dante-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dante-3.gitbook.io/dante-docs/modular-experience-system/modular-framework-classes.md).

# Modular Framework Classes

Modular actor base classes integrated with `GameFrameworkComponentManager`.

## Origin

This module is **sourced from Lyra's `ModularGameplayActors` plugin**. Class names have been renamed with the `AMES_` prefix, but the **internal behavior is exactly the same**. If you want to examine the original, refer to Lyra's `ModularGameplayActors` plugin.

{% hint style="info" %}
**Why a separate module?** — So that the MES plugin does not depend on an external plugin like `ModularGameplayActors`. This way MES becomes a fully self-contained plugin.
{% endhint %}

## Common Pattern

All framework classes follow the same pattern:

```cpp
void AMES_XXX::PreInitializeComponents()
{
    Super::PreInitializeComponents();
    UGameFrameworkComponentManager::AddGameFrameworkComponentReceiver(this);
}

void AMES_XXX::BeginPlay()
{
    Super::BeginPlay();
    UGameFrameworkComponentManager::SendGameFrameworkComponentExtensionEvent(
        this, UGameFrameworkComponentManager::NAME_GameActorReady);
}

void AMES_XXX::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    UGameFrameworkComponentManager::RemoveGameFrameworkComponentReceiver(this);
    Super::EndPlay(EndPlayReason);
}
```

This allows actions like `GameFeatureAction_AddComponents` to perform runtime component injection on these actors.

## Class List

### AMES\_GameModeBase

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_GameModeBase : public AGameModeBase
```

Modular GameModeBase. In the constructor, it sets default classes to the other MES\_ classes:

* `GameStateClass` → `AMES_GameStateBase`
* `PlayerControllerClass` → `AMES_PlayerController`
* `PlayerStateClass` → `AMES_PlayerState`
* `DefaultPawnClass` → `AMES_Character`

> **Note:** This class does **not register** as a `GameFrameworkComponentReceiver` — GameMode does not need component injection. It only sets the default classes.

### AMES\_GameMode

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_GameMode : public AGameMode
```

Full-featured modular GameMode derived from `AGameMode`. Includes match lifecycle support. Default classes are set in the constructor:

* `GameStateClass` → `AMES_GameState`
* `PlayerControllerClass` → `AMES_PlayerController`
* `PlayerStateClass` → `AMES_PlayerState`
* `DefaultPawnClass` → `AMES_Character`

### AMES\_GameStateBase

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_GameStateBase : public AGameStateBase
```

| Override                    | Description                                                |
| --------------------------- | ---------------------------------------------------------- |
| `PreInitializeComponents()` | `AddGameFrameworkComponentReceiver(this)`                  |
| `BeginPlay()`               | `SendGameFrameworkComponentExtensionEvent(GameActorReady)` |
| `EndPlay()`                 | `RemoveGameFrameworkComponentReceiver(this)`               |

### AMES\_GameState

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_GameState : public AGameState
```

Same pattern as `AMES_GameStateBase` + additional override:

| Override                  | Description                                |
| ------------------------- | ------------------------------------------ |
| `HandleMatchHasStarted()` | `Super` call + extension event propagation |

### AMES\_Character

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_Character : public ACharacter
```

Modular Character. Standard `PreInitializeComponents` → `BeginPlay` → `EndPlay` lifecycle.

### AMES\_Pawn

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_Pawn : public APawn
```

Modular Pawn. For lightweight pawn needs without a Character (no mesh/movement component).

### AMES\_PlayerController

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_PlayerController : public APlayerController
```

| Override                    | Description                                           |
| --------------------------- | ----------------------------------------------------- |
| `PreInitializeComponents()` | Receiver registration                                 |
| `EndPlay()`                 | Receiver removal                                      |
| `ReceivedPlayer()`          | Component extension event — here instead of BeginPlay |
| `PlayerTick()`              | `GameFrameworkComponentManager` tick propagation      |

> **Note:** PlayerController uses `ReceivedPlayer()` instead of `BeginPlay` because the player may not be fully ready when BeginPlay is called.

### AMES\_PlayerState

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_PlayerState : public APlayerState
```

| Override                    | Description                                      |
| --------------------------- | ------------------------------------------------ |
| `PreInitializeComponents()` | Receiver registration                            |
| `BeginPlay()`               | GameActorReady event                             |
| `EndPlay()`                 | Receiver removal                                 |
| `Reset()`                   | Extension event propagation                      |
| `CopyProperties()`          | Property copy propagation during seamless travel |

### AMES\_AIController

```cpp
UCLASS(MinimalAPI, Blueprintable)
class AMES_AIController : public AAIController
```

Modular controller for AI-controlled pawns. Standard lifecycle pattern.

> **Dependency:** This class depends on `AIModule` (in ModularExperienceFramework.Build.cs).

## Module Dependencies

```
ModularExperienceFramework
  ├─ Public:  Core
  └─ Private: CoreUObject, Engine, ModularGameplay, AIModule
```

## Usage Guide

### Method 1: Derive Directly (Recommended)

Select `AMES_GameMode` or `AMES_GameModeBase` as the parent class in your GameMode Blueprint. The other default classes are set automatically.

### Method 2: Via Auto Setup

When `bAutoSetup = true`, you can even use a standard `AGameStateBase` — the subsystem automatically registers actors as receivers.

### Method 3: Your Own Base Classes

If you have your own class hierarchy, you don't have to use the framework classes. All you need to do is implement the pattern above in `PreInitializeComponents` / `BeginPlay` / `EndPlay` — or enable Auto Setup.

## Compatibility with ModularGameplayActors

The MES subsystem recognizes **both its own `AMES_` classes and the classes from the `ModularGameplayActors` plugin**. If `ModularGameplayActors` is also loaded in your project, actors derived from its classes are correctly detected and double registration is avoided.

This check is two-layered:

1. **Compile-time:** Direct check via `IsA<AMES_GameStateBase>()` etc.
2. **Runtime:** Dynamic check via `FindObject<UClass>(nullptr, TEXT("/Script/ModularGameplayActors.ModularGameStateBase"))`
