# RPG Damage Calculation Logartihm in Java

I'm trying to make a damage calculation formula for my RPG game, there are 12 levels for both the Player and the Enemy, I've come as far as making a Reverse Exponential formula, but I want the damage to go down from slow to faster as the Players level gets closer to the level of the Enemy.

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

public class DamageCalc {

private static double defense;
private static double dmg;
private static String teststring;

public static void main(String args[]) throws FileNotFoundException, UnsupportedEncodingException{
for(int i = 1; i <= 12; ++i){
for(int j = 1; j <= 12; ++j){
defense = ((j * 3) * 2 + 11) * 2;
dmg = i * 12;
double totaldmg = getDamage(i,dmg,defense,j);
teststring += "Player Level " + i + "\nMonster Level " + j + "\nTotal Damage " + totaldmg + "\n----------------------------------\n";
}
}
PrintWriter test = new PrintWriter("testvalues.txt","UTF-8");
test.println(teststring);
test.close();
}

public static double getDamage(double level, double dmg, double defense, double enemy){
double intdamage = (((2*level+10) / 128) * (dmg/defense) * 11 + 1) * 10;
double damage = Math.ceil(Math.pow(intdamage,level/12) * 10);
System.out.println(intdamage);
return damage;
}

}


The code just loops through the players level (int i) and the enemies level (int j), then returns the damage done. The difference in damage between level 1 and 2 is significantly higher than between 11 and 12, eventhough that should be the other way around.

EDIT: I'll explain it even further. The player starts with 12 for each stat, every level 12 get's added (dmg = level * 12). Every stat for the player has 128 points and monsters 128 points, so that's why the begin defense of a monster is 11. If the damage stat from the player is lower than the defense of the enemy, the damage will get a penalty, otherwise it will get a boost (double * (dmg/defense)).

I hope this explains it.

• I don't see a question. – user3730788 Dec 2 '15 at 12:59
• I'm seeing a value of 13 for Lvl 1 vs Lvl 2 and a value of 239 for Lvl 11 vs Lvl 12... There must be something I'm missing as 13 is not significantly higher than 239? – XNargaHuntress Dec 2 '15 at 15:07
• @XGundam05 No I mean, if you are Level 12, and you fight versus a Lvl 1 and 2 enemy, the difference inbetween those is way higher than when you fight a Lvl 11 and 12 enemy. – GigaNova Dec 2 '15 at 15:14

Your given damage calculation (except for the inverse exponential) breaks down to:

intDamage = (1320/128) * (10 * lvl^2 + 50 * lvl)/(6 * enemyLvl + 11) + 10


The damage curve you appear to be looking for instead will wind up taking the form of:

1 / (enemyLvl - n) + m
^    ^
|  push desired part of curve above origin
|
move desired part of curve to right of origin


Approximately in this case, n = maxLvl + 1 and m = 1. Given that, we can figure out something that should approximate the curve, and damage levels you're looking for:

c = 1320 / 128
equalLvl = (((10 * lvl^2 + 50*lvl) / (6*lvl + 11)) + 10) * c
damage = equalLvl * ((1 / (enemyLvl - 13)) + 2);
finalDamage = Ceiling(damage/20 * lvl)


This gives a rough approximation of the desired curve with close to the desired damage values.

To get the damage falloff more to where you like it, primarily play around with the values of n and m.

UPDATE: To get an even closer approximation to the desired curve, we should scale the curve according to the player's level, and then handle what happens after the "knee" (where enemy > player).

So we can approximately adjust the formulae as follows:

if (enemyLvl > lvl)
damage = equalLvl * ((1 / (enemyLvl - (lvl + 1)) + 2)
else
damage = equalLvl * (lvl / enemyLvl) /*Deal with the Knee*/


The snippet below has been adjusted to use the new approximation.

var result = document.getElementById('result');

function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

function getDmg(lvl, dmg, def, ene){
var c = 1320/128;
var cDamage = ((10*lvl*lvl+50*lvl)/(6*lvl+11) + 10) * c;
var yDamage = cDamage * (1/(ene-(lvl + 1))+2);

if (ene > lvl)
yDamage = cDamage * (lvl / ene);

var damage = Math.ceil(yDamage/20*lvl);
return damage;
}

for (var pl = 1; pl <= 12; pl++){
for (var ml = 1; ml <= 12; ml++){
var def = ((ml*3)*2+11)*2;
var dmg = pl*12;
var totDmg = getDmg(pl, dmg, def, ml);

var s = ml== 1? '*' + pad(pl, 5, ' ') : pad(pl, 6, ' ');
s += ' ' + pad(ml, 7, ' ');
s += ' ' + pad(totDmg, 6, ' ');

result.textContent += s + '\n';
}
}
<pre id='result'>Player Monster Damage
</pre>

There are a number of functions you can use to model this functionality.

We want to modify the player damage by 1x if the player_level - monster_level = 0, and we want the player damage modifier to increase exponentially as player_level - monster_level approaches infinity. Conversely we can have the player damage modifier decrease exponentially as player_level - monster_level approaches negative infinity. You should be able to use any function of the following form, f(x) = 1 + x^n where x = player_level - monster_level, and n is a natural number AND n is odd. This will give you an odd function which meets your criteria.

Graph these functions to see if they meet your requirements, f(x) = 1 + x^3, f(x) = 1 + x^5, and f(x) = 1 + x^9.