   Attack Formula
  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.   
  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 = TrueandDamage = Random((MinDamageOfWeapon * MinDamageMultiplier) to (MaxDamageOfWeapon * MaxDamageMultiplier)) * (1 / DamageResistance) - DamageReductionMinDamageOfWeapon 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 weaponsMaxDamageMultiplier is the factor (calculated elsewhere) that is used to change the maximum damage level of the weaponsDamageResistance 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.5Then 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 - DamageReductionIf 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:1Minimum Multiplier:1Maximum Multiplier:4Maximum Damage:20Damage Delt:19(was 18.7 was rounded)Armor Rating:100Real 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]} = AttackDamageARMOR DEFENSE[RoundDown(ARMOR VALUE*0.75)] = ArmorDefenseATTACK DAMAGE vs ARMOR(AttackDamage-ArmorDefense) = UnsoakedDamageDAMAGE TO BODY(Health-UnsoakedDamage) = HealthAfterDamageDamage CorrectionIf(UnsoakedDamage<0, Health, DamageToBody) = FinalHealthAfterDamageBasically 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 #1minWDMG 1maxWDMG20minDMGMultiplier1maxDMGMultiplier4Armor22DMGMultiplier3WeaponDMG15Attack DMG45.75(armor)16Unsoaked Damage29Health100HealthAfterDamage71FinalHealthAfterDamage71Test #2minWDMG1maxWDMG20minDMGMultiplier1maxDMGMultiplier4Armor63DMGMultiplier3WeaponDMG13Attack DMG39.75(armor)47Unsoaked Damage-8Health100HealthAfterDamage108FinalHealthAfterDamage100Test #3minWDMG1maxWDMG20minDMGMultiplier1maxDMGMultiplier4Armor14DMGMultiplier1WeaponDMG20Attack DMG20.75(armor)10Unsoaked Damage10Health100HealthAfterDamage90FinalHealthAfterDamage90;  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:1Maximum Weapon Damage:5Minimum Damage Multiplier:1Maximum Damage Multiplier:5Armor:100Damage Multiplier:4Weapon Damage:1Attack Damage:4Armor Rating(.75):75Unsoaked Damage:-71Minimum Weapon Damage:1Maximum Weapon Damage:5Minimum Damage Multiplier:1Maximum Damage Multiplier:5Armor:100Damage Multiplier:5Weapon Damage:1Attack Damage:5Armor Rating(.75):75Unsoaked Damage:-70Minimum Weapon Damage:1Maximum Weapon Damage:5Minimum Damage Multiplier:1Maximum Damage Multiplier:5Armor:100Damage Multiplier:2Weapon Damage:4Attack Damage:8Armor Rating(.75):75Unsoaked 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]} = AttackDamageATTACK DAMAGE TO ARMOR[RoundDown(AttackDamage*.75)] = AtkDMGToArmor ATTACK DAMAGE TO HEALTH(AttackDamage - AtkDMGToArmor) = AtkDMGToHealthARMORArmor=100ARMOR AFTER ATTACK DAMAGE TO ARMOR(Armor - AtkDMGToArmor) = ArmorAfterDMGFINAL ARMOR AFTER DAMAGE TO ARMOR[if(ArmorAfterDMG<0,"ARMOR BROKE",ArmorAfterDMG)] = FinalArmorAfterDMGUNSOAKED DAMAGE IF ARMOR BROKE{if[FinalArmorAfterDMG="ARMOR BROKE",({ArmorAfterDMG*-1}+AtkDMGToHealth),0]} = UnsoakedDMGHEALTHHealth=100HEALTH AFTER DAMAGE[if(UnsoakedDMG<0,Health-UnsoakedDMG,Health-AtkDMGToHealth)] = HealthAfterDMGFINAL 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 1minWDMG1maxWDMG5minDMGMultiplier1maxDMGMultiplier5DMGMultiplier3WeaponDMG3Attack DMG9AtkDMGToArmor6AtkDMGToHealth3Armor100ArmorAfterDamage94FinalArmorAfterDamage94UnsoakedDMG0Health100HealthAfterDamage97FinalHealthAfterDamage97ATTACK 2minWDMG1maxWDMG5minDMGMultiplier1maxDMGMultiplier5DMGMultiplier3WeaponDMG3Attack DMG9AtkDMGToArmor6AtkDMGToHealth3Armor94ArmorAfterDamage88FinalArmorAfterDamage88UnsoakedDMG0Health97HealthAfterDamage94FinalHealthAfterDamage94ATTACK 3minWDMG1maxWDMG5minDMGMultiplier1maxDMGMultiplier5DMGMultiplier3WeaponDMG4Attack DMG12AtkDMGToArmor9AtkDMGToHealth3Armor88ArmorAfterDamage79FinalArmorAfterDamage79UnsoakedDMG0Health94HealthAfterDamage91FinalHealthAfterDamage91ATTACK 4minWDMG1maxWDMG5minDMGMultiplier1maxDMGMultiplier5DMGMultiplier5WeaponDMG4Attack DMG20AtkDMGToArmor15AtkDMGToHealth5Armor79ArmorAfterDamage64FinalArmorAfterDamage64UnsoakedDMG0Health91HealthAfterDamage86FinalHealthAfterDamage86ATTACK 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).minWDMG1maxWDMG10minDMGMultiplier1maxDMGMultiplier10DMGMultiplier8WeaponDMG5Attack DMG40AtkDMGToArmor30AtkDMGToHealth10Armor64ArmorAfterDamage34FinalArmorAfterDamage34UnsoakedDMG0Health86HealthAfterDamage76FinalHealthAfterDamage76ATTACK 6Uh oh! Looks like that Armor is starting buckle!minWDMG1maxWDMG10minDMGMultiplier1maxDMGMultiplier10DMGMultiplier3WeaponDMG10Attack DMG30AtkDMGToArmor22AtkDMGToHealth8Armor34ArmorAfterDamage12FinalArmorAfterDamage12UnsoakedDMG0Health76HealthAfterDamage68FinalHealthAfterDamage68ATTACK 7The Armor Broke! CRAP! Now watch how fast the (not so defending) defender dies without it if he doesn't put up a fight.minWDMG1maxWDMG10minDMGMultiplier1maxDMGMultiplier10DMGMultiplier6WeaponDMG7Attack DMG42AtkDMGToArmor31AtkDMGToHealth11Armor12ArmorAfterDamage-19FinalArmorAfterDamageARMOR BROKEUnsoakedDMG30Health68HealthAfterDamage38FinalHealthAfterDamage38Attack 8minWDMG1maxWDMG10minDMGMultiplier1maxDMGMultiplier10DMGMultiplier5WeaponDMG7Attack DMG35AtkDMGToArmor26AtkDMGToHealth9Armor0ArmorAfterDamage-26FinalArmorAfterDamageARMOR BROKEUnsoakedDMG35Health38HealthAfterDamage3FinalHealthAfterDamage3Attack 9The attacker switches to his fist (a multiplier of 2 and a strength of 2) to finish this nemesis off.minWDMG1maxWDMG2minDMGMultiplier1maxDMGMultiplier2DMGMultiplier1WeaponDMG2Attack DMG2AtkDMGToArmor1AtkDMGToHealth1Armor0ArmorAfterDamage-1FinalArmorAfterDamageARMOR BROKEUnsoakedDMG2Health3HealthAfterDamage1FinalHealthAfterDamage1ATTACK 10well...now the attacker will just slap him on the face to speed up the dying process.(dmg 1 multiplier 2)minWDMG1maxWDMG1minDMGMultiplier1maxDMGMultiplier2DMGMultiplier2WeaponDMG1Attack DMG2AtkDMGToArmor1AtkDMGToHealth1Armor0ArmorAfterDamage-1FinalArmorAfterDamageARMOR BROKEUnsoakedDMG2Health1HealthAfterDamage-1FinalHealthAfterDamageDEADAnd there you have it.[Edited by - Griffin_Kemp on June 7, 2009 4:11:27 PM];Quote:Original post by SpardraOkay 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:1Minimum Multiplier:1Maximum Multiplier:4Maximum Damage:20Damage Delt:19(was 18.7 was rounded)Armor Rating:100Real 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:100Minimum Multiplier:1Maximum Multiplier:4Maximum Damage:2000Damage Delt:1870 (18.7 * 100)Armor Rating:100Real Damage:1770Of 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