Chapter 9: "Your Number Is Up"
Some details, ideas, and
musings I've had experiencing effective RPGs and RPG Makers
© April 2019 Written by David Wicker
Please do
not reprint without permission
Today's chapter is going to be a slightly tedious one. Yes, it's that old devil math, come to pay us an intellectual visit.
Now, if you don't have your thinking cap on, go to do so now. I'll wait here for you ...
Back ? Okay, let's begin. First off, it's quite easy to drown in math. Trying to figure out calculations involving hit points, armor defense, elemental spells, levels of play, prowess of opponents, and speed of attackers without a ready plan could be a nightmare indeed.
But if you think it out - carefully, and work out the equations, simplest to hardest, you should be able to do it.
What this chapter will NOT cover is the method of gaining power as used by Saga Frontier 1 for the PSX where you always gain attributes after every fight, nor will it in any way talk about how to gain levels or "hearts" as might be seen in Legend Of Zelda, any incarnation.
No, this will cover a hopefully relatively simple method of turn-based combat where you start with standard in your party and you want to know how to handle damage, defense, levels, and elemental values.
The most important thing with any degree of calculation that increases exponentially is to make a table. Now sure, you could calculate your way manually to everything, but you might lose focus on what the original purpose of the numbers were for.
Let's begin. To start with, we're going to make an incremental array, 100 elements in size, numbered from 0 to 99. The resulting value will be a number from 0 to 999,999,999 which should be big enough to divide into any category you wish.
Before we do this, I wanted to point out some common variable types that you will need for any decent programming language. I am not going to recommend the programming language you write your game in as there are already countless articles pointing out the merit and lack of in different coding languages out there.
I am going to assume the programming language you chose is capable of 32-bit numbers. Here is a brief list of variable types that should be available in the system you choose:
BOOLEAN (or BIT or BOOL) ... 1-bit (1 or 0 or TRUE and FALSE, constants)
BYTE ... 8-bits (from 0 up to 255)
SHORTINT ... 8-BITS (from -128 up to 127)
CHAR ... 8-bits (single character string holding an ASCII value from 0 to 255)
INTEGER (or INT) ... 16-bits (from -32768 to 32767)
FLOAT ... 32-bits (from 1.2E-38 to 3.4E+38)
LONGINT ... 32-bits (from -2147483648 to 2147483647)
LONGFLOAT (or DOUBLE) ... 64-bits (from 2.3E-308 to 1.7E+308)
STRING ... special case, can contain multiple characters, treat as single indice array
It will be LONGINT that we will create the table in. As you can see there are 10 digits available. We are only going to use the first 9 to store a value from 0 to 999999999 or to read it properly:
999,999,999
or
Nine hundred ninety-nine million, nine hundred ninety-nine thousand, nine hundred ninety-nine.
Certainly should be big enough. And I will state at this time, experience points are the one value you want to have as high as possible so the player can indeed always at least gain 1-experience point to defeat a critter, but must seek out more difficult prey in order to boost their experience points to the millions.
Remember RPGs if they are done correctly can take MONTHS to play. You want to stretch out those experience points as high as possible.
The exponent we'll use here is hand-picked, in this case, and you're more than welcome to use this for your own projects:
Increment=Increment+Index^3.8480788+475*(Index/4976.0)
Array[Index]=Increment
Phew ! Are you still with me ? Good ! Okay, let's look at this table now.
Array[0]=0
Array[1]=1
Array[2]=15
Array[3]=83
Array[4]=290
Array[5]=779
Array[6]=1766
Array[7]=3553
Array[8]=6540
Array[9]=11239
Array[10]=18288
Array[11]=28459
Array[12]=42676
Array[13]=62021
Array[14]=87749
Array[15]=121300
Array[16]=164309
Array[17]=218618
Array[18]=286288
Array[19]=369608
Array[20]=471109
Array[21]=593573
Array[22]=740044
Array[23]=913840
Array[24]=1118562
Array[25]=1358107
Array[26]=1636675
Array[27]=1958784
Array[28]=2329277
Array[29]=2753335
Array[30]=3236484
Array[31]=3784608
Array[32]=4403960
Array[33]=5101169
Array[34]=5883252
Array[35]=6757625
Array[36]=7732112
Array[37]=8814954
Array[38]=10014820
Array[39]=11340818
Array[40]=12802504
Array[41]=14409890
Array[42]=16173457
Array[43]=18104162
Array[44]=20213451
Array[45]=22513265
Array[46]=25016051
Array[47]=27734773
Array[48]=30682921
Array[49]=33874519
Array[50]=37324136
Array[51]=41046895
Array[52]=45058484
Array[53]=49375163
Array[54]=54013775
Array[55]=58991754
Array[56]=64327136
Array[57]=70038569
Array[58]=76145319
Array[59]=82667282
Array[60]=89624992
Array[61]=97039632
Array[62]=104933041
Array[63]=113327725
Array[64]=122246866
Array[65]=131714328
Array[66]=141754671
Array[67]=152393157
Array[68]=163655761
Array[69]=175569177
Array[70]=188160830
Array[71]=201458884
Array[72]=215492250
Array[73]=230290599
Array[74]=245884365
Array[75]=262304758
Array[76]=279583772
Array[77]=297754193
Array[78]=316849610
Array[79]=336904422
Array[80]=357953847
Array[81]=380033932
Array[82]=403181561
Array[83]=427434463
Array[84]=452831223
Array[85]=479411289
Array[86]=507214980
Array[87]=536283498
Array[88]=566658934
Array[89]=598384277
Array[90]=631503423
Array[91]=666061185
Array[92]=702103300
Array[93]=739676437
Array[94]=778828208
Array[95]=819607176
Array[96]=862062861
Array[97]=906245752
Array[98]=952207315
Array[99]=999999999
Zero is zero. Yes it is. If you don't want that, you can always increase the index by one to get the desired number of one. You are also welcome of course to just manually copy that code above if you don't want to fudge with the math involved.
Okay, now that we have a table, how do you cut it ? Pretty much like a cake. We already have 999,999,999 as our biggest number so let's consider what could actually EQUAL this monster.
We mentioned earlier experience points. So, okay, let's do that. Set it so the LEVEL OF THE PLAYER is a number from 1-99 and the 9-digit value is the experience points required to be at that level.
Since you don't want the player to start at level 0, you can either adjust so it APPEARS the player is level 1 visually, or fudge the table and increase by one, shouldn't hurt either way.
Now I know what you're wondering, okay, so you created a table for experience points, now, how about hit points ? No problem.
It has been my experience (no pun intended) that RPGs never give the player more than 9999 hit points at level 99. So, simply, take the expr value and divide by 100000, that's 5 zeroes.
Then add 20 if you like, so the player has a bit of a buffer and won't die on the first hit. It doesn't matter if you do or do not include the actual 99th array, if you want to stop at 98 so you can do early math, that's okay too.
Right, now let's get to some of the more difficult math. Combat.
It's important to realize what HELPS and HINDERS the player in combat. Let's see an example of this.
The player is level 7. They are attacking a level 5 "Fire Dragon" in the desert. They are equipped with a "Frosty Battle Axe" which is weapon level 3, attribute ICE. The player's strength is 10 and the dragon has an attribute of FIRE for defense.
Quite a bit ! Okay, so what we really want to do is calculate the lot of this so it can work out up to 99 but no higher, in order to retrieve the return value, which in turn can be sliced so the maximum damage possible is 999.
The easiest way to do this is to determine which from a number of 1-100 uses up the entire 100% based on the importance of each attribute calculated.
Here is what flies or fails your combat, getting the percentages correct all the way around. We're not even going to worry about the ending value just yet, we want to get the BALANCES set first.
It's all about how you slice it. It's still going to wind up delicious if you do it right.
So, the level of the player minus the level of the attacker is probably the most important value so let's give that a priority of 50%. The player's strength is next. Prioritize that at 15%. We still have 35% left before we must return a value.
The last value we want here is the actual weapon's level. We can throw our lot and use up the remaining 35% for that. And we're done - for determining basic damage.
But this isn't a basic monster. We still must account for elemental class, in this case a "Frosty Battle Axe" and a "Fire Dragon." But that comes later.
Now it's time to calculate the dragon's defense. This will directly COUNTER the values of the player. We already took into account the calculation of the player's level minus the attacker's level. And yes, if the attacker's level is the same as the player's, then zero is the result for the remaining 50% of the damage the attacker receives.
So quite simply, if you are attacking a critter that is the same level as you, the only damage you can do is calculated from your weapon, strength, and any attributes and NOT your player's level.
This then encourages the player to "grind." That is, to attack many lower level critters first to build up their strength before going after harder monsters.
Alright, let's talk about elements. Adding an elemental attribute to a weapon improves it in many different ways. First off, if you are attacking normally a monster that has an elemental attribute, you will always be penalized for the final total value.
I'm not going to go into great detail regarding the different types of elemental classes but we can deal with a few simple ones if you like, and each must have one that is the opposite.
ELECTRICITY and WATER
LIGHT and DARK
FIRE and ICE
You can develop new ones on your own. Back to the combat. The critter has a FIRE attribute and you are attacking with an ICE weapon. This will make your attack 2x more powerful ! Here is a comparison table, and you can just use this manually, a table will not be needed.
ICE weapon vs ICE attribute = 100% damage
NO ELEMENT weapon vs FIRE attribute = 25% damage
ICE weapon vs FIRE attribute = 200% damage
ANY OTHER ELEMENT weapon vs FIRE attribute = 50% damage
You can see how this develops. Quite simply, take the final damage value and feed it through here. Indeed it may be possible to get a number higher than 9999 or whatever boundaries you have set. Curb the enthusiastic numbers and keep them within range should they stray outside of what the table is you are using.
Defense is very similar.
ICE attack vs ICE armor = 100% defense
FIRE attack vs NO ELEMENT armor = 50% defense (player receives more damage)
FIRE attack vs WATER armor = 25% defense (player receives most damage)
FIRE attack vs ANY OTHER ELEMENT armor = 75% defense, elements always prosper
If you reverse that, that is, a non-elemental attack hits a player with an elemental armor:
NO ELEMENT vs ICE armor = 150% defense
NO ELEMENT vs NO ELEMENT = 100% defense
I think you get the idea.
Combat in most RPGs comprise a large part of the game itself. While in RPGs you do find keys, locks, treasure, secrets, hidden objects, and maybe a little romance along the way. But for the most of it, you WILL be in combat and it must "taste" correct. That is as I penned earlier, Fast, Funny, and Furious. Never have combat linger on and on.
Keep these 3-attributes but also make the math correct. If a player is wearing ice armor and they come up against fiery monsters, the player is going to be at a severe penalty in defense. Reversing, if they are wearing ice armor and come up against ice monsters, they will be evenly classed.
And the last, if the player is wearing ice armor (or really any elemental armor) and come up against non-elemental attacks, the player will always receive a bonus in protection as it is understood purchasing elemental armor (or weapons for that matter) will always be more expensive than regular weapons and armor.
. . .
Phew ! This was indeed a tedious chapter but a very necessary one. You cannot have a RPG without combat - so get the math right and make a lot of players happy. :)
Next week we'll cover the topic of dungeons and the advantages and disadvantages of having them randomized or instead to be carefully designed tile-per-tile by the Worldbuilder. Also the mechanics and important attributes involved in building random dungeons.
Until then, bye for now ...