Attack Formula

Started by
9 comments, last by AlphaCoder 14 years, 10 months ago
Hello, I am creating a web-based RPG and I need help with the battle class I am creating. I need help thinking of a good way to do the attack forumla... Here is my idea for stats: Strength - Affects how much damage you do with melee hits. Intelligence - Affects how much (mana or magic) you have, how much damage you do with skills, chance to hit with skills and (mana or magic) heal rate. Dexterity - Affects your chance to hit and to be hit. Constitution - Affects your life level, life healing rate and healing items have a better effect. There will be defense as well but that will come from the armor... I need to think of a way to make it so the strength,defense and dexterity have an effect with how much damage someone does with their weapons. The weapons will have a minimum/maximum hit value so that needs to be incorporated as well. Here is what I have tried, but isn't working to my liking as it is very unpredictable. %Hit = (rand(1, %OffDEX) - rand(1, %DefDEX)); //Hit percentage %Hit would equal a random number between 1 and the Offenses Dexterity subtract a random number between 1 and the Defenses Dexterity if its greater than zero then an attack will be made, if zero or less it will miss. %ATK = round(((%OffSTR * rand(%OffWEPMin, %OffWEPMax)) / rand(1, %DefDEF)), 0); //Hit amount %ATK would equal the Offenses strength multiplied by the weapons min/max attack rating divided by the Defenses defense and if its less than zero it would attack 1.. Just didn't work out how I planned as it always hits 1 or over 10 never in between or nothing. The Weapon min/max value was 1 to 5 and the strength was 5 and the defense was 50. So yeah, if anyone has a good formula to help with my attacks I would greatly appreciate it. Thanks in advance.
Advertisement
What you need to start with is the system.

The formula is the end result of the combat system design. It is how the system is implemented (in the code).

So a broad outline of what you have described is:

* There is some factor that governs the chance to hit.
* There is some factor that governs the chance to avoid being hit.
* There is some factor that increases the amount of damage inflicted.
* There is some factor that decreases the amount of damage inflicted.

Therefore:

If (ChanceToHit - ChanceToDodge) > 1 Then Hit = True

and

Damage = Random((MinDamageOfWeapon * MinDamageMultiplier) to (MaxDamageOfWeapon * MaxDamageMultiplier)) * (1 / DamageResistance) - DamageReduction

MinDamageOfWeapon is the minimum base damage that the weapons dose.
MaxDamageOfWeapon is the maximum base damage that the weapons dose.

MinDamageMultiplier is the factor (calculated elsewhere) that is used to change the minimum damage level of the weapons
MaxDamageMultiplier is the factor (calculated elsewhere) that is used to change the maximum damage level of the weapons

DamageResistance is the ability of the target to resist a percentage of the damage.
DamageReduction is a factor that reduces a set amount pf damage from each hit.

This DamageResistance and Damage Reduction allow you to have an interesting aspect to the game. Quick attacks are more effected by DamageReduction than slow powerful attacks. So if you make quick attacks do more damage per second (or damage per turn if in a turn based game) and allowing multiple hits to be made in that period, then you have a gameplay choice between fast but individually weak hits and slow but individually powerful hits.

For example:

If two different attacks with the first doing 5 hits at 20 damage each hit for a total of 100 damage and the other doing 1 hit for 100 damage.

Then a DamageResistance of 5% would give 5 hits at 19 damage (20 - 20 * 0.05) for a total of 95 damage for the first and for the second a total of 95 damage (100 - 100 * 0.05).

A DamageReduction of 1 (which is the same value as the Resistance value) would also give 5 hits at 19 damage for a total of 95 damage for the first and for the second a total of 99 damage.

As you can see, DamageReduction is weaker against Powerful attacks than DamageResistance.
Thanks, that helped a lot but I ran into another problem. See I am not going to have damage resistance in my game at all. There will be no elemental attacks really, just physical attacks.

So my question is: Without using damage resistance and just damage reduction coming from a percentage of their defense, how could I make it work that way? I tried using 5% for every 100 armor they had but once they got up to 2000 armor they got hit for 0 this is what I was doing:

%Damage = (%ATK - %ATK * (%DefDEF / 2000))

Which I know my problem, (2000 / 2000) = 1 so therefore (%ATK - %ATK * 1) = 0 but there has to be a way to fix that because I am sure users would get over 2000 armor rating... But if I use a lower percent per every 100 armor they have there really isn't a significant damage reduction so it kinda makes armor useless in a way besides Stat Gains...
Make 0=1.5
Then the lowest possible equation is (1.5*1)
Quote:Thanks, that helped a lot but I ran into another problem. See I am not going to have damage resistance in my game at all. There will be no elemental attacks really, just physical attacks.

Dropping Damage Resistance is fine, it was just something that I thought could make combat more interesting, but it is not necessary. Also, I didn't know how you were going to implement armour (Armour could mean damage resistance or damage reduction so I included both). You could equally well keep damage reduction and drop damage resistance.

Damage resistance isn't necessarily about element attacks, it is just a different way that one can implement armour.

Although, what you are describing as the intent of your formula is very much like damage resistance, but the implementation of your formula is like damage reduction (and I think this is where your problem lies - you are wanting one but a implementing the other)

Quote:Which I know my problem, (2000 / 2000) = 1 so therefore (%ATK - %ATK * 1) = 0 but there has to be a way to fix that because I am sure users would get over 2000 armor rating... But if I use a lower percent per every 100 armor they have there really isn't a significant damage reduction so it kinda makes armor useless in a way besides Stat Gains...

The problem is in the formula itself. So the first thing is to throw that formula out, it will not work the way you intend it to work.

If you want the formula to work like damage reduction your formula needs to be like:

Damage = Attack - DamageReduction

If you want your formula to work like Damage Resistance it needs to look like this:

Damage = Attack - (Attack * DamageResistance)

Where DamageResistance is a floating point number between 0 and 1.

In your formula, because you are dividing the defence variable by 2000 you are stating that a defence value of 2000 will mean that no damage gets through. You are saying that a defence value of 2000 of a 100% reduction in damage. So having an defence value of greater than 2000 will actually heal the target.

Using my formulas as a basis (you can expand on them a bit, mainly in how you calculate the Attack and DamageResistance/Reduction values) you can get the formula you want.
Okay with all that in mind, where does the damage reduction variable come from? How could I implement that, lets say everything looks like this:

Minimum Damage:1
Minimum Multiplier:1
Maximum Multiplier:4
Maximum Damage:20
Damage Delt:19(was 18.7 was rounded)
Armor Rating:100
Real Damage:??

Those are real variables I just did a debug output of them. But not sure how to subtract the armor from the Damage Delt to do an understandable amount of damage lets say in the example the armor rating is 100 and the damage delt is 19 so therefore 19 - 100 = -81 so therefore no damage would've been done... Got a formula for that I know everything is probably there right in front of my face I just cannot seem to work it out at all.
Here's my take on this same process:

ATTACK DAMAGE
{[RandomBetween(minDamangeOfWeapon, MaxDamageOfWeapon)] * [RandomBetween(minDamageMultiplier, maxDamageMultiplier]} = AttackDamage

ARMOR DEFENSE
[RoundDown(ARMOR VALUE*0.75)] = ArmorDefense


ATTACK DAMAGE vs ARMOR
(AttackDamage-ArmorDefense) = UnsoakedDamage

DAMAGE TO BODY
(Health-UnsoakedDamage) = HealthAfterDamage

Damage Correction
If(UnsoakedDamage<0, Health, DamageToBody) = FinalHealthAfterDamage


Basically this takes the product of the damage multiplier and the weapon damage and subtracts that from 75% of the Armor value. What is left from this is subtracted from the hitpoints(body).
If the armor soaks all of the incoming damage, then the hitpoints(body)remain at the value they were prior to the attack.

Here's a snapshot of it just using excel (using a random between 0-100 for Armor to simulate different Armor encounters)


Test #1
minWDMG 		1maxWDMG			20minDMGMultiplier	1maxDMGMultiplier	4Armor			22DMGMultiplier		3WeaponDMG		15Attack DMG		45.75(armor)		16Unsoaked Damage		29Health			100HealthAfterDamage	71FinalHealthAfterDamage	71


Test #2
minWDMG			1maxWDMG			20minDMGMultiplier	1maxDMGMultiplier	4Armor			63DMGMultiplier		3WeaponDMG		13Attack DMG		39.75(armor)		47Unsoaked Damage		-8Health			100HealthAfterDamage	108FinalHealthAfterDamage	100


Test #3
minWDMG			1maxWDMG			20minDMGMultiplier	1maxDMGMultiplier	4Armor			14DMGMultiplier		1WeaponDMG		20Attack DMG		20.75(armor)		10Unsoaked Damage		10Health			100HealthAfterDamage	90FinalHealthAfterDamage	90
See that is the thing once again, in my game you'll probably start off with around 100 armor rating from the beginning gear and up from there. Depending on the race you choose your stats will range from 1 to 5 in the start and your beginning weapon will do between 1 to 5 damage... Using what you just showed me this is what I get.

Minimum Weapon Damage:1
Maximum Weapon Damage:5

Minimum Damage Multiplier:1
Maximum Damage Multiplier:5

Armor:100
Damage Multiplier:4
Weapon Damage:1
Attack Damage:4
Armor Rating(.75):75
Unsoaked Damage:-71

Minimum Weapon Damage:1
Maximum Weapon Damage:5

Minimum Damage Multiplier:1
Maximum Damage Multiplier:5

Armor:100
Damage Multiplier:5
Weapon Damage:1
Attack Damage:5
Armor Rating(.75):75
Unsoaked Damage:-70

Minimum Weapon Damage:1
Maximum Weapon Damage:5

Minimum Damage Multiplier:1
Maximum Damage Multiplier:5

Armor:100
Damage Multiplier:2
Weapon Damage:4
Attack Damage:8
Armor Rating(.75):75
Unsoaked Damage:-67
Then you have a broken system with the way that you are using armor.

If armor is a soak prior to health being hit, then damage that is not capable of exceeding your armor's value is never going to hit.

The above of what you typed isn't a problem with the formula.
That is mathematically the effect of a kid with a stick hitting a man wearing armor.

It doesn't hurt. The man wearing the armor would just stay at 100 health.

You have to figure out how Armor is used in your system more clearly if you want to make weapons small numbers against armor which is large numbers and still have it hit the health.

You have to change the system to be more complex and allow for armor to act as a second pool of health which depletes to 0 over time (breaks) until repaired.

I would suggest allowing armor to take 75% of the attack damage, and health take 25% of the attack damage up until the armor depletes to 0 (breaks).

You would need an equation that says the following:

ATTACK DAMAGE
{[RandomBetween(minDamangeOfWeapon, MaxDamageOfWeapon)] * [RandomBetween(minDamageMultiplier, maxDamageMultiplier]} = AttackDamage

ATTACK DAMAGE TO ARMOR
[RoundDown(AttackDamage*.75)] = AtkDMGToArmor

ATTACK DAMAGE TO HEALTH
(AttackDamage - AtkDMGToArmor) = AtkDMGToHealth

ARMOR
Armor=100

ARMOR AFTER ATTACK DAMAGE TO ARMOR
(Armor - AtkDMGToArmor) = ArmorAfterDMG

FINAL ARMOR AFTER DAMAGE TO ARMOR
[if(ArmorAfterDMG<0,"ARMOR BROKE",ArmorAfterDMG)] = FinalArmorAfterDMG

UNSOAKED DAMAGE IF ARMOR BROKE
{if[FinalArmorAfterDMG="ARMOR BROKE",({ArmorAfterDMG*-1}+AtkDMGToHealth),0]} = UnsoakedDMG

HEALTH
Health=100

HEALTH AFTER DAMAGE
[if(UnsoakedDMG<0,Health-UnsoakedDMG,Health-AtkDMGToHealth)] = HealthAfterDMG

FINAL HEALTH AFTER DAMAGE
[if(HealthAfterDMG<0,"DEAD",HealthAfterDMG)]


This computes as follows (the following is a spot of the same two character's with one progressively getting beat down until dead).

Here is the 10 attack report of this test.
ATTACK 1minWDMG			1maxWDMG			5minDMGMultiplier	1maxDMGMultiplier	5		DMGMultiplier		3WeaponDMG		3Attack DMG		9AtkDMGToArmor		6AtkDMGToHealth		3	Armor			100ArmorAfterDamage	94FinalArmorAfterDamage	94UnsoakedDMG		0	Health			100HealthAfterDamage	97FinalHealthAfterDamage	97ATTACK 2minWDMG			1maxWDMG			5minDMGMultiplier	1maxDMGMultiplier	5		DMGMultiplier		3WeaponDMG		3Attack DMG		9AtkDMGToArmor		6AtkDMGToHealth		3	Armor			94ArmorAfterDamage	88FinalArmorAfterDamage	88UnsoakedDMG		0	Health			97HealthAfterDamage	94FinalHealthAfterDamage	94ATTACK 3minWDMG			1maxWDMG			5minDMGMultiplier	1maxDMGMultiplier	5		DMGMultiplier		3WeaponDMG		4Attack DMG		12AtkDMGToArmor		9AtkDMGToHealth		3	Armor			88ArmorAfterDamage	79FinalArmorAfterDamage	79UnsoakedDMG		0	Health			94HealthAfterDamage	91FinalHealthAfterDamage	91ATTACK 4minWDMG			1maxWDMG			5minDMGMultiplier	1maxDMGMultiplier	5		DMGMultiplier		5WeaponDMG		4Attack DMG		20AtkDMGToArmor		15AtkDMGToHealth		5	Armor			79ArmorAfterDamage	64FinalArmorAfterDamage	64UnsoakedDMG		0	Health			91HealthAfterDamage	86FinalHealthAfterDamage	86ATTACK 5Well...at this point, the attacker figured that a sword was really gettingannoying to attack with and picked up an axe, which attacks at twice thestrength (and multiplier because I want to) of the sword (translation...in anautomated system this may go quickly, but in spread sheet hit by hitform...this would take forever at 5*5 max hitting power).minWDMG			1maxWDMG			10minDMGMultiplier	1maxDMGMultiplier	10		DMGMultiplier		8WeaponDMG		5Attack DMG		40AtkDMGToArmor		30AtkDMGToHealth		10	Armor			64ArmorAfterDamage	34FinalArmorAfterDamage	34UnsoakedDMG		0	Health			86HealthAfterDamage	76FinalHealthAfterDamage	76ATTACK 6Uh oh! Looks like that Armor is starting buckle!minWDMG			1maxWDMG			10minDMGMultiplier	1maxDMGMultiplier	10		DMGMultiplier		3WeaponDMG		10Attack DMG		30AtkDMGToArmor		22AtkDMGToHealth		8	Armor			34ArmorAfterDamage	12FinalArmorAfterDamage	12UnsoakedDMG		0	Health			76HealthAfterDamage	68FinalHealthAfterDamage	68ATTACK 7The Armor Broke! CRAP! Now watch how fast the (not so defending) defender dies without it if he doesn't put up a fight.minWDMG			1maxWDMG			10minDMGMultiplier	1maxDMGMultiplier	10		DMGMultiplier		6WeaponDMG		7Attack DMG		42AtkDMGToArmor		31AtkDMGToHealth		11	Armor			12ArmorAfterDamage	-19FinalArmorAfterDamage	ARMOR BROKEUnsoakedDMG		30	Health			68HealthAfterDamage	38FinalHealthAfterDamage	38Attack 8minWDMG			1maxWDMG			10minDMGMultiplier	1maxDMGMultiplier	10		DMGMultiplier		5WeaponDMG		7Attack DMG		35AtkDMGToArmor		26AtkDMGToHealth		9	Armor			0ArmorAfterDamage	-26FinalArmorAfterDamage	ARMOR BROKEUnsoakedDMG		35	Health			38HealthAfterDamage	3FinalHealthAfterDamage	3Attack 9The attacker switches to his fist (a multiplier of 2 and a strength of 2) to finish this nemesis off.minWDMG			1maxWDMG			2minDMGMultiplier	1maxDMGMultiplier	2		DMGMultiplier		1WeaponDMG		2Attack DMG		2AtkDMGToArmor		1AtkDMGToHealth		1	Armor			0ArmorAfterDamage	-1FinalArmorAfterDamage	ARMOR BROKEUnsoakedDMG		2	Health			3HealthAfterDamage	1FinalHealthAfterDamage	1ATTACK 10well...now the attacker will just slap him on the face to speed up the dying process.(dmg 1 multiplier 2)minWDMG			1maxWDMG			1minDMGMultiplier	1maxDMGMultiplier	2		DMGMultiplier		2WeaponDMG		1Attack DMG		2AtkDMGToArmor		1AtkDMGToHealth		1	Armor			0ArmorAfterDamage	-1FinalArmorAfterDamage	ARMOR BROKEUnsoakedDMG		2	Health			1HealthAfterDamage	-1FinalHealthAfterDamage	DEADAnd there you have it.


[Edited by - Griffin_Kemp on June 7, 2009 4:11:27 PM]
Quote:Original post by Spardra
Okay with all that in mind, where does the damage reduction variable come from? How could I implement that, lets say everything looks like this:

Minimum Damage:1
Minimum Multiplier:1
Maximum Multiplier:4
Maximum Damage:20
Damage Delt:19(was 18.7 was rounded)
Armor Rating:100
Real Damage:??

Those are real variables I just did a debug output of them. But not sure how to subtract the armor from the Damage Delt to do an understandable amount of damage lets say in the example the armor rating is 100 and the damage delt is 19 so therefore 19 - 100 = -81 so therefore no damage would've been done... Got a formula for that I know everything is probably there right in front of my face I just cannot seem to work it out at all.

As Griffin_Kemp said, you are using the numbers incorrectly.

If armour is going to be the amount of damage soaked from each hit, then it can not be larger than the amount hit for. Either you have to increase the Health and Attack values, or lower the armour values.

These values (armour, health and damage) are actually arbitrary values.

If I had an attack that did 10 damage and my opponent had 50 health, this is no different from me having an attack value of 10,000 and the target having 50,000 health.

In either case it will take 5 hits to kill the target.

The scale of the value is completely arbitrary.

So if you are going to have armour values of around 100 to 2000, then you probably want to have health around 1,000 to 5,000. Based on the values you have posted, then you might want to multiply Health and Damage by around 50 to 100.

This would mean that the new values would look like:

Minimum Damage:100
Minimum Multiplier:1
Maximum Multiplier:4
Maximum Damage:2000
Damage Delt:1870 (18.7 * 100)
Armor Rating:100
Real Damage:1770

Of course, if you armour reduces it to below 0 then you set the amount of damage to 0, this is just a simple if statement:

if Damage Dealt < 0 then Damage Dealt = 0

This topic is closed to new replies.

Advertisement