# How to Create Custom Enemy Battle Configurations in the Undertale Changer Template

> Learn to create custom enemy battle configurations in Undertale Changer Template by implementing IMultiEnemiesConfig. Define enemy groups and turn logic for unique encounters.

- Repository: [Archived AIk/undertale-changer-template](https://github.com/arch-aik/undertale-changer-template)
- Tags: how-to-guide
- Published: 2026-02-25

---

**You create custom enemy battle configurations by implementing the `IMultiEnemiesConfig` interface to define enemy groups and turn logic, which `TurnController` automatically discovers at runtime via reflection.**

The Undertale Changer Template provides a plug-in architecture for defining multi-enemy encounters without modifying core battle logic. By leveraging the `IMultiEnemiesConfig` interface and the reflection-based discovery system in `TurnController`, you can add new enemy combinations by simply creating a new class. This guide explains how to implement custom enemy battle configurations using the actual source code from the arch-aik/undertale-changer-template repository.

## Understanding the Multi-Enemy Architecture

### The IMultiEnemiesConfig Interface

The contract for enemy groups is defined in [`Assets/Scripts/UCT/Battle/MultiEnemiesConfigs/IMultiEnemiesConfig.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Battle/MultiEnemiesConfigs/IMultiEnemiesConfig.cs). This interface requires three key members: **`EnemyNames`** (a string array mapping to prefab names), **`validIndicesList`** (an int array defining valid turn indices), and the **`_EnemyTurns`** coroutine that orchestrates enemy actions during the battle phase.

### TurnController Discovery Mechanism

[`TurnController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/TurnController.cs) located at [`Assets/Scripts/UCT/Battle/TurnController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Battle/TurnController.cs) handles battle initialization. It calls `GetAllImplementationsOf<IMultiEnemiesConfig>()` to automatically find all concrete implementations at runtime. This reflection-based approach means new configurations are registered immediately without manual registry updates or scene modifications.

## Creating a Custom Enemy Group Configuration

To define a new enemy combination, create a C# class that implements `IMultiEnemiesConfig`. The example below shows a minimal configuration for a battle featuring NPC1 alongside a custom enemy:

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UCT.Battle.MultiEnemiesConfigs;
using UCT.Battle.Enemies;

public class MyCustomConfig : IMultiEnemiesConfig
{
    // Names must match prefab folder names under Assets/Resources/Prefabs/Enemies/
    public string[] EnemyNames => new[] { "NPC1", "MyNewEnemy" };

    // Valid indices correspond to the order of EnemyNames
    public int[] validIndicesList => new[] { 0, 1 };

    // Coroutine that runs each enemy's turn sequence
    public IEnumerator<float> _EnemyTurns(int[] indices, ObjectPool bulletPool, ObjectPool boardPool)
    {
        foreach (int i in indices)
        {
            IEnemy enemy = TurnController.Instance.enemiesControllers[i].Enemy;
            
            yield return Timing.WaitForOneFrame;
            yield return Timing.RunCoroutine(enemy._EnemyTurns(i, bulletPool, boardPool));
        }
    }
}

```

**Key implementation details:**

- **`EnemyNames`** must reference existing prefab names (see the prefab files under `Assets/Resources/Prefabs/Enemies/`).
- **`validIndicesList`** defines the pool of possible turn indices; typical values are `new[] { 0, 1, 2 }` for three-enemy battles.
- The coroutine iterates over the `indices` array and delegates to each enemy's own `_EnemyTurns` method, preserving the existing turn-order system.

## Implementing Individual Enemy Logic

For new enemy types, implement the **`IEnemy`** interface defined in [`Assets/Scripts/UCT/Battle/Enemies/IEnemy.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Assets/Scripts/UCT/Battle/Enemies/IEnemy.cs). Below is a simple enemy that fires a projectile every turn:

```csharp
using System.Collections;
using UnityEngine;
using UCT.Battle;
using UCT.Battle.Enemies;

public class MyNewEnemy : MonoBehaviour, IEnemy
{
    public IEnemyTurnNumber TurnGenerator { get; set; } = new FixedTurnNumber(0);
    public EnemyState state { get; set; } = EnemyState.Default;

    public IEnumerator<float> _EnemyTurns(int index, ObjectPool bulletPool, ObjectPool boardPool)
    {
        var bullet = bulletPool.GetObject();
        bullet.transform.position = transform.position;
        bullet.GetComponent<Rigidbody2D>().velocity = Vector2.right * 5f;

        yield return Timing.WaitForSeconds(0.5f);
    }

    public string[] GetActOptions() => new[] { "Talk", "Inspect" };
}

```

**After creating the script:**

1. Save the prefab for the new enemy under `Assets/Resources/Prefabs/Enemies/MyNewEnemy.prefab`.
2. Reference the exact prefab name (`"MyNewEnemy"`) in the `EnemyNames` array of your custom configuration class.

## Runtime Selection and Testing

While the UI automatically populates available configs discovered by `TurnController`, you can force a specific configuration programmatically for testing purposes:

```csharp
// Inside TurnController.StartBattle() or a test script
var config = new MyCustomConfig();
StartCoroutine(config._EnemyTurns(indices, bulletPool, boardPool));

```

This bypasses the automatic discovery system and immediately launches your custom encounter with the specified enemy group.

## Summary

- Implement **`IMultiEnemiesConfig`** to define enemy groups, turn orchestration, and valid indices.
- Place enemy prefabs in `Assets/Resources/Prefabs/Enemies/` with names matching your config's `EnemyNames` array exactly.
- **`TurnController`** automatically discovers all configurations via reflection at runtime—no registration required.
- Individual enemies implement **`IEnemy`** with a **`TurnGenerator`** (such as `WeightedRandomTurnNumber` or `FixedTurnNumber`) and an **`_EnemyTurns`** coroutine.
- Reference existing enemies like those in [`Npc1Enemy.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Npc1Enemy.cs) or [`Npc2Enemy.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Npc2Enemy.cs) when designing complex multi-enemy encounters.

## Frequently Asked Questions

### What naming convention should I follow for enemy prefabs?

The strings in your configuration's `EnemyNames` array must exactly match the file or folder names under `Assets/Resources/Prefabs/Enemies/`. For example, if your prefab is named "NPC1.prefab", the array should contain the string `"NPC1"` (without the file extension).

### How does the turn order system work for multiple enemies?

Each enemy implements **`IEnemyTurnNumber`** through concrete generators like `WeightedRandomTurnNumber`, `CyclicTurnNumber`, or `FixedTurnNumber`. Your configuration's `validIndicesList` defines which indices are valid for that encounter, and the generators determine the sequence in which enemies take turns within those constraints.

### Do I need to register my new configuration in a central registry?

No. The `TurnController` automatically discovers all classes implementing `IMultiEnemiesConfig` using reflection when the battle initializes. Simply compiling the new class into your project makes it available for selection without touching [`TurnController.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/TurnController.cs) or any other manager.

### Can I combine existing template enemies with my custom ones?

Yes. The `EnemyNames` array can reference any combination of existing enemies (such as "NPC1" or "NPC2" from [`Npc1AndNpc2Config.cs`](https://github.com/arch-aik/undertale-changer-template/blob/main/Npc1AndNpc2Config.cs)) alongside your custom implementations, provided all corresponding prefabs exist in the `Assets/Resources/Prefabs/Enemies/` directory.