Search Unity

  1. Unity 2020.1 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Spell System - turn based combat

Discussion in 'Game Design' started by Varjacic, Aug 12, 2019.

  1. Varjacic

    Varjacic

    Joined:
    Dec 26, 2015
    Posts:
    2
    Hello everyone. For the last few days I've been trying to come up with a good way to implement spell system for my turn-based (grid) game. I recently found out about Scriptable Objects and they seem like a perfect tool for implementing this system. First I started with thinking about different types of spells and effects that I'd have in a game. So what I came up with is, buffs and debuffs (single and multi target, last through X turns), auras, direct damage spells (single target, aoe(multiple tiles)) with or without projectiles and on-hit effects. I believe SOs would be a good idea because they would make it easy(hopefully) to customize different spells just through inspector.

    I'm having a hard time with starting all of this. I have an idea but I feel like it's very inefficient and just a mess overall. Ok, so direct dmg spells seem like an easiest thing of the bunch, but for buff/debuffs, I think I should have an array of those in each Unit class so I can add them when they are cast and check at the start of turn if they should be removed or not. First thing that came to my mind is make a base abstract class for all spells.
    Code (CSharp):
    1. public abstract class SpellEffect : ScriptableObject {
    2.     public float cost;
    3.  
    4.     public abstract void Cast();
    5. }
    And then make a sub-class for each type.
    Code (CSharp):
    1. public  class StatusEffect : SpellEffect {
    2.  
    3.     public int numOfTurns;
    4.     public float modAmount;
    5.     public float modPerTurn;
    6.     public StatType statType;
    7.     public TargetType targType;
    8.  
    9.     public override void Cast() {
    10.     }
    11. }
    12. public class DirectDamage : SpellEffect {
    13.     public float damage;
    14.     public Projectile projectile;
    15.     public StatusEffect debuff;
    16.     public bool useProjectile = false;
    17.     public bool useDebuff = false;
    18.     public TargetType targType;
    19.  
    20.     public override void Cast() {
    21.     }
    22. }
    23.  
    24. public enum StatType {
    25.     critChance,
    26.     dodgeChance,
    27.     health,
    28.     armor,
    29.     attackDamage
    30. }
    31. public enum TargetType {
    32.     SELF,
    33.     TARGET,
    34.     AOE,
    35. }
    Something like that.
    I really don't know where or how to begin exactly. I would really appreciate some help and pointers.

    Thanks.
     
    TheKingOfTheRoad likes this.
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,891
    This seems like more of a code design problem than a game design one. You need to separate "how should I store the data?" from "what should the class hierarchy look like?" — these are two independent issues.

    For data storage, I generally prefer to use text files (in GRFON format, but that's just me). This allows me to do things like change the data while the game is running (assuming of course I have code that checks and reloads the files). Of course to some extent that can be done with ScriptableObjects too, as long as you're running within the editor.

    For the code design, yes, you'll probably want a base class, or at least an interface, for all your spells, and probably one for all your buffs/debuffs. For anything that has state (i.e. is not just an instant one-time effect), you'll also need to keep track of the state of the spell, probably separate from the code that defines the spell.

    But as this is the wrong forum to go into all that, I'm going to quit while I'm not too far behind. :)
     
    Joe-Censored and BIGTIMEMASTER like this.
  3. Varjacic

    Varjacic

    Joined:
    Dec 26, 2015
    Posts:
    2
    Thanks. And yeah, I picked SOs since they can be easily modified on the fly while running the game.
    If this is the wrong forum, is there a way to ask mods to move this thread?
     
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    8,776
    You can report your own thread probably, or send a private message to one of the mods. Probably send it to the Scripting forum.
     
  5. Volcanicus

    Volcanicus

    Joined:
    Jan 6, 2018
    Posts:
    169
    Before this dies, just so you know from my personal experience: top-down RPG design is very very bad if you are not good at it. If you have never done this before, either copy numbers from another system OR start with a base damage/cost formula and build from there. Otherwise you will end up with a degenerate RPG where only 1 strategy is optimal. That is the pitfall of top down design.

    Bottom-up design means you create a singular block and build with it. Top down is that you draw it all out from roof to foundations. Unless you are a pro, it is very hard to build something lacking foundations :)
     
  6. BIGTIMEMASTER

    BIGTIMEMASTER

    Joined:
    Jun 1, 2017
    Posts:
    3,484

    If this is meaning what I think, the idea is, build a super simple game with like one core ruleset (i.e. checkers or tic-tac-to), and only add on one feature at a time from there? Is that the idea?
     
    Volcanicus likes this.
  7. Volcanicus

    Volcanicus

    Joined:
    Jan 6, 2018
    Posts:
    169
    I will give you an idea of what I mean:
    Top down:
    You create 40 races, 18 classes, 20 spell schools and over 100 spells and what they do and the program each bit one by one and you have a game. There is a bit of testing for individual spells but no synergy testing beyond that.
    That is top down.

    Bottom up:
    You create 2 races and 2 classes with 1 spell each. You standardize that spell to do 1/10th of total hp dmg and test it.
    Then you tweak it. You continuously tweak it and add onto it until satisfactory.

    The second is more meticulous and longer to implement but also you have to do less refactoring. :)
     
unityunity