Page 1 of 2

Attack/defense formula for game

Posted: Thu Nov 15, 2018 5:26 pm
by DRW
In my current game, the amount of energy that a character loses shall be determined by certain attributes:

The hero has an attack value.
The hero has a defense value.
The hero has current life energy.

The opponent has an attack value.
The oponent has current life energy.
(Since the same opponent type always has the same initial values, a defense value isn't necessary here. A higher defense is simply realized by giving him more initial energy.)


When the hero gets hit by an opponent, the hero's energy loss is calculated by the opponent's attack value and the hero's defense value.

When the hero attacks an opponent, the opponent's energy loss is calculated by the hero's attack value.


Now, what is the best formula to calculate the energy loss per hit?

I've found some formulas:

damage = attack * attack / (attack + defense)

damage = attack / (100 / (100 + defense)

However, they use arbitrary multiplication and division, which is not really ideal for NES games since it eats up too much CPU time.

So, is there any good formula that can be calculated in a fast way and that has no drawbacks?
What did action adventures on the NES or Game Boy use here?


Since my game uses screen-by-screen scrolling like in "Zelda" and since weapons and items are equipped in a menu, I could maybe do an alternate approach:

I could use one of the above formulas to store the current potential hero damage and opponent damage values into the opponents' properties.
During a screen transition, the game stops for a moment anyway, so the calculation doesn't need to be ultra fast here.
Same when I equip items in a menu: I could just update each opponent's properties there.
This way, the game would simply use this one pre-calculated value to subtract from the energy and doesn't need to do any complicated calculations during live gameplay.

However, if I decide to make it possible that a new opponent enters the screen during gameplay, this could require a calculation of this forumla during live gameplay.

In the moment, new opponents cannot enter the screen, but I'm not sure if this will stay like this. Maybe bosses can spawn smaller henchmen.

One situation where new "characters" entering the screen is definitely already the case is when the opponent shoots a weapon.

And opponents and weapons have no direct relation:
An opponent has an array of movement patterns. And one step in one of those patterns might be "shoot this and that weapon".
Therefore, I cannot store a weapon damage value in an opponent's properties since the opponent definition doesn't even know directly if the opponent can shoot arrows or fireballs. Everything is independent from each other:
Certain opponent properties points to a collection of movement patterns. And any pattern can have any "spawn weapon xyz" as a command.


Another likely situation that might require calculation during live gameplay: If the hero is influenced by a temporary status value (like "cursed" or whatever those RPGs use) where, for example, his defense goes down for 20 seconds.


So, what would you suggest here? And how did old games do it?

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 5:46 pm
by rainwarrior
DRW wrote:However, they use arbitrary multiplication and division, which is not really ideal for NES games since it eats up too much CPU time.
Unless you expect to have to resolve 20 attack damages in the same frame, the slowness of division shouldn't really be a problem here.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 6:10 pm
by DRW
Not by itself, but the game logic does a whole bunch of other stuff as well which all adds up.

For example, this calculation:
damage = attack / (100 / (100 + defense));
where all variables are global zeropage variables of type unsigned char, requires 11 scanlines worth of CPU time. (I measured it by enabling and disabling $2001 mid-frame.)

This one:
damage = attack * attack / (attack + defense);
requires nine scanlines, so it's only slightly better.

Such values are unacceptable.
I'm aiming more for something in the range of one or two, at most three scanlines.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 7:50 pm
by never-obsolete
Are you set on calculating these things at run-time? If not, you could use look up tables.

And IIRC, the original Zelda just right shifted enemy attack values based on which ring upgrade you had. Essentially n, n/2, or n/4.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 8:00 pm
by gauauu
Now, what is the best formula to calculate the energy loss per hit?
It's hard to answer the question of BEST without really knowing your goals, but I've often just used the much simpler and obvious method:

Code: Select all

max(1, (attack - defense))
It has obvious disadvantages, but the advantage is that it's simple to calculate and simple to undestand.
What did action adventures on the NES or Game Boy use here?
Zelda was mentioned already.
I'm pretty sure Crystalis used just

Code: Select all

max(0,(attack-defense))
. (which is why you could get enemies you couldn't damage, or that couldn't damage you)
No idea what other games used.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 8:05 pm
by DRW
never-obsolete wrote:Are you set on calculating these things at run-time? If not, you could use look up tables.
Lookup tables would be fine, but how should I do this?

Let's say you attack an opponent:
You have an attack value that is native to the hero. (I'm not yet sure whether this is a fixed value or one that increases during the game.)
Your weapon has its own attack value.
But you can also equip items that increase your attack value. (Either by adding "+ n" to the current value or by doing stuff like "NewValue = BaseValue * 2".)
Furthermore, time-based live statuses may increase or decrease the value, like when an opponent can make you weak for 20 seconds or when you can temporarily boost your status with magic.

So, it's a bit difficult to do a lookup table here.
Same with being attacked by the opponent: You have to calculate the opponent's attack value in combination with your defense value. However, your defense value is calculated based on several items and statuses.
never-obsolete wrote:And IIRC, the original Zelda just right shifted enemy attack values based on which ring upgrade you had. Essentially n, n/2, or n/4.
Yeah, that was was really simple. But as you see, my game setup is a bit more complicated and more in line with actual RPGs, only that it's still an action game and not turn-based.
gauauu wrote:It's hard to answer the question of BEST without really knowing your goals
What do you mean with goals?
gauauu wrote:but I've often just used the much simpler and obvious method:

Code: Select all

max(1, (attack - defense))
Was this commonly used? Because it looks very simple.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 8:16 pm
by Nicole
gauauu wrote:It's hard to answer the question of BEST without really knowing your goals, but I've often just used the much simpler and obvious method:

max(1, (attack - defense))
Even Breath of the Wild goes for something this simple, for enemies attacking Link:

damage = max(1, base attack + max(0, weapon attack - defense))

Damage is in units of quarter-hearts, so if Link has 20 hearts, he has 80 HP.

Base attack depends on the enemy type and rank (e.g. for Bokoblins, it's 0 for red, 4 for blue, 8 for black, and 24 for silver). The effect of base attack is that attacks always do at least a set amount of damage, so no matter how stacked up on armor you are, a Silver Bokoblin will always do at least 24 damage (6 hearts) per hit, for example.

The reverse, where Link attacks enemies, is about as simple as it could possibly get:

damage = weapon attack

Enemies don't have defense at all, so they compensate with huge amounts of HP. For instance, as an extreme case, Gold Lynels, the strongest enemies in the game, have 7000 HP, the equivalent of 1750 hearts. (Luckily, the game doesn't actually tell you the correspondence between hearts and enemy HP, or it'd feel a little ridiculous.)

This does leave out a few combat mechanics (elemental damage, blocking, buffs, spin attacks, etc.), but as you can see, even a modern game can get by with simple formulas like these.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 8:52 pm
by gauauu
DRW wrote: What do you mean with goals?
I mean, like how you want your game balance to work. How impactful you want armor to be. Whether you're ok with the character just taking 1 damage. Whatever technique you pick will require planning armor values, enemy attack values, and player health values to achieve the balance and character progression that you want your game to have. So suggestions like mine (or what zelda does) will create a much different game than your formula. So the question comes down to: what reduces complexity but still keeps the goals you have for your game?

Code: Select all

max(1, (attack - defense))
Was this commonly used? Because it looks very simple.
No idea how commonly used it was. I've used it in 2 action-adventures, and I gave the example of Crystalis. But I haven't studied enough other games to know what's common.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 10:41 pm
by Oziphantom
either use "hit points" which is what I would think most things would do.

or use 128 percentiles. i.e don't /100 * 100 but /128 * 128, you will need to "up" your values by say 1/5 but a lot faster and its the relative scales of what you are doing that is important not the actual raw values.

Re: Attack/defense formula for game

Posted: Thu Nov 15, 2018 11:18 pm
by never-obsolete
Let's say you attack an opponent:
You have an attack value that is native to the hero. (I'm not yet sure whether this is a fixed value or one that increases during the game.)
Your weapon has its own attack value.
But you can also equip items that increase your attack value. (Either by adding "+ n" to the current value or by doing stuff like "NewValue = BaseValue * 2".)
Furthermore, time-based live statuses may increase or decrease the value, like when an opponent can make you weak for 20 seconds or when you can temporarily boost your status with magic.

So, it's a bit difficult to do a lookup table here.
Same with being attacked by the opponent: You have to calculate the opponent's attack value in combination with your defense value. However, your defense value is calculated based on several items and statuses.
From what it sounds like you plan to do, the attack/defense values will only involve some adds and possibly some shifts. These aren't very costly in terms of cpu cycles and the results can be cached until something changes. I was looking more at the damage formulas you gave as somewhere you could use the look up tables because there were only two inputs, the operations never change, and are costly.

With the proper look up table this:

Code: Select all

damage = attack / (100 / (100 + defense));
would be reduced to this:

Code: Select all

			ldy attack_val
			lda dmg_ptrlo, Y
			sta __ptr
			lda dmg_ptrhi, Y
			sta __ptr + 1
			
			ldy defense_val
			lda (__ptr), Y
			; A now holds your damage value
Now you have to look at what the possible ranges are for attack and defense, because the table will get huge fast.

Re: Attack/defense formula for game

Posted: Fri Nov 16, 2018 4:07 am
by mkwong98
Fire Emblem uses max(0,(strength + weapon - defense))

Re: Attack/defense formula for game

Posted: Fri Nov 16, 2018 8:14 am
by Sumez
How you want to calculate damage really depends on the design of your game. Like, do you want a higher damage or defense rating to be a nice "added bonus", or do you want it to be central to fighting an enemy?

For example, the Dragon Quest games usually have a treshold for when you can actually do solid damage to certain enemies with high defense, and it's not like twice the defense just means you do half the damage. These games thoroughly reward (and occasionally require) using spells to boost your attack or reduce the enemy's defense. And it gives a more immediately noticeable feedback from leveling up your stats.
However, for most pure action games this approach won't work as well, as you want the player to be able to win by using skill, rather than just relying on stats. (unless we count something like the old Ys games as "action")

Re: Attack/defense formula for game

Posted: Fri Nov 16, 2018 9:41 am
by yaros
You can also roll to calculate your attack based on the skill and defense. It will be longer than max check, but faster than /100 division.

You have weapon
Base damage: 5
Weapon (or character) skill: 80 out of 100

Enemy
Defense: 30 out of 100

Chance to attack: 80 (Skill) - 30 (Defence) = 50

Code: Select all

if (rand(100) < 50) 
    damage = 5;
else
    damage = 0;
Now you can double your damage if you have critical chance.

Code: Select all

if (rand(10) == 9) // assuming roll(10) gives 0-9 range
   damage = damage << 1;
These numbers are purely arbitrary, balance depends on what you want.

Re: Attack/defense formula for game

Posted: Fri Nov 16, 2018 9:44 pm
by Oziphantom
This is basically how D&D works..

Roll for Attack, I got a 12
Roll for Defense, they got a 8

I did 4 damage.

Re: Attack/defense formula for game

Posted: Sat Nov 17, 2018 2:39 am
by Bregalad
I'm no expert, but a random guess is that most NES-era games did it based on simple additions and substractions, possibly shifts. This makes it hard to get the balance right; for instance in Fire Emblem games (any game in the series) it's easy to be overpowered or underpowered, and this is part of the game; if you have the wrong character with wrong weapons it's not rare that you'do 0 damage per attack, and vice versa, if your character is overpowered it's not rare a weak enemy can do 0 damage per attack; and both sides can easily one-hit KO eachother.

More conventional RPGs such as Final Fantasy or Dragon Quest might use more advanced formulas, but those doesn't seem to have been developed before the SNES era. If this is inspiring for you, there is on GameFaqs:
Damage Formula FAQ for Final Fantasy III
Mechanics Guide for Chrono Trigger
Battle Mechanics FAQ and Enemy Mechanics FAQ for Final Fantasy VII

Whether those FAQs are accurate or not, and how did they figure the internal mechanics out, I do not know.