Search Unity

Evaluate my spell design?

Discussion in 'Scripting' started by Nemox, Feb 4, 2015.

  1. Nemox

    Nemox

    Joined:
    Feb 16, 2010
    Posts:
    396
    Hey, so I'm creating a spell system and I wanted to see if any pros think my design is valid.

    I want to rely on a very composition-based approach so that creating new spells is easy. My Spell class currently only has a few variables: The icon, the caster, target and subtargets, the time elapsed, and a duration for the chargeup and channeled part of the spell. Every spell basically has a flow of these states:
    Initialize > Chargeup > Begin > Channel > Finish.

    Also in the Spell class is a corresponding List<SpellEffect> for each state. A SpellEffect is mostly just a small collection of variables and an enum that tells the Spell how to use them. (The enum has stuff like ScriptedEffect, FindTarget, FindSubTarget, ClearTargets, SpawnObject, DoAnimation, PhysicalDamage, etc.)

    Since some SpellEffects might have to refer to already-existing objects or variables (like a fireball that's been spawned during chargeup but not yet fired), I thought it might be useful to have the Spell also contain lists of GameObject, float, int, string, etc. components. This would also cut down on the sheer number of variables a SpellEffect needs to contain, because instead a SpellEffect could refer to Spell components by name instead of having a ton of serialized fields itself.
    This does, however mean having a ton of custom KeyValuePair-type lists, which could get unwieldy... Let's call them "Labeled".

    Thus the Spell class will roughly have these properties;
    icon, caster, target, subtarget, time, chargeDuration, channelDuration, List<SpellEffect> x5, List<LabeledGameObject>, List<LabeledInt>, List<LabeledFloat>, List<LabeledString>.


    Does this sound like a good design, or should I be wary about going this direction?
     
  2. tango209

    tango209

    Joined:
    Feb 23, 2011
    Posts:
    379
    I generally find trying to create a do-it-all class like this is a royal PITA to maintain and extend. I would suggest creating separate classes with a common base class for things that act fairly different (instant cast, channeled, spells that hop from target to target, etc.).

    I wouldn't put a ton of effort into designing the classes out at this point. Your design won't survive the first week, if days. Things to attempt to design for at this point are things you know will be very different. Do a lot of iteration and play testing.

    Anyways, that's how I usually tackle these kinds of systems.
     
  3. Nemox

    Nemox

    Joined:
    Feb 16, 2010
    Posts:
    396
    Hm... My main goal is to create a kit that even non-programmers could use to create spells, while still keeping the potential open for that sort of inheritance-based design, hence the ScriptedEffect part of the enum.

    I will be sure to keep practicality in mind though. Gotta ship eventually.
     
  4. Zaladur

    Zaladur

    Joined:
    Oct 20, 2012
    Posts:
    392
    I'm not fully following what you are attempting to do with the Labels system, but I can see that becoming unwieldy.

    Can you give a specific example of a spell and how the Labels system would be used to create/manage it?

    I've worked on a similar system for generic spell creation that relies heavily on composition, so I'm more than happy to do a deeper dive in this later on when I have more time.
     
  5. Nemox

    Nemox

    Joined:
    Feb 16, 2010
    Posts:
    396
    Cool! Before I explain, I do want to note that I just remembered hashtables are a thing, so that'll simplify a lot of the non-serialized runtime variables and such.

    Let's say I've got a simple fireball spell. On the Spell, I've got a list of GameObjects to use as prefabs, so I've got one that I label "Fireball". I also have a list of floats, one of which is "Speed".

    When the spell is first cast, the spell is Initialized, and the Initialize SpellEffects happen. This includes; spawning the gameobject labeled "Fireball" as a property of the hashtable, creating a vector called "Velocity" in the hashtable that is set to the character's orientation, multiply "Velocity" by "Speed", start the character's animation.

    Then the Spell goes into chargeup mode, and a timer keeps track of that for a while. When the chargeup ends, it goes into Begin mode and the Begin SpellEffects happen. The "Fireball" in the hashtable is then launched at "Velocity", and the character is animated. The Channel duration is at 0, so it skips to Finish, and some data is cleaned up and whatnot.