BlackMagicAPI Guide

Updated a week ago

BlackMagicAPI Guide

A comprehensive framework for Mage Arena modding

Table of Contents

  1. Basic Setup
  2. Spell Creation
  3. Item System
  4. Crafting Recipes
  5. Death Icons
  6. Asset Management
  7. Network Synchronization
  8. API Reference
  9. Troubleshooting

Basic Setup

Core Requirements

  • BepInEx 5.4.21+
  • .NET Framework 4.8
  • BlackMagicAPI.dll reference

Plugin Template

[BepInPlugin("your.mod.id", "Your Mod Name", "1.0.0")]
public class MyMod : BaseUnityPlugin
{
    private void Awake()
    {
        // Registration examples
        BlackMagicManager.RegisterSpell(this, typeof(YourSpellData), typeof(YourSpellLogic));
        BlackMagicManager.RegisterItem(this, typeof(YourItemData), typeof(YourItemBehavior));
        BlackMagicManager.RegisterCraftingRecipe(this, typeof(IngredientA), typeof(IngredientB), typeof(Result));
        BlackMagicManager.RegisterDeathIcon(this, "custom.death", "death_icon.png");
    }
}

Spell Creation

Spell Data Class

internal class FireballData : SpellData
{
    public override SpellType SpellType => SpellType.Page;
    public override string Name => "Fireball";
    public override float Cooldown => 3f;
    public override Color GlowColor => Color.red;
    
    // Additional voice command aliases
    public override string[] SubNames => ["flameball", "inferno"];
}

Spell Logic Class

internal class FireballLogic : SpellLogic
{
    public override void CastSpell(GameObject playerObj, PageController page, Vector3 spawnPos, Vector3 viewDirectionVector, int castingLevel)
    {
    }

    // Optional page item interaction
    public override void OnPageItemUse(GameObject itemOwner, PageController page)
    {
    }
}

Spell Prefab Access

// Get all active instances
var activeFireballs = Spell<FireballData>.GetLogicInstances();

// Get specific prefab component
var fireballPrefab = Spell<FireballData>.GetLogicPrefab<FireballLogic>();

// Check prefab existence
if(Spell<FireballData>.GetPagePrefab() != null) 
{
    // Prefab is loaded
}

Registration

BlackMagicManager.RegisterSpell(
    this, 
    typeof(FireballData), 
    typeof(FireballLogic)
);

Item System

Complete Item Example

internal class HealthPotionData : ItemData
{
    public override string Name => "Health Potion";
}

internal class HealthPotionBehavior : ItemBehavior
{
    protected override void OnItemUse(GameObject owner)
    {
    }
}

Crafting Recipes

Advanced Recipe Configuration

// Basic recipe
BlackMagicManager.RegisterCraftingRecipe(
    this,
    typeof(FireEssence),
    typeof(IceShard), 
    typeof(SteamSpirit)
);

Recipe Requirements

Component Requirements
Ingredients Must implement IItemInteraction
Result Must be a prefab of IItemInteraction

API Reference

SpellLogic Class

/// <summary>
/// Base class for all spell behaviors with lifecycle management
/// </summary>
public abstract class SpellLogic : MonoBehaviour, ISpell
{
    /// <summary>
    /// Core spell casting implementation
    /// </summary>
    public abstract void CastSpell(GameObject playerObj, PageController page, 
        Vector3 spawnPos, Vector3 viewDirectionVector, int castingLevel);

    /// <summary>
    /// Network data serialization for Castor
    /// </summary>
    public virtual void WriteData(DataWriter writer, PageController page,
        GameObject player, Vector3 spawnPos, Vector3 direction, int level) {}

    /// <summary>
    /// Client-side data synchronization
    /// </summary>
    public virtual void SyncData(object[] values) {}
}

Spell<SD> Utility Class

/// <summary>
/// Generic spell accessor providing runtime management utilities
/// </summary>
public class Spell<SD> where SD : SpellData
{
    /// <summary>
    /// Retrieves the PageController prefab for this spell type
    /// </summary>
    public static PageController? GetPagePrefab() { ... }

    /// <summary>
    /// Gets all active instances of this spell type
    /// </summary>
    public static SpellLogic?[] GetLogicInstances() { ... }

    /// <summary>
    /// Gets typed instances filtered by specific SpellLogic subtype
    /// </summary>
    public static SL?[] GetLogicInstances<SL>() where SL : SpellLogic { ... }
}