Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

gpalin

RPG damage equation

This topic is 5805 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am working on my first RPG in Visual Basic. I have gotten to a point where I need a good damage equation for when attacking enemies. The statistics I have are Strength, Endurance, Agility, Power, and Intelligence. I have a basic equation using the attacker''s Strength and the enemy''s Endurance, as below.
If characterStrength > enemyEndurance Then
  enemyHP = enemyHP - characterStrength - 5 + Random(characterLevel)
elseif characterStrength < enemyEndurance then
  enemyHP = enemyHP - characterStrength + 5 + Random(characterLevel)
end if
 
If the attacker has greater attack then the defender’s endurance, do extra damage. If attacking strength is less than defending endurance, do less damage. The Random statement adds some randomness to the attack, based on the character’s level. As the character goes up in levels, his attacks can increase too. I also have here the accompanying Random function, just for completeness.
Public Function Random(ByVal num As Long) As Long
  Random = Int(num * Rnd)
End Function
 
Now, this is just some pseudo code I wrote up, just to get started. What I would like to do is to add something to check for the Agility of the character and enemy, and make them both miss sometimes when attacking, and also to sometimes do double damage. As this is my first RPG, I would like some suggestions for including the Agility and occasionally lucky hits through code. Grant Palin

Share this post


Link to post
Share on other sites
Advertisement
Ok well I'm not much of a programmer but equations I can do. If I were you though I think I would check for the miss or lucky hit before like generate a random number off the charater level then say if the number is lower then some number (x) then it will be a miss if the number is between x and n then it is normal and if the number is above n it is lucky and have three equations where if it is a miss damage=0 and if it is normal use the same equation and if lucky make the equation add something else. It might look somthing like this.


If Random(characterLevel) < x Then
enemyHP = enemyHP
elseif Random(characterLevel) >x If characterStrength > enemyEndurance then
enemyHP = enemyHP - characterStrength - 5 + Random(characterLevel)
elseif characterStrength < enemyEndurance then
enemyHP = enemyHP - characterStrength + 5 + Random(characterLevel)
elseif Random(characterLevel >n Then
If characterStrength > enemyEndurance Then
enemyHP = enemyHP - characterStrength - 5 + Random(characterLevel) + Random(characterLevel)
elseif charaterStrengh < enemyEndurance then
enemyHP = enemyHP - characterStrengh + 5 + Random(characterLevel) + Random(characterLevel)
end if


My code prob. won't work I was doing it with not much programming skills but I hope you get my idea. Also you could take the agility of the player into account by adding it like this
(enemyAgility - characterAgility) 
and then add that to the random number. Hope this helps.

Edit: I actually think I would take it into funtions but I don't really know Basic all that well I'm more with C++ but that is two different if statements not one so I prob. need an
endif 
after your equations too.

[edited by - Serge on July 26, 2002 10:38:46 PM]

Share this post


Link to post
Share on other sites
Thanks Serge, the equation you provided looks pretty good. I've revised it as below. I corrected a few errors...There was an End If missing at the bottom.


If Random(characterLevel) < x Then ‘Miss
enemyHP = enemyHP
ElseIf Random(characterLevel) >=x and Random(characterLevel) If characterStrength > enemyEndurance Then
enemyHP = enemyHP - characterStrength - 5 - Random(characterLevel)
ElseIf characterStrength < enemyEndurance Then
enemyHP = enemyHP - characterStrength + 5 - Random(characterLevel)
End If
ElseIf Random(characterLevel) >=n Then ‘Lucky hit- double damage
If characterStrength > enemyEndurance Then
enemyHP = enemyHP - 2*(characterStrength - 5 + Random(characterLevel))
ElseIf characterStrength < enemyEndurance Then
enemyHP = enemyHP - 2*(characterStrength + 5 + Random(characterLevel))
End If
End If


Note that at the bottom of the code, for the double damage section, I removed the second Random number in each of those two equations, and as you can see, added a 2* in front, to double the effect. I also changed the + in front of each of the Random numbers to -, since I don't want to be giving HP back to the enemy! Only in the first set of equations, though. If I did the same in the second set, I would be losing damage. Anyway, let me know if there are any errors in my editing, and if you have any other ideas, just leave a message here!

Grant Palin

[edited by - gpalin on July 26, 2002 12:48:24 AM]

Share this post


Link to post
Share on other sites
If I were you I wouldn''t use arbitrary numbers such as ''2*'' or ''-5''. I''d rather make an universal and logical system
But it''s up on you of course.

Share this post


Link to post
Share on other sites
If you feel like getting more complex with this (and other parts of the RPG), you may consider getting the Advanced Dungeons And Dragons Rulebook (or another paper and pen based RPG). The AD&D Volume 2 rulebook has some pretty well integrated stuff in there that'd apply in other parts of the game as well. Also, it should give you some idea of how others have handled these sorts of calculations.

If I remember right, I believe their setup is something like this:

Each character has agility, dexterity, intelligence, wisdom, charisma, strength, 'n some others that I can't remember at the moment.

Depending on the character's dexterity and the character's proficiency with whatever weapon he/she's using at the time, they get assigned a THAC0 (To hit armour class 0 (lower armour class=better protection; higher agility may provide bonuses to armour class)). At the beginning of a turn in a fight the character will decide who to attack and they'll calculate what they need to roll to hit that character (if the player has a THAC0 of 7 and the enemy has an armour class of 3, the player must roll a 4 to hit the enemy (remember: lower armour class = good thing)). During a fight the character will roll some dice (I dunno, a bunch let's say) and if the number's higher than whatever they need to hit the enemy, they hit 'em. If it's exactly a certain number (18 I figure, as the sum of three six sided dice), then the player may double the damage that will be dealt to the enemy (critical hit).

Please note, this is all based on whatever I happen to remember of reading a book many years ago, so a good portion of this may be sheer BS.


[Edit: Spellin ish bad while drunch: they're != there != their]

[edited by - Melraidin on July 27, 2002 1:14:28 AM]

Share this post


Link to post
Share on other sites
quote:

If I were you I wouldn''t use arbitrary numbers such as ''2*'' or ''-5''. I''d rather make an universal and logical system.



Why??

Here''s my equation as I have it now, after some revision.


If Random(50) < x Then ‘Miss
Damage = 0
enemyHP = enemyHP
ElseIf Random(50) >= x and Random(50) < n Then ’Normal hit
If characterStrength > enemyEndurance Then
Damage = characterStrength + 5 + Random(characterLevel)
enemyHP = enemyHP - Damage
ElseIf characterStrength < enemyEndurance Then
Damage = characterStrength - 5 + Random(characterLevel)
enemyHP = enemyHP - Damage
End If
ElseIf Random(50) >=n Then ‘Lucky hit- double damage
If characterStrength > enemyEndurance Then
Damage = 2 * (characterStrength + 5 + Random(characterLevel))
enemyHP = enemyHP - Damage
ElseIf characterStrength < enemyEndurance Then
Damage = 2 * (characterStrength - 5 + Random(characterLevel))
enemyHP = enemyHP - Damage
End If
End If


This advanced equation adds checking for the value of a random number; if the random number is below a constant value, no damage is done (a miss). If the value is between the previous constant and the second constant, the damage is a normal amount (normal damage). And if the value is above the second constant, the damage is doubled (lucky attack).

I''d still like to add something for Agility. I''ve got an idea. and I''ll put it online when I''ve got it fleshed out.

Grant Palin

Share this post


Link to post
Share on other sites
Okay, here''s my new equation.


If Random(50) < x Then ‘Miss
Damage = 0
enemyHP = enemyHP
ElseIf Random(50) >= x and Random(50) < n Then ’Normal hit
If characterStrength > enemyEndurance Then
Damage = characterStrength + 5 + (characterAgility - enemyAgility) + Random(characterLevel)
enemyHP = enemyHP - Damage
ElseIf characterStrength < enemyEndurance Then
Damage = characterStrength - 5 + (characterAgility - enemyAgility) + Random(characterLevel)
enemyHP = enemyHP - Damage
End If
ElseIf Random(50) >=n Then ‘Lucky hit- double damage
If characterStrength > enemyEndurance Then
Damage = 2 * (characterStrength + 5 + (characterAgility - enemyAgility) + Random(characterLevel))
enemyHP = enemyHP - Damage
ElseIf characterStrength < enemyEndurance Then
Damage = 2 * (characterStrength - 5 + (characterAgility - enemyAgility) + Random(characterLevel))
enemyHP = enemyHP - Damage
End If
End If


This version of the equation uses the Agility stats of the attacker and defender. If the attacker has more Agility, he does more damage, and less Agility means less damage.

I am thinking of removing the random numbers based on the character levels, since they don''t seem to have much of an effect on the total damage. If anyone has thoughts on this, please let me know.


Grant Palin

Share this post


Link to post
Share on other sites
I wouldn''t use numbers like *2 or -5 because

1. You may forget why they''re there
2. They''re hard to change later

It''s much easier to make a variable such as COMBAT_PENALTY or COMBAT_BONUS and use that instead because it would fix the above problems.

Share this post


Link to post
Share on other sites
Allow me to suggest a few things.

1) Write your character class as an object with all of your listed statistics as properties.

It will be alot easier to keep track of it all, trust me,
but i will stick to your linear method for now.

2) Try not to do as much math on the fly. I''m assuming that like any good RPG there will be alot of combat involved. If your going to call this function alot, which you will, you should resolve as much upfront as possible.

How will you handle armor, how will you change it?

See if any of this looks good:


Const CHAINMAIL_VALUE = 30


Private Function NewAC As Long

NewAC = Agility + EquippedArmorValue

End Function

Private Function ToHit AS Long

ToHit = CharacterStrength + Int(Rnd * 100) + 1

End Function


When your character changes armor then

EquippedArmorValue = CHAINMAIL_VALUE
CurrentAC = NewAC




When your character actually attacks:

If ToHit >= MonsterArmorClass Then

ResolveDamage

Else

You Missed

End If



Kind of tough really to read because i haven''t coded without objects since i''ve learned to do them but definitely don''t recalculate anything in your to hit swing that you can calculate once and carry with you. Invent an ArmorClass that will carry each creatures chance to avoid damage with it, so you don''t have to recalculate it. Also think about your code and your game, you don''t want write a line of code for each incidence in your program, you really just want to write the rules they will use and then toss a bunch of data at your rules. And finally, for the third time(i think) pre-calculate everything you can. VB math functions are really slow. Maybe you could Pre-generate a whole bunch of random numbers when your app loads and then iterate through an array to get your to hit seed. (make any sense?)

Best of Luck!


Dreddnafious Maelstrom

"If i saw farther, it was because I stood on the shoulders of giants."

Sir Isaac Newton

Share this post


Link to post
Share on other sites
quote:
Original post by Dreddnafious Maelstrom
Allow me to suggest a few things.

1) Write your character class as an object with all of your listed statistics as properties.


You mean like this??

Public Type Character
Name As String
Sex As String
Race As String
Class As String
Strength As Long
Endurance As Long
Agility As Long
Power As Long ''Controls the effectiveness of spells
Intelligence As Long ''Controls the number of spell points
MaxHP As Long ''Maximum Hit points
CurHP As Long ''Current HP
MaxSP As Long ''Maximum Spell points
CurSP As Long ''Current SP
Level As Long ''Current level
Experience As Long ''Current experience
ExpToNextLvl As Long ''Experience to next level
Gold As Long
End Type

Public Hero As Character


quote:

It will be a lot easier to keep track of it all, trust me,
but I will stick to your linear method for now.


No need, I have a fair grasp of classes, like I showed above. If you thought of that because I had all those seperate variables, that was just some pseudocode I wrote up to get me started. Here''s the real code that I have in the game now...


If Random(50) < x Then ''Miss- no damage
Damage = 0
Enemy(CurrentType).CurHP = Enemy(CurrentType).CurHP
ElseIf Random(50) >= x And Random(50) < n Then ''Normal hit
If Hero.Strength > Enemy(CurrentType).Endurance Then
Damage = Hero.Strength + 5 + Random(Hero.Level)
Enemy(CurrentType).CurHP = Enemy(CurrentType).CurHP - Damage
ElseIf Hero.Strength < Enemy(CurrentType).Endurance Then
Damage = Hero.Strength - 5 + Random(Hero.Level)
Enemy(CurrentType).CurHP = Enemy(CurrentType).CurHP - Damage
End If
ElseIf Random(50) >= n Then ''Lucky hit- double damage
If Hero.Strength > Enemy(CurrentType).Endurance Then
Damage = 2 * (Hero.Strength + 5 + Random(Hero.Level))
Enemy(CurrentType).CurHP = Enemy(CurrentType).CurHP - Damage
ElseIf Hero.Strength < Enemy(CurrentType).Endurance Then
Damage = 2 * (Hero.Strength - 5 + Random(Hero.Level))
Enemy(CurrentType).CurHP = Enemy(CurrentType).CurHP - Damage
End If
End If


quote:

2) Try not to do as much math on the fly. I''m assuming that like any good RPG there will be alot of combat involved. If your going to call this function alot, which you will, you should resolve as much upfront as possible.


It''s not a real-time game, if that''s what you''re wondering. I don''t know nearly enough yet to do real-time. My game is played through forms I created in Visual Basic, and combat is turn-based. I don''t think your statement above would be as much of an issue, would it?

That aside, I don''t really understand- should I seperate the calculations somehow? That doesn''t seem to make sense to me, since I''m only doing them in one place: the Combat form. Could you explain yourself some more?

quote:

How will you handle armor, how will you change it?

See if any of this looks good:


Const CHAINMAIL_VALUE = 30


Private Function NewAC As Long

NewAC = Agility + EquippedArmorValue

End Function

Private Function ToHit AS Long

ToHit = CharacterStrength + Int(Rnd * 100) + 1

End Function


When your character changes armor then

EquippedArmorValue = CHAINMAIL_VALUE
CurrentAC = NewAC




When your character actually attacks:

If ToHit >= MonsterArmorClass Then

ResolveDamage

Else

You Missed

End If



Kind of tough really to read because i haven''t coded without objects since i''ve learned to do them but definitely don''t recalculate anything in your to hit swing that you can calculate once and carry with you. Invent an ArmorClass that will carry each creatures chance to avoid damage with it, so you don''t have to recalculate it. Also think about your code and your game, you don''t want write a line of code for each incidence in your program, you really just want to write the rules they will use and then toss a bunch of data at your rules. And finally, for the third time(i think) pre-calculate everything you can. VB math functions are really slow. Maybe you could Pre-generate a whole bunch of random numbers when your app loads and then iterate through an array to get your to hit seed. (make any sense?)


I''m not doing anything with armor yet. I''m trying to get the basic game running first, and to tell the truth, I''m not sure yet exactly which way it''s going to go. All I have (more or less) fully functioning yet are the Character Creation and Combat forms.

However, please do keep up with the helpful advice!

quote:

Best of Luck!



Thanks!!

Grant Palin

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!