2

I have an attack chaining system for a game, but it gets very complicated very q...

 2 years ago
source link: https://www.codesd.com/item/i-have-an-attack-chaining-system-for-a-game-but-it-gets-very-complicated-very-quickly.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

I have an attack chaining system for a game, but it gets very complicated very quickly

advertisements

I'm in a game development course for my compsci bachelors and our project it to make an XNA game. We're making a jrpg-style game and came up with a cool idea for the combat: every turn you queue 3 skills, based on the skills and the order chosen various bonus effects can be applied. We made a basic one with 2 skills: attack and fire.

You start with the first skill, then the arrows show the second and third skills chosen. The boxes on the second and 3rd levels show the effect added at that point.

The basics: Attack+Attack = Higher crit chance for the second attack. Fire+Attack = Adds some fire damage to the attack's original damage. Fire+Fire = Applies burn status

The harder part is when you hit 3 in a row, since they make a sort of special attack. Attack does a 1/4 chance of crit, Fire does a double damage Fire attack (named a Fireball).

Implementing this in if-statements could get painful with more skills. The number of if-statements is equal to the sum of n^n from 1 to n, so if we wanted 6 skills we would need to write 6+36+216=258 if statements! Many of which would be redundant as well! This would be prone to errors as we'd have to painstakingly craft each if statement so that they're in the correct position as we code our flowcharts.

That's why we thought we should have some generalized combinations with a static effect, maybe increasing a counter if it can be cumulative, then for when we have 3 in a row call the function that has the special attack of that skill.

The first thing that came to mind was a finite state machine. It would be able to handle all cases except the specials I think. Maybe a push-down automata? The main problem I have is that I have no idea how I would implement them in code. The class I learned them in was theoretical.

Are there any other more efficient or easier to write/code methods?


I'd figure out some kind of recursive model instead:

enum Outcomes { Crit, DoubleCrit, FireDMG, Burn, NoEffect }

abstract class Attack
{
    public Attack() { Child = null; }

    List<Outcomes> GetOutcomes();
    protected virtual Attack Child;
}
class Melee : Attack
{
    public Melee() : base() { }
    public Melee(Attack child) : base() { Child = child; }

    List<Outcomes> GetOutcomes()
    {
        List<Outcomes> ret = new List<Outcomes>();
        if(Child != null) ret.Add(Child.GetOutcomes());

        if(ret.Contains(Outcomes.Crit))
            ret.Add(Outcomes.DoubleCrit);
        else
            ret.Add(Outcomes.Crit);

        return ret;
    }
}
class Fire : Attack
{
    public Fire() : base() { }
    public Fire(Attack child) : base() { Child = child; }

    List<Outcomes> GetOutcomes()
    {
        List<Outcomes> ret = new List<Outcomes>();
        if(Child != null) ret.Add(Child.GetOutcomes());

        List<Outcomes> PossibleOutcomes = new List<Outcomes>();        

        PossibleOutcomes.Add(Outcomes.FireDMG);
        PossibleOutcomes.Add(Outcomes.Burn);

        if(ret.Contains(Outcomes.Burn)) PossibleOutcomes.Add(Outcomes.Fireball)
        if(ret.Contains(Outcomes.FireDMG)) PossibleOutcomes.Add(Outcomes.NoEffect);

        // Use some randomization method to select an item from PossibleOutcomes
        int rnd = 2; // Totally random number.
        ret.Add(PossibleOutcomes[rnd]);

        return ret;
    }
}

Then to chain attacks just use:

Attack ChosenAttack = new Melee(new Fire(new Melee()));

Or assuming the user selects each branch you just need to keep the last one and continuously add it as a child to the next attack they select.

Attack ChosenAttack = new Melee();

// Some events occur...

ChosenAttack = new Fire(ChosenAttack);

// Some more...

ChosenAttack = new Melee(ChosenAttack);

I apologize if I'm not quite understanding the problem and my suggestion won't work.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK