Skip to main content

I am the army, skyler!!!!

https://preview.redd.it/o0bygi3c051d1.png?width=1299&format=png&auto=webp&s=f86c1a5f0faee68b7b957aae561b261c134b9ab9 350 vs 800 guys and get 100 kills alone :D submitted by /u/Kindly-Assistance-80 [link] [comments]

The Module System: The science behind siege negotiations

As there was a meme earlier today about how towns literally never surrender, I went digging to see how the game calculates whether the AI is willing to surrender or not. As my finds were rather curious, I thought I might as well share what I found, and explain how it works.

The game code

Part 1: selecting the correct dialogue option

Whenever the player selects

[anyone,"player_siege_ask_surrender", [(lt, "$g_enemy_strength", 100), (store_mul,":required_str","$g_enemy_strength",5),(ge, "$g_ally_strength", ":required_str")], "Perhaps... Do you give your word of honour that we'll be treated well?", "player_siege_ask_surrender_treatment", []], [anyone,"player_siege_ask_surrender", [(lt, "$g_enemy_strength", 200), (store_mul,":required_str","$g_enemy_strength",3),(ge, "$g_ally_strength", ":required_str")], "We are ready to leave this castle to you and march away if you give me your word of honour that you'll let us leave unmolested.", "player_siege_ask_leave_unmolested", []], [anyone,"player_siege_ask_surrender", [], "Surrender? Hah! We can hold these walls until we all die of old age.", "close_window", []], 

So these are the options the AI has in response to the statement "Surrender! Your situation is hopeless!" you can choose. Before the first two options there's a bit of code, and that code decides if that particular option is chosen. Let's have a look at that code.

(lt, "$g_enemy_strength", 100), (store_mul,":required_str","$g_enemy_strength",5),(ge, "$g_ally_strength", ":required_str") 

This can be divided into a few chunks, each of which is contained in a set of brackets. The first bit reads (lt, "$g_enemy_strength", 100). This is a simple comparison of numbers. lt stands for "lesser than", and "$g_enemy_strength" is the numerical value that determines how strong the enemy is (more on how that is calculated later). So this bit of code says "if the enemy's strength is less than 100, execute the next bit".

Next, we get (store_mul,":required_str","$g_enemy_strength",5). This bit of code is only executed if the first bit of code was executed (so if the enemy's strength is less than 100). store_mul has 3 parameters, and essentially says "multiply parameters 2 and 3, and store the results in parameter 1". So this bit of code makes a new value called :required_str which equals the enemy's strength times 5.

Finally, we get (ge, "$g_ally_strength", ":required_str"). Like lt, ge is another comparison, except this time it stands for "greater than or equal to". This bit of code then calls "$g_ally_strength" (the numerical strength of the player's party and allies), and compares it to the :required_str value we made in the previous bit. As this is also the last bit of code, if this bit succeeds, the dialogue option linked to this bit of code is chosen. So this bit says "if the allied troops' numerical strength is greater than the required strength, select this dialogue option".
So in total, this codeblock says "if the enemy's strength is less than 100, and the allied troops' strength is greater than 5x higher than the enemy's strength, select this dialogue option". If this codeblock fails for any reason (enemy strength is greater than 100, or the player's strength is not greater than 5x higher), the AI moves to the next option.

The next option reads very similar to the first. I won't go into the same amount of detail as before, but essentially the second option's code reads "if the enemy's strength is less than 200 (but more than 100, because that option was already covered in the first dialogue option), and the allied troops' strength is greater than 3x higher than the enemy's strength, select this dialogue option". If both of these options fail, the game defaults to the last option, the infamous "Surrender? Hah! We can hold these walls until we all die of old age.".

So if we want to fully dissect how this mechanic works, we next need to examine how the strength of a party is calculated.

Part 2: calculating party strength

So the previous bit of code makes use of "party strength", which is a bit of a vague term. These strength values are determined with a rather longer bit of code. I will show part of it, and explain the rest. Essentially, what the game does is go through the entire party, and look at all the "stacks" in the party. A stack is essentially a group of troops of the same type. So if you have 5 Swadian Militia, 3 Nord Veterans, and 12 Nord Huscarls in your party, you have 3 different stacks (4 if you include the player). For each of these stacks, the game then does the following:

(try_for_range, ":i_stack", ":first_stack", ":num_stacks"), (party_stack_get_troop_id, ":stack_troop",":party", ":i_stack"), (store_character_level, ":stack_strength", ":stack_troop"), (val_add, ":stack_strength", 4), (val_mul, ":stack_strength", ":stack_strength"), (val_mul, ":stack_strength", 2), (val_div, ":stack_strength", 100), (val_max, ":stack_strength", 1), (try_begin), (neg|troop_is_hero, ":stack_troop"), (party_stack_get_size, ":stack_size",":party",":i_stack"), (party_stack_get_num_wounded, ":num_wounded",":party",":i_stack"), (val_sub, ":stack_size", ":num_wounded"), (val_mul, ":stack_strength", ":stack_size"), (else_try), (troop_is_wounded, ":stack_troop"), #hero & wounded (assign, ":stack_strength", 0), (try_end), (val_add, reg0, ":stack_strength"), (try_end), 

So, this code is rather a bit longer. Let's dissect it again. First, we get this bit:

(try_for_range, ":i_stack", ":first_stack", ":num_stacks"), 

This is a bit of code that says "execute the following bit of code for every individual stack in the party". This is what's called a "loop".

(party_stack_get_troop_id, ":stack_troop",":party", ":i_stack"), 

First, the game looks up exactly what kind of troop this stack is filled with. This could be Swadian Recruit, Farmer, Khergit Horseman, etc. The value of this troop is then stored in :stack_troop.

(store_character_level, ":stack_strength", ":stack_troop"), 

Next, the game looks up the level of the troop. Every troop has a level, just like the player character has a level. For some examples, the Swadian Militia is level 9, while the Nord Huscarl is level 28. Stronger troops have a higher level is the rule of thumb. The level value is then stored in :stack_strength.

(val_add, ":stack_strength", 4), (val_mul, ":stack_strength", ":stack_strength"), (val_mul, ":stack_strength", 2), (val_div, ":stack_strength", 100), (val_max, ":stack_strength", 1), 

Here we get to some extra maths. The :stack_strength that was found in the previous bit has some manipulations done to it. First, val_add adds 4 to the strength. Next, val_mul multiplies the strength with itself. Then it's multiplied by 2 again, before being divided by 100. Then the game compares the value to 1, and picks the higher value of the two. So if the result is 0.3, it will get increased to 1. If it's 8.7, it will just stay as that. This is the final strength value of a single troop in a single stack in a party.

(try_begin), (neg|troop_is_hero, ":stack_troop"), (party_stack_get_size, ":stack_size",":party",":i_stack"), (party_stack_get_num_wounded, ":num_wounded",":party",":i_stack"), (val_sub, ":stack_size", ":num_wounded"), (val_mul, ":stack_strength", ":stack_size"), 

This bit calculates how many troops are in this stack, and subtracts the wounded troops from the amount. Finally, the strength we found before is multiplied by the amount of unwounded troops in the stack. There is also a line here that checks to make sure the current stack is not that of the player or a companion.

(val_add, reg0, ":stack_strength"), 

reg0 is the final result of this calculation, so at the end of this stack's calculation, the stack's strength value is added to the total value.

This is then done for every stack in the party, until all are done and added up.

Calculating party strength, an example

Let's say we have a player's party with 20 Swadian Militia, and 50 Nord Huscarls, while the player himself is level 15. None of the troops are wounded.

This party has three stacks: the player, the Swadian Militia, and the Huscarls. The strength value of the player is ((15 + 4)2) * 2 / 100, which is 7.22. As there is only one player, this value is not multiplied. The strength value of a Swadian Militia is ((9 + 4)2) * 2 / 100, which is 3.38. Since there are 20 Militia, the value of this stack is 3.38 * 20 = 67.6. The strength value of a Nord Huscarl is ((28 + 4)2) * 2 / 100, which is 20.48. Since there are 50 Huscarls, the value of this stack is 20.48 * 50 = 1024. So the total strength of this party is 7.22 + 67.6 + 1024 = 1098.82.

So, what can we learn for this?

All this science essentially gives us a few rules of thumb:

  • Towns or castles with a strength higher than 200 will never surrender.
  • A strength of 200 is pretty low. A town with just 60 Swadian Militia and nothing else has a strength of 202.8, and will never surrender.
  • If a settlement has less than 200 strength, but more than 100, and your party's strength is more than 3 times higher, the enemy will offer to leave. They will spawn outside the town as an army if you accept.
  • If a settlement has less than 100 strength, and your party's strength is more than 5 times higher, the enemy will say you can take them captive, but if you accept you don't actually get to imprison them. Instead, they'll just vanish from the game.

In my opinion, this mechanic is largely useless. The player's persuasion skill is not used at all in this calculation, a settlement with 60 second tier troops will never surrender, not even when under attack by an entire faction worth of lords.



Submitted June 29, 2019 at 11:27AM by Halfkroon https://ift.tt/2NgsyqL

Comments

Popular posts from this blog

ERROR - Could not load merged xml file correctly: ItemsError: Object reference not set to an instance of an obect.

Reinstalled the game recently and have been getting the error message above. I'm able to launch the game but once I click on "new game" it crashes and shows error. I have some mods download and have checked to make sure they're updated to the current version. I've also made sure to unblock all dll files. Any suggestions would be great thanks. submitted by /u/leopaldo [link] [comments]

TaleWorlds Forums

Back when Bannerlord was announced, I vaguely remember that, in the announcement thread, people were discussing the choice of the title "Bannerlord." Does anyone else remember that? It was a useless topic to discuss, but I kept coming back because I was so hyped about the game and was hoping for more information about it. Submitted December 23, 2018 at 06:27AM by Genghis-Swan http://bit.ly/2PXSwvf

Old Realms mod crash

Hi everyone I've been trying to get the Old Realms mod to work the last couple of hours. I changed my bannerlord patch to match mod (1.6.2). Everytime I try to boot it up, it reaches the "Old Realms" loading screen for a couple of seconds, then crashes.. I really want to get this to work, anybody who can help? :D Submitted October 09, 2021 at 10:45AM by molly1111 https://ift.tt/30b37xX