How would you implement a dodge action?

I want to implement a DodgeAction for fun. The action would add a DODGING condition somewhere on the GameObject that lasts for a turn and gives a change to avoid damage.

This is just something fun I’m doing. The action is straight forward, I would add the condition as an enum of conditions, my question is what would you recommend adding it to? I could add a list of conditions to the Unit component, or to the HealthSystem component, or even create a new condition manager script on the Unit.

My question is mostly around coding best practices. How would you implement this?

My gut tells me to create a new script called Condition Manager on the Unit. I could add a listener to the Turn system to know when to clear it. I’m wondering if that is overkill though.

Just as a though experiment, how would you implement something like this?

As a side note, the whole reason I’m bothering with this now is that it’s a nice personal challenge to enhance the AI action options in this section.

That depends on what you mean by “best coding practices”, I’m going to be honest, I’ve shown this course’s code to some of my peers (I work at a game dev studio), and they don’t think it is “good, clean, code”, I won’t get into details as to why because I’ll have to write an essay, and I rather not, but long story short, the number of singletons, racing, and events, is just absurd according to them.

First, things first, naming conventions: Don’t name your scripts “managers”, it means everything, be more precise, like “Condition Assigner”, and I know, naming is hard, but trust me, if you put a little bit more effort into that your code will become a lot easier to read.

If you are planning to add multiple actions with different conditions then go ahead and create an enum, if you don’t, then keep it simple, a bool would be enough.

The ‘Dodge Action’ should be really simple, when the button is pressed it may play an animation and set a dodge bool to true. The health script can read the ‘Dodge Action’ script and see if the dodge is activated to act accordingly, you can add even more events, which I don’t recommend because debugging that is a complete nightmare, so I suggest a simple GetComponent in the Health script, if there’s a dodge action then read it, if not, then proceed to take damage.

When the full turn ends set the dodge bool to false, if I remember correctly there are already events that trigger when the turn ends, you can subscribe to those.

Just a quick game design note in case you want to turn your project into a full-fledge game. That ability might be a nightmare to balance for the following reasons:

  • AI reaction: It ignores units with that buff completely? The ability becomes way too situational, It doesn’t ignore the buff? Players will abuse the mechanic.
  • Balancing action points.
  • How many dodges per turn? Can a unit dodge multiple attacks or just one?
  • Take damage types into consideration. Can a unit dodge grenade damage?
  • Can the player use it multiple times per turn to increase the amount dodges?
  • The AI ignores the buffed units when looking for a path? Getting close to them without attacking.
  • If the AI ignores them completely, What’s the difference between dodging, invisibility and invincibility?

Hope this helps.

I don’t know that the AI should ignore the dodge at all.

I would say once the dodge is triggered by an attack, it would then be cleared.
Alternatively, thd dodge could be the number of action points spent on it that turn…

My first thought on this was “no”… but then I thought about it a bit further… a Dodge action, IMO, should cost the balance of the action points available to a character. This means it should be the last action chosen.

1 Like

That’s kinda the issue I’m seeing with this mechanic.

How will the AI prioritize targets? When there’s no evasion is kinda easy to do, you order the AI to attack the closest target with the lowest health, but, What if the lowest target has evasion on? Is it better to attack another target to lower its health or waste an attack on the buffed unit? If the enemy prioritizes dealing damage then there’s no difference from turning a unit invisible to the AI when using evasion, but if the enemy prioritizes attacking low health targets then the ability becomes over powered because you can use it as some sort of invicibility taunt.

The second scenario, the invicibility taunt, I can see myself enjoying that a lot, is a high risk high reward strategy, but to balance that out we should talk about adding classes, which opens up a lot of other things to consider, because that sort of ability should be given to a “rogue” type of class, meaning a high mobility, high damage, low health unit, if you give it to a “tank” class you’ll never see the benefit of it.

There are a lot of assumptions here that aren’t accurate but I’ll try to answer.

In my implementation, Dodge is triggered on your turn and the flag doesn’t get cleared until the start of your next turn. It reduces your chance to be hit as well as your chance to hit. You can make the AI strategy as complex or simple as you like. Fairly simple in this implementation,

if you have the dodge condition already or if there are no enemies in range, value is 0.
If you don’t have the condition and there are enemies in range the max value is multiplied by the ratio of enemies to friendlies.

When the AI chooses a target, it considers the value of both its chance to hit (I’ll implement ranges later), if the target is wounded.

Balance is an ongoing issue in any game.

1 dodge per turn, it lasts until your next turn. In my implementation I don’t use the blocking BUSY box, I have logic on the button to enable or disable it based on some conditions, in the case of Dodge it’s unavailable if you’ve dodged already.

Grenades don’t involve a to hit roll. (Again, I have that in my implementation, it’s not in the course)

Units can only dodge if they aren’t currently dodging.

There are a few questions assuming the AI ignores things, this just isn’t true. Ultimately, if things are too deterministic, I may add a weighted choice option for top actions if they are within a particular range. Stubbing out actions there are basically Spend and Use actions, and Use Once actions. Dodge is just stubbing out a Use Once action. If I polish this to actual game I’d probably implement cover instead, and add an Evade flag on a double move. For now though, Dodge puts in the mechanic I want to develop (modifications on the to hit chance and AI values for defense).

Again, the invincibility-invisibility-AI-ignores-them assumption isn’t applicable.

In terms of my own implementation, I just made an enum for conditions and stuck it in an array on the HealthSystem. I may expand that later to include timed conditions instead of simple set/clear conditions but it’s fine for now. The Dodge action sets the condition on the units health system, and adds a listener to clear it to the Turn System.

Hope that answers your questions.

I deviated the conversation from coding to game design because this mechanic can cause a lot of issues in a not-so-distant future. If you are just testing things out and having fun with the code, then feel free to completely ignore me.

As a professional game designer, I can tell you that phrase is a very, VERY, common trap many developers fall into. I’ve seen projects that had to be restarted because they didn’t foresee how the game would break because of a single mechanic, and numbers can’t always fix the issue, actually, more often than not, they’ll make it worse. Try to keep that in mind when developing a complex game like the one you’re creating, but again, you already said you are just having fun, ignore me.

Privacy & Terms