Can These Things Be Fixed? <Long>

Users who are viewing this thread

Here's the last of RR_Razor's blunt stuff; at least the things I have here. Curiously, there are missing things; for example, there is rrr_mace1, 3 and 4, but not rrr_mace2. I don't know if that was me or RR_Razor's doing. I still need to do some mace-head variants, but at least this gets the total up to 6. If these feel a little less than perfectly detailed on the stiped bits, have no fear; in-game those will be so small on-screen that it'll look better than it does at maximum zoom. That said, figuring out new ways to stuff in more visual variety has been a real challenge with these maces, which are really, really low-poly.

Had to get this done early today, as the rest of my schedule's wiped due to stuff IRL. I'll probably try and do IgorBB's stuff tonight.

rrr_blunt_BL_02.jpg
 
Last edited:
Got IgorBB's main stuff done.

This happily included a fairly-decent jian sword, so the Chinese stuff's a little more complete. Also a cool Eastern European fighting axe design that really isn't anywhere else.

Had a bad time with his fantasy-weapon mesh. I really should just rework it from start; it's pretty badly optimized and I don't like the skin I painted for it back in the day, even after adjustments for PBR, etc. That's going to have to sit really low on the priority list, though.

igorbb_BL_01.jpg
 
Last edited:
OK, I think I've got enough content done. RR_Razor's swords will be gotten to, along with other things, but I want to start seeing all of this content be playable.

Now it's time to finally talk about game-design considerations, code to support it, and data integration. It's not much of a "fix" if we're not talking about that. This is going to get kind of long and boring, if you're not seriously interested in game development, so it's mostly spoilered.

I've already written and finished testing a fundamental rewrite of the TW damage system- this affects pretty much all aspects of medieval combat. I'll be finally putting up code on GitHub for this stuff sometime next week, before the mod's really playable beyond a rough alpha. Here's roughly what this entails, at least for damage and how weapons interact with armor. This talk involves a fair number of discursions into philosophy of game design- the "why did you do that" as well as the "what are you doing". I think that's helpful for anybody wanting to learn more about this subject.

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.

So that's the major systems of a revised damage code. The code's working and basically feature-complete at this point. What largely needs to start happening is data-entry and unit testing; bringing in all this content and integrating it with the design goals and working code.

Which brings us to the other big problem: data. To make this work properly, it's time to do some major rework, and put all these assets into the game, getting rid of the "forged" stuff, revamping armor values, etc.

This is a bit challenging. Taleworlds set up almost all of the melee weapons to use the forging system, and it's resulted in bizarrely over-complicated data sets. I really can't emphasize enough what a mess this is, under the hood. I'm zero surprised that there are so few new weapons out there in mods. But I need to get 300+ weapons (probably rising to nearly 400 by the time I'm done) into the game, so it's not going to be an option to just sit around crying about it.

Luckily, Taleworlds left me one breadcrumb to break this system down into its essential components- the Torch:

<Item
id="torch"
name="{=ErOLa263}Torch"
is_merchandise="false"
body_name="bo_mace_a"
recalculate_body="true"
mesh="torch_g"
prefab="torch_a_wm_only_flame"
culture="Culture.empire"
value="4"
weight="0.2"
Type="OneHandedWeapon"
item_holsters="abdomen_left">
<ItemComponent>
<Weapon
weapon_class="OneHandedAxe"
weapon_balance="100"
thrust_speed="78"
speed_rating="97"
missile_speed="0"
weapon_length="65"
swing_damage="6"
swing_damage_type="Blunt"
item_usage="torch"
physics_material="metal_weapon">
<WeaponFlags
MeleeWeapon="true" />
</Weapon>
</ItemComponent>
<Flags
DropOnWeaponChange="true"
ForceAttachOffHandPrimaryItemBone="true"
HeldInOffHand="true"
HasToBeHeldUp="true" />
</Item>

The Torch is not really a "weapon", in the sense that you can whack people with it. But it showed me that weapons that weren't "forged" and weren't missile weapons were totally possible.

From there, I figured out how to get Grom (the fantasy axe I designed long ago) into the game:
mackie_weapons_in_BL02.png

Grom worked just fine. It showed up in shops, it whacked people, the whole bit. I wasn't just showing off that I could get an art asset working there; if this hadn't been feasible, I'd have stopped the project right then.

Grom's XML is like this:
<Item
id="xeno_grom"
name="Grom's Axe"
is_merchandise="true"
body_name="bo_axe_short"
recalculate_body="true"
mesh="xeno_grom"
culture="Culture.sturgia"
value="1000"
weight="1.5"
difficulty="0"
appearance="0.5"
Type="OneHandedWeapon"
item_holsters="axe_right_hip:axe_right_hip_2:mace_right_hip:axe_back"
>

<ItemComponent>
<Weapon
weapon_class="OneHandedAxe"
weapon_balance="100"
thrust_speed="100"
speed_rating="135"
missile_speed="0"
weapon_length="48"
swing_damage="140"
swing_damage_type="Cut"
thrust_damage="60"
thrust_damage_type="Cut"
modifier_group="axe"
physics_material="metal_weapon"
item_usage="onehanded_shield_axe"
>
<WeaponFlags
MeleeWeapon="true"
BonusAgainstShield="true"
/>
</Weapon>
</ItemComponent>
<Flags
QuickFadeOut="true"
/>
</Item>

So, let's talk about all that stuff for a moment... and then I'm going to get back to the rest of my day, followed up by doing the data-entry necessary to get everything into the game.

Most of what's in that XML is (fairly) self-explanatory. There are a few things that were quite annoying and (imo, at least) involved a lot of needless duplication of data.

First off, the top-line stuff in an Item entry:

id: unique hash-table id, stored as string, can be retrieved.
name: TextObject reference; allows for localization of the weapon's name.
is_merchandise: boolean value, referenced by economic code I haven't looked at much yet.
body_name: a reference to the Collision Body being used. All Collision Bodies use "bo_NameOfBody" in the Editor, but I think that's a naming convention, not a hard requirement. Note: does not need a relative path, etc.- the game handles that.
recalculate_body: a boolean. I believe this makes the weapon automatically scale the collision body referenced along the Y axis upon instantiation. Whether it uses the weapon_length value or the bounds in the 3D mesh hasn't been determined, but I'm guessing the former rather than the latter, for control over weapon lengths vs. what it looks like graphically.
mesh: a string for the weapon's name in the Editor. This is whatever the Geo data's named, which is usually pulled from the first entry in the FBX, minus anything after a trailing period. I.E., if your first entry in your FBX's hierarchy is Foo.1, the Geo gets named Foo.
culture: This is a reference to the Cultures, designating which Culture will generate the item as merchandise, if any. I'm not sure what happens if this is left as ""- possibly, this means "all Cultures" or it breaks the game. I haven't tested it yet. Items like Butter have no value for this, which strongly suggests it's not required.
value: Roughly, price of item in a shop. Roughly, because this is impacted by the player's Merchant skill.
weight: weight, in kilograms. This is required.
difficulty: how much of the <relevant skill> is necessary before using <item>. This is non-mandatory, and I'm setting all of that to zero.
appearance: this is a non-mandatory value, probably used for Civilian Armor to determine whether the player looks "rich" or not. I haven't hunted that down yet.
Type: this is the first of several confusing references to the type of weapon. In this case, it's the major sorting category for the Inventory and Shop.
item_holster: this is where the weapon will be shown on a character when holstered. Note that it can use combinations of values; this is probably true of things like culture as well, but again, haven't tested that yet.
default_item_holster_position_offset: basically, moves the weapon relative to the item_holster position (defined in another XML) in XYZ. Z is "along the shaft of the weapon", generally.
use_weapon_as_holster_mesh: does this weapon have a holster mesh? If no and it can be shown at all (deleting item_holster makes it no longer appear anywhere) then it can use that holster mesh. I still don't really understand how that works, but I can tell you right now that it involves the "forging" system; in "forged" weapons, it specifies which part of a multi-part weapon to hide if holstered. So I'll have to leave this value as "true" until I fully understand that, or just not bother showing weapons holstered at all.

Now, inside the Item entry, we have an ItemComponent. Inside that, for whatever confusing reasons, we have a Weapon, WeaponFlags and ItemFlags.

weapon_class: this value is the weapon's class when striking a target (see: WeaponClass in Taleworlds.Core).
weapon_balance: this is a value that's used internally by Bannerlord's code to determine how quickly a character goes from "unbalanced" to "balanced" states. Since my new code ignores this, all it's getting set to 100.
thrust_speed: if a weapon is capable of thrusting, this is the speed value, as a percentage, that the animation is sped up.
speed_rating: basically, how quickly does the weapon do all ready, release and recovery animations.
missile_speed: if the weapon may be used as a Missile, how fast does the missile go, in meters / second.
weapon_length: weapon's hitbox length, in centimeters.
swing_damage: how much raw damage does the weapon do, if swung.
swing_damage_type: what DamageType to use. Valid values here are "Blunt, Cut, Pierce, Other". "Other" is basically the catch-all for drowning, falling off of things, etc., etc. and Bannerlord's damage system (and mine, at present) convert this into Blunt damage.
thrust_damage: if the weapon can be used in a thrusting attack, how much raw damage it does.
thrust_damage_type: see swing_damage_type, above.
modifier_group: this has to do with WeaponModifiers- whether it can be "chipped" or "masterwork", etc. with teensy changes to stats. I'm getting rid of that, but there's how to mess with that. Why that isn't tied directly to weapon_class is one of many mysteries.
physics_material: now this is interesting. Taleworlds' code refers to the CollisionObjects and their physics materials, which is defined in Collision Bodies (see above), and then attempts to do things with weapons based on whether a given part is wood or metal. I suspect that physics_material: overrides that. For now, I'm making all of them "metal_weapon".
item_usage: this is where the weapon's animation states and a whole bunch of other important things are controlled. Whether the weapon can be used with a shield, for example. See Native's item_usage_sets.xml. The whole system is a bit of a mess, but I'm going to have to figure this out if I want to do any weapons with custom behaviors. Sadly, there isn't a Pistol or Musket set defined here, as in the olden days, so if I want functional firearms, I'll have to figure this out.

Lastly, we have WeaponFlags. This is a bunch of booleans that govern weapon behaviors, essentially. This touches many areas of Bannerlord's code. Many of these flags are missile-specific, but weapons with the Flag set appear to override the missile values.

AffectsArea: does damage to an area. Used for siege weapons. I haven't looked at the specific range in meters yet.
AffectsAreaBig: does damage to an area, but larger. Used for siege weapons. I haven't looked at the specific range in meters yet.
AmmoBreakOnBounceBackMask: sets flags AmmoBreaksOnBounceBack and AmmoCanBreakOnBounceBack to true.
AmmoBreaksOnBounceBack: whether the ammo involved breaks when it hits something it can't damage (ground, trees, etc.).
AmmoCanBreakOnBounceBack: sets up a chance (how big, I don't know yet) the ammo breaks, but not always.
AmmoSticksWhenShot: whether the ammo sticks into the target or not, attaching itself to the Agent or damage-able object involved.
AttachAmmoToVisual: I think this is whether said sticking ammo is shown visually or not. It's confusing that there are two values involved here.
AutoReload: does the weapon automatically start the reloading process after being fired. Should be set to true for missile weapons.
BonusAgainstShield: does the weapon do extra damage to shields- axes and halberds, etc.?
Burning: a flag that specifies if a weapon is "burning". Could be useful for doing various Damage Over Time systems.
CanBlockRanged: whether or not the weapon's hitbox gets checked vs. missiles, and if so, whether it gets handled. This is performance-heavy, and I'm largely leaving this turned off.
CanCrushThrough: can this weapon "crush through" a blocking state? Reserved for unusually-massive weapons like Mauls. I'll be using it for a few silly fantasy things as well.
CanDismount: can cause Agents to be instantly dismounted. My damage system doesn't currently handle this flag, as it seems like it'll cause more problems than it solves. If I want an Agent dismounted, then I should kill their mount. But it's there- maybe I'll use it for bolas or something.
CanHook: I think this is meant for weapons that can hook a shield, pulling it out of place. I couldn't find a place where it's actually used, but I'll try and find a reference. I'm ignoring it for now.
CanKnockDown: whether the weapon is capable of knocking down a target. Again, reserved for unusually-heavy weapons.
CanPenetrateShield: whether a weapon can ignore a shield entirely or partially.
CantReloadOnHorseback: missile-weapon specific, and does what it says... except when it's a Hero and they have a special Perk that allows it anyhow.
Consumable: used for Ammo items. Whether it gets used up or not. Honestly, I'm thinking that I may experiment with just turning this off; in Blood and Steel, there was a special ammo-reload item players could buy, that effectively made this issue moot, and frankly, ammo limits are kind of a drag, because either they don't matter at all, or they're massively important; I'd rather control the "using a bow or not" issue pretty directly through inventory manipulations.
DataValueMask: I don't know what this does yet. Pretty sure this is for ancillary values.
FirearmAmmo: why this is separated, I'm not sure, but it is.
HandUsageMask: this looks like maybe it'd allow overrides of item_usage flags, but I can't find an example of it anywhere in Native's data.
Has HitPoints: whether this weapon has hitpoints that can be reduced by other events. I may or may not use this, if I want to simulate polearms breaking.
HasString: used by missile weapons where there's a draw animation (i.e., bows, crossbows). Probably triggers the appropriate mesh animations.
LeavesTrail: missile makes "fire" trail of particles, apparently.
MeleeWeapon: lets game know this weapon's being used in melee, and can potentially block other melee weapons.
MissileWithPhysics: weapon may impart physics forces on a target when it hits. Only used by the Boulder siege weapon.
MultiplePenetration: whether weapon can penetrate multiple targets or not. Used by siege weapons; potentially useful for unusually-heavy melee weapons
NoBlood: for weapons that somehow cause damage, but no bleeding. I'm not planning on using this.
NotUsableWithOneHand: this covers things like bows and crossbows, where they cannot be aimed / shot with just one hand.
NotUsableWithTwoHand: this is for shields, forbidding them from being combined with two-handed weapons.
PenaltyWithShield: this weapon does less damage if used with a shield. I'm going to experiment with that and spears, but it's probably of dubious value.
RangedWeapon: this flag lets the AI know that it needs to do target leading, etc. and see how far the weapon's range is.
StringHeldByHand: used by bows, to let the animation system know how to handle the ready state.
TwoHandIdleOnMount: for weapons that would awkwardly clip through mounts if held in their default idle states. I think this overrides item_usage.
UnloadWhenSheathed: if the weapon has reached the "loaded" state, is that reset to zero when the weapon is sheathed? Generally should be true, unless you want to simulate Early Modern Firearms.
UseHandAsThrowBase: whether or not to use the hand's location for whether the projectile shows up when it's thrown. I'm not sure why we wouldn't want this to be true for a thrown weapon, but it's there.
WeaponMask: I presume this is used internally as a bitmask for weapon-related values? Not sure yet.
WideGrip: whether or not to use the "wide grip" setting. So far as I can tell, this is meant largely as a damage flag for certain situations, and has no effect on animations.


Last, but not least, there are Item Flags.

AttachmentMask: a bitmask of the various special bone attachment types, detailed below.
CanBePickedUpFromCorpse: can the player pick the weapon up after an Agent dies?
CannotBePickedUp: can this weapon be picked up at all? AI uses this to determine if it can recover thrown spears, etc.
Civilian: can be used in a "civilian" setting. For weapons, this is generally used for small daggers, hand-axes, throwing daggers, etc.
DoesNotHideChest: for armors, where it doesn't hide the upper bodies, apparently. I don't understand why this is a thing, when the Armors already have the covers_body flag, but there it is. Maybe... that's the secret sauce I was looking for earlier, regarding flesh color???
DoNotScaleBodyAccordingToWeaponLength: for melee weapons; overrides auto-scaling of the collision body. Unsure why this is a thing, but it's used for the one staff weapon.
DropOnAnyAction: essentially, "you cannot hold this, period"; even if a Player manages to "pick up" the item, it immediately leave the Inventory.
DropOnWeaponChange: if it's in the inventory and the Agent switches weapons, it's dropped. Used for siege weapons.
ForceAttachOffHandPrimaryItemBone: doesn't allow this to be in the primary hand. Only used for ammo items.
ForceAttachOffHandSecondaryItemBone: used to force item to be attached to the bone item2. Used only for shields.
HasToBeHeldUp: used for the Torch and Banners, forcing the Agent to use a special animation for that arm.
HeldInOffHand: like it sounds like, it forces the weapon into the off hand. Used mainly by shields and the Torch.
NotStackable: will not stack in Inventory. Used for weapon crafting pieces.
NotUsableByFemale: if isFemale (a boolean tag in Monster) is true, don't allow this to be used. I'm going to be using this quite a lot on Armors later on. Not used on Native's stuff; you can cross-dress all you wanna, with often-disastrous-results, visually.
NotUsableByMale: same but male. Ditto.
QuickFadeOut: once this item (generally, a missile) hits something, does it go away very quickly?
UseTeamColor: allows for the team-color overlay systems to operate, or not.
WoodenAttack: generates wood hit sounds, can be used to adjust damage.
WoodenParry: deals with parrying sounds and potentially could be used for "axe parried by spear shaft" simulations, one supposes.


Wheeeeee.

Why this stuff isn't well-documented officially yet (seriously, half this stuff isn't even listed) is beyond me. But now you all have a reference.
 
Last edited:
Lastly, to get all this working properly, we need to talk about another major issue: how weapon animations are integrated. It's a mess, lol!

Basically, this is all defined by the serialized value in item_usage, as delineated in item_usage_sets.xml. I presume that this file can be added to and modified, but I haven't gotten there yet.

What does a given value there entail? Well, let's look at Grom's axe, where it has a value of "onehanded_shield_axe". If we look that up in item_usage_sets.xml, we find:

XML:
<item_usage_set
        id="onehanded_shield_axe"
        switch_to_alternate_action="act_switch_back_alternate_axe"
        switch_to_alternate_action_left_stance="act_switch_back_alternate_axe_left_stance"
        base_set="onehanded_block_shield_swing"></item_usage_set>

This, in turn, references "onehanded_block_shield_swing" via base_set:

XML:
<item_usage_set
        id="onehanded_block_shield_swing"
        switch_to_alternate_action="act_switch_back_alternate_knife"
        switch_to_alternate_action_left_stance="act_switch_back_alternate_knife_left_stance"
        base_set="onehanded_shield_swing">
        <usages>
            <usage
                style="defend_up"
                defend_action="act_defend_up_1h_passive"
                defend_active_action="act_defend_up_1h_active"
                defend_parry_light_action="act_defend_up_1h_parry_light"
                is_mounted="False"
                require_free_left_hand="False"
                begin_hand_position="0.3,0.25,0.4"
                begin_hand_rotation="-90,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_up"
                defend_action="act_defend_up_1h_passive"
                defend_active_action="act_defend_up_1h_active"
                defend_parry_light_action="act_defend_up_1h_parry_light"
                is_mounted="True"
                require_free_left_hand="False"
                begin_hand_position="0.3,0.25,0.4"
                begin_hand_rotation="-90,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_up"
                defend_action="act_defend_up_1h_passive_left_stance"
                defend_active_action="act_defend_up_1h_active_left_stance"
                defend_parry_light_action="act_defend_up_1h_parry_light_left_stance"
                is_mounted="False"
                require_free_left_hand="False"
                is_left_stance="True"
                begin_hand_position="0.3,0.25,0.4"
                begin_hand_rotation="-90,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_down"
                defend_action="act_defend_forward_1h_passive"
                defend_active_action="act_defend_forward_1h_active"
                defend_parry_light_action="act_defend_forward_1h_parry_light"
                is_mounted="False"
                require_free_left_hand="False"
                begin_hand_position="0.3,0.25,-0.4"
                begin_hand_rotation="-90,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_down"
                defend_action="act_defend_forward_1h_passive"
                defend_active_action="act_defend_forward_1h_active"
                defend_parry_light_action="act_defend_forward_1h_parry_light"
                is_mounted="True"
                require_free_left_hand="False"
                begin_hand_position="0.3,0.25,-0.4"
                begin_hand_rotation="-90,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_down"
                defend_action="act_defend_forward_1h_passive_left_stance"
                defend_active_action="act_defend_forward_1h_active_left_stance"
                defend_parry_light_action="act_defend_forward_1h_parry_light_left_stance"
                is_mounted="False"
                require_free_left_hand="False"
                is_left_stance="True"
                begin_hand_position="0.3,0.25,-0.4"
                begin_hand_rotation="-90,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_left"
                defend_action="act_defend_left_1h_passive"
                defend_active_action="act_defend_left_1h_active"
                defend_parry_light_action="act_defend_left_1h_parry_light"
                is_mounted="False"
                require_free_left_hand="False"
                begin_hand_position="-0.4,0.25,0.0"
                begin_hand_rotation="0,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_left"
                defend_action="act_defend_left_1h_passive"
                defend_active_action="act_defend_left_1h_active"
                defend_parry_light_action="act_defend_left_1h_parry_light"
                is_mounted="True"
                require_free_left_hand="False"
                begin_hand_position="-0.4,0.25,0.0"
                begin_hand_rotation="0,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_left"
                defend_action="act_defend_left_1h_passive_left_stance"
                defend_active_action="act_defend_left_1h_active_left_stance"
                defend_parry_light_action="act_defend_left_1h_parry_light_left_stance"
                is_mounted="False"
                require_free_left_hand="False"
                is_left_stance="True"
                begin_hand_position="-0.4,0.25,0.0"
                begin_hand_rotation="0,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_right"
                defend_action="act_defend_right_1h_passive"
                defend_active_action="act_defend_right_1h_active"
                defend_parry_light_action="act_defend_right_1h_parry_light"
                is_mounted="False"
                require_free_left_hand="False"
                begin_hand_position="0.4,0.25,0.0"
                begin_hand_rotation="0,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_right"
                defend_action="act_defend_right_1h_passive"
                defend_active_action="act_defend_right_1h_active"
                defend_parry_light_action="act_defend_right_1h_parry_light"
                is_mounted="True"
                require_free_left_hand="False"
                begin_hand_position="0.4,0.25,0.0"
                begin_hand_rotation="0,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
            <usage
                style="defend_right"
                defend_action="act_defend_right_1h_passive_left_stance"
                defend_active_action="act_defend_right_1h_active_left_stance"
                defend_parry_light_action="act_defend_right_1h_parry_light_left_stance"
                is_mounted="False"
                require_free_left_hand="False"
                is_left_stance="True"
                begin_hand_position="0.4,0.25,0.0"
                begin_hand_rotation="0,0"
                begin_arm_rotation="0,0"
                begin_arm_length="0" />
        </usages>
    </item_usage_set>

Which refers back to "onehanded_shield_swing":

XML:
item_usage_set
        id="onehanded_shield_swing"
        switch_to_alternate_action="act_switch_back_alternate_knife"
        switch_to_alternate_action_left_stance="act_switch_back_alternate_knife_left_stance"
        equip_sound="event:/mission/combat/equip/sword_equip"
        unequip_sound="event:/mission/combat/equip/sword_unequip">
...This goes on so long that I hit the character limit for a Forum post, lol.

This doesn't have a base_set defined, and is the "root" that all this other stuff inherits from. To develop new animation sets is going to be a little more complicated than it was in Warband.
 
Last edited:
I have most of the major weapon template types working. Still need to do Basic Two-Handed Stuff, One-Handed Spears, Two-Handed Spears, and maybe figure out the "braced" and couching stuff. I've also tested whether I can effectively remove items from circulation by making them non-merchandise; it doesn't crash, so I think it'll work, but I won't know until I've done that to all of the CraftedItem entries.

Figuring throwing axes out was fun. I'm hoping throwing spears are just a minor alteration of this.

Only problem remaining is that it has infinite ammo for some odd reason. I'm not sure I care enough to keep messing with XML values and enduring crashes until I find the secret combination; ammo with throwing weapons was always kind of a pointless feature because of the super-short ranges. But otherwise, it works.

XML:
<Item
        id="dejawolf_einhendi_hedmarkrox"
        name="Nord Throwing Axe"
        is_merchandise="true"
        body_name="bo_axe_short"
        recalculate_body="true"
        mesh="dejawolf_einhendi_hedmarkrox"
        culture="Culture.sturgia"
        value="500"
        weight="1.5"
        difficulty="0"
        appearance="0.5"       
        Type="Thrown"
        item_holsters="throwing_axe:throwing_axe_2"
        >
      
        <ItemComponent>
            <Weapon
                ammo_class="ThrowingAxe"
                weapon_class="ThrowingAxe"
                stack_amount="8"
                weapon_balance="100"
                thrust_speed="100"
                speed_rating="100"
                accuracy="150"
                missile_speed="30"
                weapon_length="45"
                swing_damage="60"
                swing_damage_type="Cut"
                thrust_damage="60"
                thrust_damage_type="Cut"               
                modifier_group="throwing"
                physics_material="metal_weapon"
                item_usage="throwing_axe"
                passby_sound_code="event:/mission/combat/missile/passby"
                rotation_speed="0, -3.0, 0"
                sticking_position="0,-0.4,0"
                sticking_rotation="90,135,90"
                >
                <WeaponFlags
                    AutoReload="true"
                    UnloadWhenSheathed="true"
                    UseHandAsThrowBase="true"
                    Consumable="true"
                    AmmoSticksWhenShot="true"           
                    RangedWeapon="true"
                    BonusAgainstShield="true"
                />
            </Weapon>
        </ItemComponent>
        <Flags
            QuickFadeOut="true"
        />       
    </Item>
 
Last edited:
Was puzzling over how to remove all of the CraftedWeapons from stores without having to go through major gyrations in testing or by breaking existing savegames, so that my new weapons are all that populates the stores. Hopefully without causing crashes or otherwise damaging things.

Since the new weapons aren't CraftedItems... the code below appears to work, although the process whereby the store lists get populated in the first place probably needs to be dealt with, too. I have no idea where that code is... yet. I've also discovered that there's a special setting for "cheap weapons" that I may need to address; it may be required to meet the requirements of the "buy axes for local gang" quest. Still need to make some more meshes for that category.

C#:
        public static void removeAllCraftedWeapons()
        {
            foreach(Settlement set in Settlement.All)
            {
                Roster.ItemRoster roster = set.ItemRoster;

                if (roster != null)
                {
                    foreach (ItemRosterElement item in roster)
                    {
                        EquipmentElement element = item.EquipmentElement;
                        ItemObject itemobject = element.Item;
                        if (itemobject.IsCraftedWeapon)
                        {
                            roster.Remove(item);
                        }
                    }
                }
            }
        }
 
Further experimentation. Fully-working Throwing Axe template, which also draws on ammo:

XML:
<Item
        id="dejawolf_einhendi_hedmarkrox"
        name="Nord Throwing Axe"
        is_merchandise="true"
        body_name="bo_axe_short"
        recalculate_body="true"
        mesh="dejawolf_einhendi_hedmarkrox"
        culture="Culture.sturgia"
        value="500"
        weight="1.5"
        difficulty="0"
        appearance="0.5"       
        Type="Thrown"
        item_holsters="throwing_axe:throwing_axe_2"
        >
      
        <ItemComponent>
            <Weapon
                ammo_class="ThrowingAxe"
                weapon_class="ThrowingAxe"
                stack_amount="8"
                weapon_balance="100"
                thrust_speed="100"
                speed_rating="100"
                accuracy="150"
                missile_speed="30"
                weapon_length="45"
                swing_damage="60"
                swing_damage_type="Cut"
                thrust_damage="60"
                thrust_damage_type="Cut"               
                modifier_group="throwing"
                physics_material="metal_weapon"
                item_usage="throwing_axe"
                passby_sound_code="event:/mission/combat/missile/passby"
                rotation_speed="0, -3.0, 0"
                sticking_position="0,-0.4,0"
                sticking_rotation="90,135,90"
                >
                <WeaponFlags
                    AutoReload="true"
                    UnloadWhenSheathed="true"
                    UseHandAsThrowBase="true"
                    Consumable="true"
                    AmmoSticksWhenShot="true"           
                    RangedWeapon="true"
                    BonusAgainstShield="true"
                />
            </Weapon>
        </ItemComponent>
        <Flags
            QuickFadeOut="true"
        />       
    </Item>

Looks like that's a wrap on that one; I'll try and get the rest hammered out today. Meanwhile, been testing the damage system when I've had a spare moment, and it feels pretty good.
 
Last edited:
Throwing Spears template. I think that rounds out all of the unknown templates for thrown weapons, which I think are all the really hard ones remaining (we'll see about couched lances).

XML:
<Item
        id="dejawolf_kastspjottmidtaggir"
        name="Nord Javelin"
        is_merchandise="true"
        body_name="bo_spear_a"
        recalculate_body="true"
        mesh="dejawolf_kastspjottmidtaggir"
        culture="Culture.sturgia"
        value="1000"
        weight="1.5"
        difficulty="0"
        appearance="0.5"      
        Type="Thrown"
        item_holsters=""
        >
       
        <ItemComponent>
            <Weapon
                ammo_class="Javelin"
                weapon_class="Javelin"
                stack_amount="8"
                weapon_balance="100"
                thrust_speed="100"
                speed_rating="100"
                accuracy="150"
                missile_speed="30"
                weapon_length="45"
                swing_damage="80"
                swing_damage_type="Pierce"
                thrust_damage="80"
                thrust_damage_type="Pierce"              
                modifier_group="spear_dart_throwing"
                physics_material="metal_weapon"
                item_usage="throwing_javelin"
                passby_sound_code="event:/mission/combat/missile/passby"
                rotation="180,0,0"
                rotation_speed="0, 0, 0"
                sticking_position="0,-0.95,0"
                sticking_rotation="90,0,0"
                >
                <WeaponFlags
                    AutoReload="true"
                    UnloadWhenSheathed="true"
                    UseHandAsThrowBase="true"
                    Consumable="true"
                    AmmoSticksWhenShot="true"          
                    RangedWeapon="true"
                    BonusAgainstShield="true"
                />
            </Weapon>
        </ItemComponent>
        <Flags
            QuickFadeOut="true"
        />      
    </Item>
 
Still humming along here. Haven't quite figured out all the polearm variants yet, but I'm getting close to having a complete set of templates for most things. Something like 100 weapons are in; throwing spears are working as intended. I'll publish a complete list of these when I'm done in a separate Forum post; this should be handy for everybody who wants to get around the CraftedItem stuff in Bannerlord.

Meanwhile, I've finally solved a minor mystery.

Mackie and I made this thing:
mackie_dha.jpg
Mackie's label is "strange sword". I think Mackie saw a photo of one of these and made the model because it looked cool. In Blood and Steel, I incorrectly called it a "Great Nagamaki", thinking it was some form of early Japanese horse-killing sword. It's not. This is a dha or darb (depending on sub-culture of use- this was a widespread design in South-East Asia from Burma to Thailand):
H20136-L314274607_original.jpg
So, it's sort of a machete that grew into a two-handed sword, really. Cool weapon design... and I'm glad I finally understand where it came from. Pretty much everything Mackie modeled was something based on a photo, so it was fun tracking this down.

Pity that I didn't have any good reference photos or know what it was at the time. As you can see, my handle design, while a decent extrapolation (I was going for a fancy panabas but with some studs on the leather for grip), isn't how they were constructed; the overall handle construction is basically right, but they didn't use any leather or sharkskin; it's wood with metal caps wrapped around the tang, and depending on the owner (above is a "village" type, generally lower-quality) they could have fairly elaborate wooden or metal-covered handles. The "village" types were wrapped in rattan, and presumably the browning on this reference is hand oils; you can tell this weapon was used for a lot of practice (and maybe even war) from the wear on the fibers, where it's been polished almost smooth over time.
 
Last edited:
Glaives and various other polearm types are in. Two-handed swords of various types are done.

I still have a ton of data-entry to go, and I want to test everything before releasing the templates, mainly to make sure they'll actually work as advertised, but I think I'm nearly done. When I've gotten through that part, I'll start replacing the CraftedItems in Bannerlord, troop by troop, and then it's time to start talking about what to do next to arrive at a working alpha release.

I have some code concerns I haven't been able to visit yet, too; I've tried changing the number of troops in the Party Templates for the Lord armies, and it doesn't appear to work as I hoped; unlike Warband, it's not simply pulling the template and running it. I can fix that in a simplistic way pretty easily, based on what it took to build a better bandit-party creation system, but to do a deeper fix on the real issues (for example, do the Lord armies actually get funding from a "real economy" or are they just magical nonsense like they were in Warband, etc.).
 
I'm interested on how you convert old asset into bannerlord. I found some OSP assets in Calradia 1417 would be banger if they're on Bannerlord engine. Thanks for the posts.
 
Thanks for the interest in this. Some relevant information is in the first few pages of this post. If you're experienced in 3D and working with assets and Materials in a PBR workflow, then it's not too hard! I'll probably make a tutorial at some point, if I don't completely run out of steam after getting through making this mod reach alpha.
1. Export the relevant 3D data from BRF to OBJ.

2. Perform any repairs to the object's geometry that are needed (this often includes fixing hard edges, etc.) in Blender or other software (I usually use Wings3D).

3. Import the mesh and any LODs into Blender. All meshes need to have the same root name and LODs need *.lod2, etc. just like Warband. So if your file already has LODs, you can just export all of them as OBJ and import them straight in (I'd skip LOD1s, though, as the lower-poly Warband geometry simply won't need it in Bannerlord and it was of dubious value in terms of performance in Warband anyhow).

4. Export from Blender into the relevant folder in your mod, such as: /YourModName/AssetSources/YourFiles, that you need to create in the Bannerlord Resource Editor.

Use the following settings in Blender:

simple_fbx_export_settings_BL.jpg


5. Using the Bannerlord Resource Editor, import the meshes. If you haven't ever rotated anything since exporting from OpenBRF, it's pretty simple:

simple_fbx_import_settings_BL.jpg


6. If you haven't already, set up a Material. This is the most technically-challenging bit (well, unless you've never used 3D software in your life, in which case... this whole process may feel a bit overwhelming at first).

First, you need to right-click in the Resource Browser and create a new Material. Give it settings basically like these below, except for the diffuse, normal and specular textures.

You'll need to import all three DDS textures that the item used into your mod into your new Material first off. If you're not sure which textures it used, it's listed in the Material in OpenBRF.

Past that point, we're starting to get pretty technical; to work really well, Warband normalmap and specular textures may need some pretty big edits done to them to look their best. With normalmaps, it can be as simple as adjusting the "Normal Depth" variable in the Material, or you may need to edit the normalmap directly. Specular textures generally need to be lightened up; I've found that a safe rule-of-thumb is using a layer filled with RGB 140,140,140 and using Additive blending on the layer is a good starting-place. However, many specific areas of a specular map may need alternation.

simple_material_settings_BL.jpg

[EDIT]If you're talking about armors, and you aren't proficient at 3D modeling and rigging... I'll be honest and say that that's probably a bit too challenging. I'm pretty good at this stuff, and it's been a massive struggle to figure out, lol. Start with simple weapons meshes first, then work your way forward; dealing with conversion to Bannerlord for rigged meshes is quite a different level of complexity, because the body meshes aren't quite the same scale, Taleworlds gave us a lovely problem with how they set up the human bodies (they switched from T-Pose to A-Pose, the neck / body join region is very annoying, basically) and there are other problems, like where leg armors are supposed to terminate, etc., etc.. This is pretty advanced stuff, and I really struggled; at some point I'll probably release a FBX example or two of this for experts to stare at, but I don't have time to write a serious tutorial covering all of the things people will have to deal with, unfortunately.[/EDIT]
 
Last edited:
Meanwhile... enough stuff's in (finally) as data to really start testing things. I'm about to (finally) convert over the Looters' weapons and build a new tree for the Sisters (pretty much where I started with Blood and Steel, after the first few pokes at the Warband damage system) to make sure everything's behaving itself as expected at scale.

Also, last night I ported over Amade's awesome helmets. They were surprisingly-easy to make look good. I had to rework the ones w/ maille extensively (they're meant for males, and were a pain even in Warband), but it largely Just Worked.

working_content_in_BL_01.jpg

Amade's awesome fantasy armors are a whole 'nother can of worms, however. I can't say with certainty that I'll be able to successfully port them, but I'll try. I have a strategy, of sorts, for the female version, but the male version means making a bunch of stuff first, starting with another maille "body glove" skin to facilitate easier porting, match neck seams, etc. Oh well, it's going to be necessary, if I want to port some of the better male armors.
 
Something funny happened along the way to getting Looters refitted tonight. I was puzzling over what weapons to give them- thinking about the sorta-goofy things like "frying pan" that fits the Looters, out of what's been ported. Then I just happened to pull up something in Native's files that looked like it would fit; a pitchfork mesh. Then I looked it up in the current XMLs. Nowhere! And the Resource Browser didn't like the file, somehow; I was trying to look at the meshes connected to the Material and crashed the Editor, lol.

Seeing a golden opportunity, I opened up TPACTool and found it... and a bunch more stuff. Hunted down the textures.

I've rescued all of this.

taleworlds_rescued_assets_BL01.jpg


Taleworlds made this stuff, that's not designed around the CraftedItems systems... at some point. Then they changed their minds and all of these were replaced. But, for whatever reason (I really can't say; there were literally zero references to them in any current XML) the files stayed in the shipped game's TPAC files. I wonder how much other stuff is in there, waiting for me, lol. It's kind of like when I first stumbled upon deneme.brf in Warband, and realized, "hey, they were going to have katanas and samurai, but changed their mind".

This isn't all of this stuff- it's just a sample. I've gotten it all written up in my XMLs as well as set up with brand-new Materials and they're properly ported out; not just a reference. I don't want them broken if TW reads this and decides to remove the files later (call me paranoid, but it saved my butt once w/ Blood and Steel, when they pulled something cool out). Let's just say I have enough to equip peasants and Looters with crappy / improvised weapons, and ironically, they're all using the old XML system, and whoever made these will finally get to seem them shine; I've made very minor edits to the speculars (the wood felt flat) but nothing major.

This mod project's starting to feel less like reverse engineering and more like a time machine; these are almost certainly 4-6 years old at least.
 
New Looters finally work.

the_last_thing_they_saw.jpg


This turned out to be more of an adventure than I'd originally bargained for:

1. There's a really weird setting in EquipmentRosters, that causes an endless-loop error if the Agent in question isn't armed with a Civilian weapon:

XML:
          <EquipmentRoster
                civilian="true">
                <equipment
                    slot="Item0"
                    id="Item.taleworlds_peasent_stick" />
                <equipment
                    slot="Item2"
                    id="Item.throwing_stone" />
                <equipment
                    slot="Body"
                    id="Item.bandit_envelope_dress_v1" />
                <equipment
                    slot="Leg"
                    id="Item.wrapped_shoes" />
            </EquipmentRoster>

Taleworlds, if you're reading this... I consider that issue a bug; surely, if the Roster needs a Civilian item, but there aren't any, instead of looping endlessly (essentially, it gets stuck looping through the Agent's Equipment slots) it should just let the Agent use the Equipment and log a polite warning.

2. You'd better be real, real sure about your collision-volume names; screwing that up causes crashes. Again, not in a useful way, though; the game just blows up and doesn't even explain what's going on in the debugger. Taleworlds... that's also a bug, not a feature; if a Collision object reference is bad, crashing's fine, but crashing without any exception handling and a useful message to the end-user isn't.



Anyhow, besides all that... it was a blast.

Performance is fine, the "rescued" assets look great, and there's finally enough stuff showing up in stores that I can equip my party with some of the new gear and get a feel for how the damage system feels when characters have decent armor. Eventually I'll need to do an XSLT edit on the existing armors to push them into their new tiers and re-price them (seriously, it's amusing that armors suddenly cost 200K when they cross some invisible line, but the whole system feels absurd). Getting close to that part, but I want to do more testing first and get the vast majority of the new items into the game. I'll spend my free time this weekend on data-entry to get as many weapons in as possible, so that it's reasonable.

One thing I know feels super-good. Cavalry vs. infantry. Cavalry vs. loose or broken formations? Infantry gets its clock cleaned. Cavalry vs. tight formations of spears, or big blobs with armor? Sayonara, expensive horsies. That's going to go back and forth a bit; when horse barding is using the same continuum of values as infantry armors, I presume heavy cavalry will still do OK against infantry that's isn't a big mob of pointy sticks. But the whole, "loose formation is best" stuff doesn't apply here; infantry with light / no armor get seriously messed up by cavalry collisions and spear attacks and the converse- suddenly losing your steed during a charge- is quite fun.

One of the obstacles I already see coming: there isn't an easy method to do costume tests. I guess I can go to the Model Viewer and flip through costumes there and write everything down, but that's going to be clunky. There should be an actual UI in the Editor for designing EquipmentRosters, imo; this is one of the most time-consuming parts of developing new characters.

There's also the issues w/ pauldrons, gloves and boots, which all look horrible on women. They're absurdly over-sized or they float like crazy or both. I think I'm going to ban the vast majority from female use entirely until I can make _converted versions... or something. It's the easiest short-term solution.
 
1. You cannot add any new Factions during a campaign, even if they're mere bandits. That's a bummer, means I have to start a new campaign every time I want to test anything. I presume I'm going to have to make use of console commands and cheat like crazy to get anything started. Maybe somebody made a save editor that actually works; I'm annoyed that I'm going to have to rebuild my party and find the Companions again, lol.
2. You can, however, add all the new PartyTemplates you want. That's cool, but of really limited utility, unless I want to re-write how my bandit-spawner behaves. Right now, it's deliberately written to give the player the impression that wherever they go, whatever they do, there are lots of bandits around causing trouble; there's never more than a brief moment when the player doesn't have an enemy around they pick a fight with. This causes real havoc with Lord armies and trade caravans sometimes, but I'm inclined to ignore that until I see actual problems.
3. If I'm going to have to start new games on a regular, I may as well write out the three identical, boring Empire factions so that they no longer share the same Culture and can have completely different troop trees, because troop trees start with a basic troop type and basic "elite" troop tree, which is practically always cavalry.

Can I have the Rhodoks back?

4. Speaking of troop trees, I finally got around to playing with this area. I tried making Looters be able to upgrade to all the base infantry types. Yes, that works- you can do it, the game can deal with it. The Party UI doesn't quite handle it right, but it mainly manages and it doesn't crash. Three upgrades for a given troop where the secondary choices don't have branches, just straight upgrades, will probably actually work. Sounds like a solution to return to where I was going with the Sisters, among other things.

5. It's pretty satisfying to see all this come together. Given that I'm going to have to start clamping down and I'm still not done with data-entry stuff for the current weapons, I should probably sketch out roughly what I want:

A. Each region gets some unique "clans" that can spawn bandit parties. Something that's basically infantry, archers or cav, or a bit of everything, rough-balanced for early, mid and late-game fun.

What's in the game atm is very... generic, and has the same game-design problems as Warband, which is what it's almost copied verbatim from. There's no real variety, and if you want to make money, you go up against Sea Raiders, for the same reasons as Warband (they have good loot / kill, but are pretty weak for guys who are supposed to be scary Vikings).

Eventually, that's longer sufficiently profitable (but that takes a while now; you're more likely to hit the "there are no bandits around here" issue. Which is actually a bug, as far as I'm concerned (and dealt with), because you can actually do some silly things to the game's long-term behaviors in Native by selectively exterminating Hideouts. I doubt anybody's really messed with that, but there is an actual maximum number of Hideouts on the map and they're largely responsible for Bandit party spawns, in Native. If they're killed off in areas you want cleared, they largely stay cleared, because enough Bandit parties get generated elsewhere and the system quits generating new ones.

There's no reason to go to anywhere in the Empire, Khuzait, Aserai, etc.- reward is poor.

In the current combat system, this is even worse; parties of Forest Bandits are an actual threat (for now, with armor values unchanged) because they're showing up in large numbers and they're relatively well-armed, with decent bows and axes. It's fun beating them, but it's actually feeling like Hard Mode. Aserai and Khuzait areas are right out with a low-level party, because of the cavalry, and aren't sufficiently profitable until midgame. In Native, they're never worth fighting at all, imo. The Mountain Bandits are mid, and usually not worth tackling early.

All this needs to be addressed. There should be bad guys everywhere the player wants to fight, for fun and profits. I already have a system where the bandits "level up" and get harder with the player; what I don't have yet is data in place to make this much more interesting. I probably need to write all that now, at least at the sketch-level, so that it's done, other than making tweaks to Party Templates and NPCs.

B. The Empire probably gets split into the Imperial Remnants and the Rhodoks. I feel like the Rhodoks getting more-or-less rolled sideways into Vlandia and the Empire removed a lot from the game, personally. I wasn't ever all that excited about the Vaegir in Warband; they became the Romans-That-Weren't, but it never felt quite right. The Rhodoks were cool, though, because they were basically the Italians circa 14th-16th centuries, and they could be disgustingly difficult to fight in sieges.

C. If I keep the current slooooooooow system of casualty management and low player army size, I'll need to provide appropriate troop trees for the player to upgrade into that gives them a quality advantage that actually matters.

D. If I'm committing to yet-more data entry, I guess I need to make some real decisions about longer-term game-design goals here.

Do I bother with having an Evil Empire somewhere? That was one of the big draws of Blood and Steel, even if it always felt half-finished and crude. The Armies of Darkness were the fun challenge for the player who thought they were invincible.

It's probably easiest to take that on now, editing one of the Empire Factions with a new Culture, etc., so that they're in officially and are supported, even if they continue to look like the old stuff for now. I can support them later with special mechanics, new Races / Monster types, etc. etc. so that I can re-create their unique threat level and weird variety of troops. I'll have to look at the map, but it's probably the Southern Empire, where they're touching almost everybody but the Sturgians.
 
Messing with Cultures (to attempt to make, say, the Empire into multiple separate entities) is awful. I blew my evening trying and just feel annoyed :razz:
 
Almost all of the weapons are in, other than Lui's swords and Wheene's stuff. Getting closer now. I'm going to do Lui's swords soon and finally publish a working list of templates for others to consult; most of this has been well-tested at this point.

Did the first revisions to armor, as well.

What I found is that:

1. Stats in each set were all over the place. The general idea appears to have been, "balance so that with complete gear, total values for everything but heads is around 70". It's not terrible, but the way it was done feels pretty odd in spots, especially weights (see below).

2. There really aren't even examples of real Transitional Plate in the art, so far as I can tell (with weird exceptions like battania_brass_plate_armor, which, with different materials on the art, would be basically like a 17th Century breast-and-back suit). There's no real plate and maille. There's that weird "halloween" suit of kinda-Gothic plate and maille; it'd need extensive edits to be any good, though.

That means that in my systems, armor values top out around 85 (85 implies maille with some plate over an aketon) and if I keep current pauldron values, it's somewhere around 100-110 for a really lucky pauldron combined with good gloves, etc.

3 Weights are all over the place. They don't have much correlation with the real protective value of the armors. Some armors with the same stats are 1000% heavier than others, for example. Since this definitely messes with combat feel, I've addressed this with new, standardized values:

Light Armor (cloth, padded stuff, light leathers, etc.): 4 kilos.
Medium Armor (leathers, lighter mailles, etc.): 6 kilos.
Heavy Armor (mailles, lighter scales, etc.) 8 kilos.
Noble Armor (heavier scale, maille w/ some plate, etc.) 10 kilos.

4. The issues with weights are compounded by protection levels. It appears that the entire system of intended balance depends explicitly on the gloves, boots and pauldrons. With boots, I can't really get mad about it; the gloves and pauldrons are kind of a weird solution; in the real world, they were usually "integrated systems" with armors. The way it works in Native drives me a bit nuts, honestly; you're forced into aesthetic choices for gear that probably look horrible if you want the best sets.

So I've done a complete pass on the armor values:

Light Armor: 15-35 Body, 10-25 Arms / Legs (with a few exceptions for weird "armor" that doesn't cover arms, chest, etc.)
Medium Armor: 40-55 Body, 25-40 Arms / Legs
Heavy Armor: 60-70 Body, 45-55 Arms / Legs
Noble Armor: 70+ Body, 55+ Arms / Legs

When pauldrons / gloves / footwear is accounted for, this should, in theory, lead to results for a Noble Armored warrior somewhere around 100-ish for best-quality gear. I only got to do a brief test in my last run on high-end armors and how they affected play, but it looked good at the time.

Next up is barding, then helmets, then it's back to getting sword data in, dealing w/ Wheene's stuff, and troop revisions. I'm eager to have enough parts in to be able to test things on a broad scale and have this thing out in public for feedback.
 
Barding was interesting, but more importantly, I've learned a lot about how to build troop inventories, that I think everybody will find useful.

1. Barding doesn't cover body parts, like any other armors do. This feels like a wasted opportunity. I need to do some testing, but I don't think horses can even be headshot targets! So far as I know, my code's treating horses like humans... so this may be engine-level shenanigans.

2. Barding and real horse variety is incredibly limited vs. Warband. I'd say I was tempted to figure out horse rigging, but I'm not; I think I'm more tempted to figure out how to rig "horses" that have built-in saddle geometry. I think Taleworlds made a major mistake going this route with horses; they're all so samey and boring because of the requirements to keep them rigged exactly right without excess clipping.

Moving on to troop inventories... wow, what a complicated mess, lol.

1. Troop inventories can have multiple ways of being filled when an Agent spawns:

This is what looks like the standard method of setting up Equipment looks like. It's not very handy, if you want the Agent to have a lot of basic choices that remain the same, but it allows for full variety when spawned; essentially, the game picks an EquipmentRoster at random. This is very different from Warband, where we simply wrote out a list of items of <types> and the game automatically picked a valid item of <type> for <slot> using some internal rules.
XML:
<EquipmentRoster>
                <equipment
                    slot="Item0"
                    id="Item.taleworlds_peasent_wood_pitchfork_2" />
                <equipment
                    slot="Body"
                    id="Item.torn_bandit_clothes" />
                <equipment
                    slot="Leg"
                    id="Item.leather_shoes" />
                <equipment
                    slot="Head"
                    id="Item.wrapped_headcloth" />
            </EquipmentRoster>

If you have equipment you wish to be standardized, however, you can totally do that, via having Equipment entries outside of an EquipmentRoster. This is typically being used by Taleworlds for horses, but it turns out that this works for everything:

XML:
            <EquipmentRoster>
                <equipment
                    slot="Item2"
                    id="Item.igorbb_serbian_handaxe" />
                <equipment
                    slot="Body"
                    id="Item.buckled_wildsman_armor" />
                <equipment
                    slot="Leg"
                    id="Item.battania_leather_boots" />
                <equipment
                    slot="Gloves"
                    id="Item.studded_leather_vambraces" />
                <equipment
                    slot="Head"
                    id="Item.bearhead" />
                <equipment
                    slot="Cape"
                    id="Item.bearskin" />
            </EquipmentRoster>

            <!-- STANDARD EQUIPMENT -->               
            <equipment
                slot="Item0"
                id="Item.woodland_longbow" />
            <equipment
                slot="Item1"
                id="Item.barbed_arrows" />
            <equipment
                slot="Item3"
                id="Item.barbed_arrows" />               
                
        </Equipments>

Then there's the confusing system for "civilian" gear. A lot of Troops have "civilian" sets; why they do is rather a mystery, however; so far as I know, you'll never see Mercenaries in their "civilian" sets (in Taverns, they're fully armed and armored, to make it obvious to players) they never show up in Alley Fights (it's always the player and random poorly-equipped guys- I don't think even the Companions show up, which is a huge missed opportunity, imo. So, why do Sword Sisters have "civilian" gear? Wedding scenes, maybe? It's a mystery. At any rate, they are often designated through EquipmentSets:

XML:
<EquipmentSet
                id="empire_troop_civilian_template_t1"
                civilian="true" />

This is a reference to another EquipmentRoster, defined in another file; I guess the intent was to reduce data-entry when this stuff was being built. It's usually used to designate a "civilian" EquipmentRoster; see next.

Last but not least, you can throw a value into an EquipmentRoster that designates it as "civilian". Again, this shows up in strange places where I don't know if it's ever really used by the game:

XML:
<EquipmentRoster
                civilian="true">
                <equipment
                    slot="Item0"
                    id="Item.taleworlds_peasent_stick" />
                <equipment
                    slot="Body"
                    id="Item.bandit_envelope_dress_v1" />
                <equipment
                    slot="Leg"
                    id="Item.wrapped_shoes" />
            </EquipmentRoster>

*********************************

I've also gotten the Sword Sisters revisions started, and did a bit of tuning to other troops, just to make sure things are working as planned. The new armors look great in-game.
 
Back
Top Bottom