Trying to do an RPG move list with each move having its own method

My idea is to make it kinda like with the Mario&Luigi games where each move has a short mingame-ish thing, but I’m not sure how to give each individual move a method while still having all of them be part of the move list. Here’s how my script for the moves is currently

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface Moves
{
    public void eff();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(fileName ="Moves",menuName ="Moves/Create Move")]

public class MoveDB: ScriptableObject, Moves
{
    [SerializeField]string nom;

    [TextArea]
    [SerializeField] string desc;

    [SerializeField] int pow;

    public void eff()
    {
        throw new System.NotImplementedException();
    }

}

Rather than implementing each move in a single ScriptableObject, I would create an abstract Move ScriptableObject with something like an Execute method. Then you can create each of your moves as a subclass of Move implementing Execute. For each move, you can create an asset for it in your project. Your list of moves is then a Move list, and you can drag your assets into it in the inspector (or load it from Resources, or Addressables, or whatever). You might also make a struct that associates each Move to an identifier, so you can easily reference specific moves throughout your game.

In pseudocode form:

public enum MoveId {
    Stomp
}

[Serializable]
public struct MoveEntry {
    public MoveId id; // or int, or string, or whatever
    public Move move;
}

[CreateAssetMenu]
public class MoveList : ScriptableObject {
    public List<MoveEntry> moves;
}

public abstract class Move : ScriptableObject {
    public abstract void Execute ( /* pass whatever context you need here */ );
}

[CreateAssetMenu(menuName='Moves/Stomp')]
public class StompMove : Move {
    public override void Execute ( /* context */ ) {
        // perform the stomp move
    }
}

One question, would stuff like the moves’ attack, name, and description go on MoveEntry?

I would put that on the Move itself as fields, and then fill those fields out in the SO instance inspector.

public abstract class Move : ScriptableObject {
    public string name;
    [TextArea]
    public string description;

    public abstract void Execute ( /* pass whatever context you need here */ );
}