User:Phol ende wodan/Combat system overhaul

From NetHackWiki
Jump to navigation Jump to search

This is a proposal for an overhaul to NetHack's to-hit, armor, and damage reduction system. The current system originates from early versions of D&D; this is great for D&D players but not great for NetHack game balance. On top of this, there are many adjustments made to the original system - for instance, battles in early D&D are generally several-on-one or several-on-several instead of one-on-thousands, and enchanted gear is rare and hard to come by - but the net effect is to create a crufty system of mechanics that does not work well in the modern game. I believe that the best way to restore balance is by removing the existing system and building up a new one from scratch, instead of trying to change lots of values and algorithms to try and get it right.

This is a work in progress and it should be considered a second draft. All of the primary mechanics are present, though, and I don't expect to edit this much more apart from tweaking numbers and minor rules. Balances are likely off. Please post on the talk page to tell me how something here is wrong.

Draft 1 is here (significantly longer and much bigger scope): User:Phol ende wodan/Combat System Overhaul Draft 1.

Primary goals of the new system

  1. There should be multiple defensive stats: at least one for evasiveness, which influences to-hit, and at least one for damage reduction, which influences only damage. Currently, to-hit and damage are wrapped up in a single character stat: armor class. Bundling both of these mechanics together makes armor less strategic for players (since one should simply get AC as low as possible). It also doesn't reflect real-world combat; it should be easier to whack an enemy wearing heavy plate than one wearing light leather, but it isn't.
  2. Evasiveness, armor index, and armor enchantment should naturally be zero, and improve as they increase. Stats that improve at smaller values, like AC currently does, are counterintuitive. Negative values are valid, but only expected in edge cases such as negative armor enchantment.
  3. A good, if not complete, appraisal of the player's defense ability should be shown at all times on the status bar.
  4. Persistent flat bonuses should either be small or eliminated. Though at the same time, there should not be a bunch of random dice rolls, because high variance isn't good.
  5. Player-monster symmetry should be preserved.. The fact that there is one player fighting a horde of monsters should not affect the actual combat system, and there should be no advantages or disadvantages given exclusively to the player. The proper way to balance one player versus a horde of monsters is to balance monsters and their difficulty appropriately.
  6. The effect of Luck should be severely reduced. It's an bonus awarded only to the player, for one, and it hurts player-monster symmetry if the player has lots of advantages unavailable to monsters. Even doing what some variants implement and using 1d(Luck) seems too powerful - it can be assumed that a midgame character will have maximized their Luck and it will stay high for the rest of the game; 1d(Luck) has a high average of +7 and a high variance which makes it harder to balance. Other uses of Luck should not be influenced by this.
  7. Bonuses and penalties should mostly be continuous functions of their independent variables. Weird step functions are unintuitive, and are found all over the vanilla code (e.g. the amount of HP regenerated is 1 point at Con <= 12 and d(Con) for Con >= 13).
  8. Role variety should be preserved, but role difficulty need not be. Changes should not be made on the consideration that certain roles affected by it are known as easy or hard roles. As long as roles play differently enough, and no role becomes hugely over- or underpowered, preserving vanilla's role difficulty is not particularly important.

Overview

The to-hit formula is in the center of everything. The vanilla version is being thrown out completely, and replaced with a version that uses a normally (bell curve) distributed random variable instead of a d20. In order to hit, the random number must initially beat a 0, but various to-hit bonuses and penalties on the attacker's and defender's side push this target into negative numbers (representing an attacker advantage) or positive numbers (representing a defender advantage).

In the first draft of this proposal, shields contributed directly to evasiveness with their own mechanic for this; now they are merely armor pieces which will happen to have a high proportion of EV.

Monsters' AC is split into two stats which serve independent purposes: evasiveness, or EV, which counts as a to-hit bonus to their defense, and damage reduction, or DR, which reduces damage done on successful hits. Armor's AC stat is likewise split into EV and DR.

May be removed: Monsters can flank hostile monsters, and back them into walls and corners, for a to-hit bonus.

Evasiveness

Evasiveness is an inherent value of a monster form that determines how easy it is to score a hit. It partially replaces monster base AC as a stat. Its natural value is zero, corresponding to AC 10 in vanilla (a naked human with no special skills or bonuses), but unlike AC, it increases as it improves. It should generally correlate with monster difficulty, though outliers might apply in special cases: a gelatinous cube would be less able to evade and so should have a lower evasiveness than a standard monster of its level, while killer bees are very good at evading and so should have higher evasiveness. (Perhaps the speed and size to-hit penalties can be appropriately balanced so that this stat isn't needed, but I don't really think so; I think the ability to tweak and fine-tune these values on a per-monster basis is a good thing.)

To-hit formula

Getting a higher number in this calculation is good for the attacker.

The balance I'm aiming for here requires three things:

  1. A final value of zero (all bonuses and penalties canceling out) should result in an average 50% chance to hit.
  2. An attack should always have a non-zero chance to hit and a non-zero chance to miss.
  3. A small advantage to the attacker means that the attacks will miss a little less than half the time. A large advantage to the attacker means that the attacks will usually hit. A large advantage to the defender means that the attacks will usually miss.

To do this, rather than using a uniform distribution like the 1d20 roll to-hit currently uses, generate a Gaussian random number with mean 0. I don't know what standard deviation should be yet; that will depend on what ends up being a reasonable range of bonuses. A distribution of this shape satisfies the above constraints, and it does so smoothly and continuously.

NetHack is allergic to floating point numbers; this is fine, because Gaussian distributions can be approximated well enough with an average of uniformly distributed random numbers. But if we decide that non-integer quantities are okay at any point, a Gaussian distribution also enables the various bonuses and penalties to meaningfully be non-integer values.

The loose balance goal I'm aiming for is that the player should start off not able to hit quite reliably, and should still not be fully reliable at hitting everything at any point in the game except maybe the very late game. Bosses in particular should offer more challenge. Note that changing from vanilla balance to this to-hit system could be a pretty hard sell - overall, it's a nerf, and players might be loath to play a game where you can't be sure of hitting consistently after dungeon level 20 or so, after years of playing a game where you can.

Another loose balance goal is that in general a good player should be doing better for defense than having all bonuses add up to 0.

Physical to-hit is calculated by subtracting the total attacker bonus from the total defender bonus, and comparing that to a Gaussian-distributed random value. Note that these aggregate "bonuses" might be negative, though not usually. In mathematical terms, a hit is scored if gaussian_rnd(mean=0, stdev=who knows) > (total defender bonus) - (total attacker bonus).

Most of these terms are probably unbalanced. If you care to, please point out exactly how it's unbalanced so I can try to fix it.

Attacker bonus

  • Start at 0.
  • If the attacker is a monster, add (monster level / 4). This proportion is subject to change; ideally, it should be proportional to the defense bonus of players whose roles permit the lowest amount of defense overall.
  • If the attacker is the player, add a dexterity bonus equal to floor((Dex-10)/4). (The player is the only one with a Dex stat).
  • If the attacker is the player, add skill bonuses, including twoweapon penalties if applicable. (The player is the only one with skills.)
  • If the attacker is using a weapon, add that weapon's natural to-hit bonus.
  • If the weapon is an artifact and has a specific bonus versus the defender, add that bonus. (Also counts with artifact launchers firing ammo).
  • If the attacker is firing ammo from a launcher, add the launcher's enchantment.
  • If the attacker is wearing a ring or rings of increase accuracy, add their enchantment. Unlike most other things, this is a flat bonus.
  • Add 1d(Luck/2) for the attacker's Luck.
  • If the attacker is a Monk wearing body armor, subtract 20.
  • If the attacker is mounted, subtract a riding penalty, which is 4 at Unskilled, 2 at Basic, and 0 at Skilled and Expert.
  • If the attacker is engulfed, add 30.
  • If the attack is ranged and the projectile is not actually a projectile, subtract 4, unless it is a boulder, in which case add 4. Despite what your TV tells you, throwing your sword does not work.
  • If the attack is ranged and the projectile is kicked, subtract 3.
  • If the attack is ranged, subtract the distance. (Grid distance, not Euclidean; a monster two squares away diagonally is at a distance of 2.) This applies to spells and wands as well.
  • If the attack is ranged and the attacker is a Ranger, add 1. (Technically not player-specific, applies to Ranger player monsters too).
  • If the attacker is a Samurai firing ya from a yumi, add 1.
  • If the attack is ranged and consists of ammo being thrown or fired from the wrong type of launcher, or with no launcher at all (e.g. arrows from a crossbow), subtract 6.
  • If the attack is melee and the attacker is wielding a non-melee weapon (ammo, launcher, boomerang), subtract 2.
  • Add 1 if the defender cannot see the attacker.
  • Subtract 4 if the attacker is fumbling.
  • Subtract 2 if the attacker is not fumbling but has slippery fingers.
  • Subtract 2 if the attacker is currently stunned.
  • Subtract 1 if the attacker is currently blinded.
  • Subtract 1 if the attacker is currently confused.
  • Subtract 1 if the attacker is currently trapped.
  • Subtract 1 if the attacker is burdened, 3 if stressed, and 5 if strained. (Only applies to the player; monsters don't get encumbered.)
  • Add the flanking bonus. (Using the raw bonus may be too powerful, but maybe not.)

Note that racial to-hit bonuses are absent from this list.

MAY REMOVE THIS: A notable omission from this list is weapon enchantment. Enchantment no longer applies as a to-hit bonus, and is primarily used now for damage (though other calculations involving it like the chance of a projectile breaking are still in use too).

Defender bonus

  • Start at the defender's monster form evasiveness.
  • If the defender has protection (the greater of divine protection and spell protection), add that amount. Note that divine protection is harder to obtain and has a maximum of 6, as described below.
  • Add (2 - defender size). (This is exactly the same as vanilla.)
  • Sum up the defender's EV bonuses from armor, and add them. (This does not count enchantment; enchantment now applies only to damage reduction.)
  • If the defender is a Monk not wearing body armor or a shield and not wielding a weapon, add the defender's martial arts skill minus 2 (for Monks, this is always zero at Basic up to 4 at Grand Master).
  • Add 1d(Luck/2) for the defender's Luck.
  • Add 2 if the attacker cannot see the defender.
  • Subtract 1 if the defender is currently confused.
  • Subtract 2 if the defender is a monster and is fleeing.
  • Subtract 2 if the defender is currently stunned.
  • Subtract 2 if the defender is currently blinded.
  • Subtract 4 if the defender is currently trapped.
  • Subtract 4 if the defender is currently sleeping.
  • Subtract 4 if the defender is currently paralyzed.
  • Subtract 1 if the defender is burdened, 3 if stressed, and 5 if strained. (Only applies to the player; monsters don't get encumbered.)

Other modifications

  • Add 1 if the attacker's weapon is blessed and the defender is a demon or undead.
  • Add 1 if the attacker's weapon is a spear and the defender is kebabable.
  • Add 1 if the attacker's weapon is a trident and the defender is in water.
  • Add 1 if the attacker's weapon is a pick-axe or mattock and the defender is a xorn or earth elemental.

Overriding special cases

  • Gem class objects thrown at a unicorn always "hit" by getting caught.
  • Your quest artifact thrown at your quest leader is always caught, unless they are hostile, sleeping, or paralyzed.

Bonus tables

Skill bonus

Applies to whatever skill the attack is being made with, whether that is melee, ranged, or a spell.

Skill level Bonus
Restricted -4
Unskilled -2
Basic 0
Skilled 2
Expert 4

Twoweapon penalty

Skill level Penalty
Unskilled -6
Basic -4
Skilled -2
Expert 0

Riding penalty

Skill level Penalty
Unskilled -4
Basic -2
Skilled or Expert 0

Monk martial arts defense bonus

Skill level Bonus
Basic 0
Skilled 1
Expert 2
Master 3
Grand Master 4

Damage formula

Evasiveness only helps you avoid getting hit. If you do get hit, it is your AC that determines how much the incoming damage will be reduced. Note that this applies only to physical forms of damage; elemental or magical damage is not reduced.

First, reduce damage if a weapon or projectile is eroded (instead of making a to-hit penalty). Damage will be reduced by 1d(max erosion) - 1 points on each hit. The vanilla damage formula in which erosion counts as a penalty to enchantment no longer considers erosion.

Then moving on to the primary damage reduction mechanic: a monster can hit any one of your armor slots, and the armor you have equipped in that slot is the only armor that will count for damage reduction. The (preliminary) chances of a given attack hitting a given slot are expressed in the table below.

When a slot is chosen, if the user is wearing armor there, damage will be multiplied by a factor of 0.9^(total DR). Armor enchantment counts for +1 DR per point of enchantment.

If you are polymorphed and your polyform has some intrinsic level of damage reduction, your DR is the maximum of DR from your armor and DR from your polyform. (Monsters and armor now have a DR stat in addition to their EV stat, replacing AC, which indicates how resistant their body is to damage.)

If the resulting damage would deal over half of your current HP, some other effect happens which might reduce the amount of damage further (though this may still kill you.)

Slot Chance for an attack to hit High-damage effects
Torso (including shirt) 40% None; it is all taken as damage.
Head 20% Reduce damage by 25% and stun you for 3d2 turns.
Shield 15% Reduce damage by 50%. You stagger backwards and may crash into things.
Gloves 10% Reduce damage by 50% and get wounded arms for 3d2 turns: a condition which severely hurts your to-hit and damage from fighting with your arms, and could also prevent your shield from adding its bonuses.
Boots 10% Reduce damage by 50% and give you wounded legs for 3d2 turns.
Cloak 5% Reduce damage by 25%. Originally this made you drop your cloak but that is probably too evil; it's been suggested that this get merged into the torso attack slot.

Finally, any successful hit must deal at least 1 hit point of damage. If reduction happens to take it below 1, it will always be set to 1.

Changes to other mechanics

  • Divine protection will probably have a smaller cap of about 6, it will be the most expensive thing one can buy from a priest, and it can only be bought one point at a time.
  • Certain monsters like aligned priests and angelic beings may have divine protection.
  • Intelligent monsters will pick up non-cursed luckstones; any monster carrying one will effectively have 3 + 1d3 Luck, and their to-hit will recieve a corresponding bonus. Player monsters will usually generate with a luckstone.
  • Monsters will not make a "weapon" attack against you by swinging a launcher or other non-melee weapon at you, preferring to unwield it and hit you normally.
  • Half physical damage and half spell damage now reduce damage only by 1d(half damage) instead of flat half damage. Their non-damage effects are not changed.
  • A ring of evasiveness or ring of defense, directly increasing to-hit defense bonus, should be added to complement increase accuracy.