0
\$\begingroup\$

I've been working on a program for my friends to use for a homebrewed roleplay system that we all use for our campaigns that can generate random enemy statlines with certain constraints.

The program accepts a list of the statlines of the players, and then the user inputs a number that denotes a percentage of the player characters that this unit can beat on average in a 1v1. The issue I'm struggling with here is that combat involves different formulas for determining hit rate, critical hit rate, and damage

The formulas I have to deal with are:

Physical damage: strength - enemy defense = damage (multiplied by 2 if user's speed is 5 greater than enemy's)

Magical damage: magic - enemy resistance = damage (multiplied by 2 if user's speed is 5 greater than enemy's)

Hit rate: base hit + floor(user dex/3) + floor(user luck/5) - enemy dodge rate = hit rate (will always have a minimum of 5%)

Dodge rate: base dodge + floor(user speed/4) * 2 + floor(user luck/5) = dodge

Critical hit rate: 5% + floor((user dex - enemy luck)/5) + crit bonus = critical hit rate

(hit system is based on singular d20 with critical hit rate equivalent to number range on d20 that's considered a critical hit, meaning a 5% hit chance with a 5% or greater critical hit rate will result in every hit being a critical hit)

I've been struggling to think of an algorithm that can generate enemy statlines based on these formulas as well as the percentage constraint but I have no idea how to go about it in a way that isn't just bruteforcing it until I get a desirable outcome. I've toyed around with ideas such as ranking the inputting players based on their damage, survivability, dodge/hit, and determining upper/lower bounds on stats to work with but the issue I have is trying to establish a relationship formula between each stat to make sure that when I tweak one stat, I can change the others accordingly while staying within the user-defined constraints.

EDIT: After some thinking, I did come up with one possible solution, that being first determining the upper and lower bounds for the statline based on player stats, generating a random statline in between those bounds, and then generating tables that determine what effect on player and enemy DPS incrementing/decrementing a stat will have, and using that to precisely tweak enemies. The only issue with this solution is that for very high/diverse player stat values, this can take a long time, as well as figuring out a way to determine which stat to increment/decrement in the algorithm.

\$\endgroup\$
1
  • \$\begingroup\$ The number of statlines a brute force algorithm can attempt in a single second is very large, the brute force solution was probably still the most efficient use of developer time in the year 2000. \$\endgroup\$
    – Foxwarrior
    Apr 19, 2020 at 17:54

1 Answer 1

0
\$\begingroup\$

Here is the expected number of turns needed to be taken in order to defeat an enemy (assuming the enemy isn't fighting back, of course):

U_turns = E_hp / {max(U_strength - E_defense, U_magic - E_resistance) * (U_speed ≥ E_speed + 5 ? 2 : 1) *

max[0.05, U_accuracy + floor(U_luck / 5) + floor(U_dexterity / 3) - E_evasiveness - floor(E_luck / 5) - 2 * floor(E_speed / 4)] *

[1 + (0.05 + floor{[U_dexterity - E_luck] / 5]} + U_crititalBonus)

/ (max[0.05, U_accuracy + floor(U_luck / 5) + floor(U_dexterity / 3) - E_evasiveness - floor(E_luck / 5) - 2 * floor(E_speed / 4)] )]}

You'll probably want the players to on average defeat enemies (on average) fast enough to always have some spare medical supplies (on average, based on however healing works.) The average percentage of HP a player will have after a battle is 1 - U_turns / E_turns.

\$\endgroup\$
3
  • \$\begingroup\$ Establishing the DPS calculations wasn't the issue for me, rather it was figuring out a way to generate enemy stats such that their DPS was high enough to defeat a percentage of the player characters while being survivable enough to survive their attacks on average. \$\endgroup\$
    – lumamaster
    Apr 19, 2020 at 18:52
  • \$\begingroup\$ In other words, you want to generate stats such that 2 < E_turns < 1 / (Percentage of Characters Defeated)? In that case, I would recommend a deterministic brute force (like affixing the enemy's base dodge to a range relative to the player's hit rate, for example). \$\endgroup\$
    – Samurott
    Apr 19, 2020 at 18:58
  • \$\begingroup\$ Kinda, yeah. The main thing I'm aiming for is that E_turns to defeat player <= U_turns to defeat enemy for (percentage) of players. I could try applying that approach to the idea I came up with earlier, perhaps with asking the user for more constraints such as a minimum hitrate the enemy has to have, etc. \$\endgroup\$
    – lumamaster
    Apr 19, 2020 at 19:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .