First off, is the existing set of systems salvageable? To some degree, sure. The AI's tolerable, although the tactical AI is in dire need of work; the physics interactions and the way the animations are coded for weapon sets is largely inviolate, or difficult to modify- so much of how things work this time pretty has to stay in place, in part because, under the hood, Bannerlord's a sprawling mess. But... how about the core, where things happen that annoyed me from the start? No; the core can be gutted and refurbished by reflection, replacing a single method.
So, in between remastering weapons, the new damage code got built. How damage works is pretty important, if I want to make things feel better; this simply wasn't going to get fixed with a few stat changes here and there.
The code actually
simulates things. This was the starting-place. A proper simulation needs to account for the real-world things that happen when people hit each other with primitive weapons, whether missile, blade or blunt object, in a coherent way, and produce statistically-valid representations of what happens- in this case, what happens when people are fighting with medieval-era weapons while wearing anything from, "basically naked" to 16th-century plate-and-maille.
It can't possibly cover
everything, in infinite detail, and it should be designed to run at least as well as Bannerlord's native code in terms of speed, but I wanted a system that felt more real than TW's, where I think a bunch of things went wrong, mainly having to do with their apparent obsession with treating Multiplayer balance as the core of weapon balance, rather than the Singleplayer experience, which is what the vast majority of people will ever see. I think this is an egregious failure to understand game design; these simply aren't the same things, and the needs are different. MP players
might need a hitpoint-based, static representation of damage that has a relatively-high Time To Kill system- that's certainly one way to balance it, and as I'm not writing this code for MP, I'll presume it was judged "good enough" by testers. Singleplayer needs a much grittier system that feels grounded in reality.
So, single-player is my focus. I don't think the current system of balance works well at all there. It's a matter of both practical outcomes and feel. Armor feels weak and relatively badly-simulated; weapon capabilities are all over the map, from weapons that should be able to kill most targets (regardless of their armor) in one or two hits, that are loosely based on historical weapons... and weapons that are pretty much identical, in terms of their real-world effects, that do less than half as much damage. It's all over the place, frankly. Most of the expensive weapons are meant for players; that's sensible. But there are exceptions (the falx, for example) and whatever was going on here doesn't feel systematic or thought-out.
So, without revealing all of my code for this just yet... here's basically how it works. Let me also remark that it's much shorter, less mathematically complex, and will run better when scaled, as well as being copiously documented, should anybody want to use it or extend it in the future.
Damage for weapons is what it says on the tin and is realistically based. Damage, before the systems below interact, is the weapon's listed damage, +/- 25%, +/- some character stats, depending on the weapon type.
If you swing a sword at someone, and the sword does 40 damage, if the target's naked, then an unskilled attacker does between 30 and 50 damage, subject to further rules outlined below.
This is a radical change right from the start; Bannerlord attempted a fairly weird use of "physics" and was trying to deal with mass and rotational velocities, etc., etc. None of it works right. Just because I took a step backwards, my damage output shouldn't drop from 40 to 4. IDK how much of that was intentional (nerfing kiting for MP) and how much of it was just bad QA. Whatever, all of that stuff is gone, saving quite a lot of complicated computation that wasn't working well and served no fundamental purpose in the game design, other than, "we can claim our game is 'physics-based'".
Why this basic rule? Well, because that's the first step towards good simulation; building the ideal, best-case, nothing-weird-happened scenario.
Another example: if I shoot a naked guy in the face with a hunting bow and arrow designed to bring down a deer... I kind of expect that guy is not getting back up, let alone charging me like some sort of Medieval Zombie.
But that's exactly how Native's game design works; worse, it does this in the most awkwardly unintuitive ways imaginable.
Just because my target's 25 meters away, what I'm doing to the target doesn't magically drop by nearly 50%; that's just not how things work in the real world, where things like air friction aren't doing a whole lot to the effect of an arrow for a lot longer away than that (and as a historical matter, we now know that archers, crossbowmen and even javelins were going a
lot further and faster than we used to; for example, a typical war bow was pushing 65 m/s and could hit point targets reliably at 200m+, mass targets at roughly 300m; Asian recurve bows firing lighter arrows went even further).
All of this awkward stuff was done to "balance multi-player", I think. The signs are everywhere; in TW's patch notes and in the things they cared about in the code. This obsession with MP is, imo at least, a classic example of the squeaky wheel getting greased the most, but it's a bad business decision; if SP
felt better, it'd drive more sales than the teeny number of people playing the game online.
There's an unhealthy obsession with preventing archers from being dominant, for example; there are weird niche nerfs in the physics interpretation of hits, etc., that are pointless otherwise. All of that is gone now.
Damage for horse tramples is accurately simulated. Being a human run over by a horse
sucks. A typical horse weighs twice as much as a motorcycle. Sure, they're moving more slowly, but that's a lot of mass!
So... uh... tiny little "bumps" that do very little damage, no, that's not how it worked. I really don't understand TW's code in this area; they were doing some fairly complicated math to, uh, keep the damage roughly between the bounds of the listed damage and
zero. This is why hitting people on horseback at high speed doesn't make any sense, and feels rather unsatisfying.
In my new system, horse tramples work like this: at anything below 5 m/s, horses do zero damage (but may bump). This represents, "target can probably get mostly out of the way". Anything above that speed, it's Max(1,base damage of the horse * the velocity - 5).
So a horse with a listed damage of 20 moving at 10 m/s does 100 Blunt damage; at top speeds, it's an instant kill on an unarmored target. This makes horses hitting unarmored people at high speeds quite lethal, which is realistic and gives the player a good reason to gather their cavalry around them and charge into infantry formations; done right, it can take out dozens of troops in a single pass, just like the real world.
However...
Damage for Pointy Things At High Velocities is simulated. Like horse tramples, running into pointy sticks at high speeds is an entirely different proposition than merely being stabbed at by some Sturgian with a grudge. Spears and lances can inflict
catastrophic levels of damage at high velocities, just like in the real world.
This goes both ways. Horses and their riders can be insta-gibbed by running up on pikes or spears at high speeds. It feels quite risky trying to trample infantry with spears now; you might get lucky and go through them, you might suddenly be unhorsed and surrounded by guys with pointy things.
Weirdly, this was
kind of handled by TW's original code, but, in my opinion, it wasn't working very well, and it involved more vector math.
Base Skills can directly impact damage. Are you particularly skilled with a weapon? You're more likely to hurt somebody. It's not as huge of a thing as you'd think, though. IRL, what a skilled person is more likely to do is
hit the target. You can be a 250-lb blob of lard and hit somebody really hard with a club; you can be a 100-lb woman and be more likely to get in the first blow, or just able to dodge really well. To simulate this, depending on the type of attack, physical skills can boost damage a bit.
There's also, "how tough are you". In the real world, people who practice a lot get good at taking hits. It doesn't make it all go away, but every little bit helps. Certain Skills contribute to this, and it effectively gives a high-skill player a bit more Armor.
Lastly, people also get really good at dodging and weaving and avoiding getting hit in the first place; there is now a Dodge roll that can avoid damage entirely. This uses the largely-useless Roguery skill... and dodging successfully can give Heroes some XP towards increasing it!
Luck matters. In the real world, weapons do weird things when they interact with people in combat. Against naked people, weapons generally do what they're supposed to, but even then, weird things happen- your spear scrapes a rib but fails to penetrate, or you got super-lucky and pierced their orbital socket- lights out! When we start adding in armor, things get even more complicated. Sometimes your speartip slides off a breastplate like it should; sometimes it's channeled into the soft area under the armpit. There's no such thing as armor that has no weak spots, or a warrior so skilled that every hit is fatal.
That's reality, so it has to be in the simulation. How? Critical hits and fumbles. Crits cause more damage; fumbles ruin the attack. Certain types of players will hate this (seriously, I got tired of dealing with people complaining about luck-based rules in Blood and Steel, lol) but it's reality; combat involves some luck.
Auto-Parry is Implemented. What's "auto-parry"? It's a non-zero chance that, if an Agent's in a blocking animation state, they're able to successfully parry an attack. This is a better simulation of the real world, where I may be chambered to the left, but I can very quickly change guard IRL and block attacks. It's not a 100% chance to block, but it's high enough that, unlike Blood and Steel, players will sometimes want to counter and riposte. Obviously, this won't work against crush-through attacks, but it will work against high-speed pointy things, because yes, you can redirect those, sometimes.
This fixes one of my biggest gripes with Bannerlord, where for some odd reason they took away keyboard parries and directional attacks; combat feels even more randomly spammy than it was before in SP, where you're often fighting multiple AI troops by yourself. Yes, I know, there is probably a way to get there, too- I could probably record keystrokes and fix this for the player, sort of. But this way fixes things for the AI and player in a way that's straightforward.
Armor and damage values interact strongly and properly. I was inspired to begin this crazy journey largely by several posts about this topic on these Forums and elsewhere shortly after I started playing and seeing how Bannerlord felt.
It's a simple system, with a simple rationale. Medieval armor
worked. We have lots of good, reasonably-scientific recreations and other forms of evidence to support this. Even wearing a gambeson without maille made the wearer considerably harder to hurt, especially with lighter missiles. Late-medieval plate-and-maille was good against massive balls of (relatively) low-velocity lead shot, and it just about ignored slashing attacks, axes, and other obsolescent weapons. So, as we know from multiple sources, thrusting weapons like estocs and halberds and kinetic-energy weapons designed to concentrate force on very small surfaces areas like late-medieval maces and war hammers became the norm. This all ends when muskets finally started achieving rates of reliability and penetration that simply made armor impractical, as well as ridiculously expensive. We know all this stuff... so the game should actually reflect that.
TaleWorlds apparently explained at some point how they'd made armor not work largely for multi-player balance reasons. Again, this wasn't good for their game design for SP. Moreover, I'm not even sure it was good for MP; surely you can build a decent class-based medieval warfare game where armor is a significant part of gameplay and class balance, rather than making it feel rather ceremonial.
Armor in the new system ranges in values from 1 (thin weak cloth, basically naked) to 100 (16th-Century plate-and-maille).
Different damage types interact with this armor in radically different ways. Because this post is already reaching Epic Length... here's the actual code for that part; seeing the math and examples is useful.
C#:
//Base armor effects.
//Example: 120 Cut vs. 0 Armor (naked)
//120 * 1(armorReduction) = 120;
//120 - 0(armorAbsorption) = 120;
//Example: 65 Pierce vs. 100 Armor(full plate and maille)
//65 * 0.3(armorReduction) = 19.5;
//19.5 - 2.5(armorAbsorption) = 17;
//Example: 120 Blunt vs. 50 Armor(low-end maille)
//120 * 0.1(armorReduction) = 12
//12 - 6.25(armorAbsorbtion) = 5.75
//Example: 180 Cut (high-end bow, cutting arrow type) vs. 100 Armor(full plate and maille)
//180 * 0.075 = 13.5
//13.5 - 10 = 3.5
float armorReduction = MathF.Min(1f, 7.5f / armorEffectiveness);
float armorAbsorption = armorEffectiveness * 0.1f;
switch (damageType)
{
case DamageTypes.Cut:
break;
//Much less resistance and absorption vs. Pierce!
case DamageTypes.Pierce:
armorReduction = MathF.Min(1f, armorReduction * 4f);
armorAbsorption *= 0.25f;
break;
//Blunt is absorbed to a much greater rate.
case DamageTypes.Blunt:
armorAbsorption *= 1.25f;
break;
default:
armorAbsorption = 0f;
armorReduction = 1f;
break;
}
float finalDamage = MathF.Max(0f, (damage * armorReduction) - armorAbsorption);
Health is treated more like stamina. Basically, in the real world... you have two types of injury on the battlefield. One is something pretty major and immediately life-threatening; the other is death-by-a-thousand-cuts stuff, where any given small injury- a bruise here, a minor wound there- is not that big of a deal, but too many of those and the shock alone will make you combat-ineffective.
This is simulated in a basic way; health regenerates over time. I may implement a "bleeding out" system at some point, but generally I think this system works pretty well. Players can't game the system; the AI regenerates just like they do. As the examples of the final damage formula should indicate, a solitary knight in 16th-century plate surrounded by peasants can still be killed... but it's going to be a rough day for the peasants. This is pretty much how it worked IRL, too.