OSP Kit Combat Battlefield Tactics kit. Multiple formations per team+command revamp!

Users who are viewing this thread

Lumos said:
Damn, if I had the time to check this code out...

Damn, if I had the time to keep this code up...  :lol:

othr said:
There is just one issue I noticed.  Cavalry units will wait for their dehorsed friends before making another charge, I think it would be best if they didn't, they're very vulnerable to ranged fire when they're just standing there waiting for their buddies on foot to join up.

You know, at some point unmounted cavalry will join infantry. Or at least it was when I was still using agent_get_class instead of agent_get_division. But I did notice the other day that unmounted Vaegir vets remained with cavalry. Argh.

sphere said:
I'm still relative new to using this mod, so the following may not be accurate.  Please be tolerant, and just take those that may be useful :wink: Using warband 1127, btw.  Note this is the version BEFORE the last update.  Please ignore all the points which are no longer applicable.

In general your suggestions take the formations mod to a whole new level. I've kept implementation cheap and (relatively) simple. So my response to most of your suggestions is that it'd be a nice embellishment if someone got around to making it. I add more response to particular suggestions below.

BTW, my last update was an extension to the formations mod...

sphere said:
1) relation with the original Hold command (holding F1-F1, move to target, then release).  intuitively, I'll expect the formations to be centered horizontally and have front touching the spot marked.  This is not always the case.

Yes. It was my simple solution to the question of how many classes are selected. Rather than work out which formations should go where, it simply recreates the setup as if the PLAYER were at the F1 spot. I admit that this doesn't work well when only one formation is selected.

sphere said:
2) Facing is also a problem.  As there is a lack of rotating formations atm (unless I miss out some features), keeping the default idea of autorotating to face the nearest concentration of enemies will be good.

Right now it autorotates to the average position of the enemy UNLESS the formation is formed relative to the player. This is more of a historic accident, the code predating my rotation function. It WOULD be more consistent to follow the game engine in this regard, and, now that I think about it, it'd take the addition of but a single line of code. On the other hand, the code as it stands gives the player an alternative to autorotate, and at any rate it is simple enough for the player to rotate before calling formations. Maybe it's a FEATURE... :wink:

sphere said:
4) Separate formation position templates from assignment template.  Position will define position "slots" like ranks, staggered ranks (where a ranks positions are aligned with gaps of the rank in front, like the default Hold position in game has with "Stand Closer" issued), shieldwall, square, wedge, loose (where rest of "formation" just follow the leader losely without any fixed formation) and of course no formations.  assignment templates will decide how to assign troops to that formation (and also how to "repair" damaged formations when troops die).  E.g. maybe for just ranks, we could have:
a) 3 ranks: infantry in first line, archer in second line, mounted archers in third, cavalry divided into two blocks at either side (not mixed with the center ranks) (If only we have kneel animation and make the first line kneel with shields up....)
or
b) 2 ranks, first rank with alternating infantry and archers, second rank with alternating cavalry and mounted archers

My code is very simple in this regard -- following the original by Mirathei. There's no templates -- it just plops down whoever shows up next from try_for_agents with maybe multiple try_for_agents to accomplish sorts (I don't have the Python skills to construct proper sortable lists). I think foxyman's formations have much more troop control, if you'd like to check his implementation out.

The ranks based on troop type need no special consideration beyond the game engine distinction between classes/divisions. If you want archers behind infantry, you just advance the one or have the other fall back, right?

sphere said:
6) Regarding "Shield wall", is it a formation where those units with the biggest/baddest shield will go to first row and set their individual ai to actually hold the shield (i.e. agent performing shieldwall duty are automatically set to not put down the shield like fire range weapons or use two handed weapons unless otherwise commanded or shieldwall is changed to some other formation).  If it isn't, maybe it should be???

The sort simply takes whoever is wielding a shield for the first ranks, so I basically leave it to the mercy of the game engine. Finding which troops have shields and forcing enough to wield them to fill the first rank would be a WHOLE 'nother level of formation management.

sphere said:
Not directly related to above, but... (please ignore useless stuff, and just hoping something could be helpful)
motomataru said:
Prob 2: I noticed a variant of this problem with my new AI. Basically, the troops get their formation data from the team leader (partly because faction data is NOT attached to most troops -- even faction troops). When the leader dies, the troops can't determine which faction they belong to, hence can't pick a formation. Initially, I thought, "No problem. Leaderless troops shouldn't perform functions that require orders from a leader." But it does look funny to see a formation go kaplooey in the middle of a battle when the leader is killed. Suggestions?

I don;t understand the "faction" part exactly, do you mean this:

* formation related data are stored in faction data, and only team leader records the faction id?
* is it possible to propagate this data to all formation members during formation forming/reforming?
* if it is the lack of leader problem, can a new leader be elected by the first agent that detects leader is gone? (e.g. once agent detects leader killed, store the agent's id in global data, then read back the id (to cater for race-condition), and if the id is the agent's id, the agent is now the new leader and will do initiate the formation reforming and reading/generating all the formation data again.

* You'll see in script_get_default_formation -- I acquire the faction through the leader, then have a hard switch for formation selection.

* I'd need a new set of global variables (sigh).

* Interesting question. There is a set leader function. Problem is, most regular (non-knight) troops do NOT have faction set, and I didn't want to have the formations mod require a rewrite of the troop table. If a modder goes through the trouble of completing the troop table properly, then, yes, the faction would be available. But then I'd just need to update my code to use ordinary troop faction -- something I'm beginning to feel I ought to do. However, there's no guarantee that the first agent that comes up will be a faction troop and not, say, a farmer's wife that had been rescued. Hm, at best I could pad the odds but not guarantee the correct faction could be found.

Thanks for all your feedback!
 
motomataru said:
othr said:
There is just one issue I noticed.  Cavalry units will wait for their dehorsed friends before making another charge, I think it would be best if they didn't, they're very vulnerable to ranged fire when they're just standing there waiting for their buddies on foot to join up.

You know, at some point unmounted cavalry will join infantry. Or at least it was when I was still using agent_get_class instead of agent_get_division. But I did notice the other day that unmounted Vaegir vets remained with cavalry. Argh.

It's Warband. Unlike cavalry class, members of cavalry (or any other) division won't switch when unhorsed.

I guess this makes sense. A unit's a unit. But now I have to deal with what are effectively divisions of the divisions...
 
Hi motomataru, where in module_script I shoulde but your sript in? Due I tried but at botton before the very last ] but always got error when building new mod.

And I'm using unmodified 1.126 module system.
 
I wrote this little thing, I have no idea if this is the way this should be done but it does seem to get the job done when it comes to reassigning dehorsed cavalry to the infantry group.  I plugged this into a lance breaking trigger, it can go pretty much anywhere I guess.

Code:
    (try_for_agents, ":agent"),
      (agent_is_human, ":agent"),
      (agent_is_alive, ":agent"),
      
      (try_begin),
        (agent_get_group, ":agent_group", ":agent"),
        (eq, ":agent_group", 2), # 2 is cavalry
        (agent_get_horse, ":agent_horse", ":agent"),
        (le, ":agent_horse", 0), # lacking horse
        (agent_set_group, ":agent", 0), # 0 is infantry
      (try_end),
    (try_end),
 
Hey, sorry 'bout that. I'd actually written a little function to use agent_get_division for player formations and agent_get_class for AI formations. I was holding off on posting until I got caught up with all the little things here and from Brytenwalda betatest, but then Sphere distracted me with the self-installing mod idea.

Speaking of which, here it is. Both the original formations mod and its AI extension mod, according to sphere's initial work with placing formations mod source in independent files. I've just now realized I could have put both M&B and Warband versions in a single source file, and in any case sphere has built modmerge further, but right now I need to get back to my growing list of actual mod work.

So, without further ado:

http://dl.dropbox.com/u/8432316/Formations%20and%20AI/README.txt

Installation utilities: http://dl.dropbox.com/u/8432316/Formations%20and%20AI/modmerge%20utilities.zip
Formations mod source: http://dl.dropbox.com/u/8432316/Formations%20and%20AI/formations%20mod.zip
Formation AI extension mod source: http://dl.dropbox.com/u/8432316/Formations%20and%20AI/formation%20AI%20mod.zip

The great benefit of using these (for those of you that are already using these mods) is that you can simply drop any updates I make to the mod on top of its independent source files (if you haven't made your own modifications to them).
 
Now I'm not so sure my code snippet above your post actually does anything.  I tested it multiple times and my results are inconclusive :razz:
 
othr said:
I wrote this little thing, I have no idea if this is the way this should be done but it does seem to get the job done when it comes to reassigning dehorsed cavalry to the infantry group.  I plugged this into a lance breaking trigger, it can go pretty much anywhere I guess.

Code:
    (try_for_agents, ":agent"),
      (agent_is_human, ":agent"),
      (agent_is_alive, ":agent"),
      
      (try_begin),
        (agent_get_group, ":agent_group", ":agent"),
        (eq, ":agent_group", 2), # 2 is cavalry
        (agent_get_horse, ":agent_horse", ":agent"),
        (le, ":agent_horse", 0), # lacking horse
        (agent_set_group, ":agent", 0), # 0 is infantry
      (try_end),
    (try_end),

My first instinct was something like this. The only thing that jumps out at me in your implementation is agent_get_group. I'm not sure what it does, and it's only used in multiuser scripts. I used instead agent_get_division (which, since it always returns the original troop assignment to infantry, archers, cavalry, #3-8, really ought to have been implemented at the troop_ level (troop_get_division)).
 
@motomataru
Ok, I'm adapting formations to the latest version of modmerger again....  :smile:

I encountered some problems, possibly with warband only.

There could be a mix up between formation_mission_templates.py and formation_mission_templates_wb.py

My suspicions comes from the observation that formations_mission_templates_mb.py contains the obsoleted game constants:
##gk_order_halt = 22
##gk_order_follow = 23
##gk_order_charge = 24
##gk_order_dismount = 25
##gk_order_hold_fire_toggle = 26
##gk_order_advance = 27
##gk_order_fall_back = 28
##gk_order_stand_closer = 29
##gk_order_spread_out = 30
##gk_order_blunt_weapons_toggle = 31

whereas formation_mission_templates.py actually contains the current ones in module system warband 1127.

could you confirm this please?

thanks!!!

EDIT: btw, after I upgraded it to the latest version for modmerger (0.2.1), would you like me to post it back to you to maintain, or do you mind if I just upload it somewhere and stick a link as a sort of mini-port branch off your main work?

This time round porting is so quick (10 min, mostly due to changes on my side for some constants/variables + add a new wrapper function below each file) :smile:  Still need to test in-game though.  The only difference with your current one is that for the updated version, there is no longer need to go to every module_*.py and paste stuff into it (automated by installer script).

So the installation process for formations can become:
1) put modmerger in module system directory and run installer script.  Skip this step if modmerger already installed and up to date.
2) put formation files in same place, edit modmerger_options.py and add "formations" to list of mods_active.
3) build module

EDIT2: ok, just took 2 min to adapt formAI after the experience with the main mod, integrated and builds without a problem, then I took my little beginner testing squad of 29 men (From earlier save game) and engaged some vaegir deserters (skirmishers i think)...

They did not approach like the usual mad charge.  The deserters (seems all archers) form a nice llittle line at the far end o the map and don't move.  I tot their AI got stuck or something and rode closer... then those sneaky b***** started concentrated arrowfire on my hero.....  horse went out and before I knew it ...  I realised that helmets are important even during testing...  you should never ride horses or autobikes without one...  :roll:

Now, please tell me, is that expected or just a stroke of luck that the enemy AI got stuck and don't move??? LOL
 
Have you considered using a subversion server for your code Motomataru?  Google code offers free subversion repositories, I'm old fashioned...  I like to merge the code myself and subversion would make it really easy :smile:
 
Just updated the code with many of your suggestions from the last couple weeks. Sorry to miss the boat, sphere...

sphere said:
My suspicions comes from the observation that formations_mission_templates_mb.py contains the obsoleted game constants:

Sorry, I changed the naming convention. Extensions ending in _mb are Mount&Blade 1.011 alternative scripts, and it's the non-extended ones that are for Warband.

That's why above I say I've realized that the various versions could probably be handled by the modmerger from a single file. Like a WB codeblock and a M&B codeblock. Do you have a suggestion for how to proceed for that?

sphere said:
EDIT: btw, after I upgraded it to the latest version for modmerger (0.2.1), would you like me to post it back to you to maintain, or do you mind if I just upload it somewhere and stick a link as a sort of mini-port branch off your main work?

Whichever you think is best. It sounds super-easy to use, and I look forward to it.

sphere said:
EDIT2: ok, just took 2 min to adapt formAI after the experience with the main mod, integrated and builds without a problem, then I took my little beginner testing squad of 29 men (From earlier save game) and engaged some vaegir deserters (skirmishers i think)...

They did not approach like the usual mad charge.  The deserters (seems all archers) form a nice llittle line at the far end o the map and don't move.  I tot their AI got stuck or something and rode closer... then those sneaky b***** started concentrated arrowfire on my hero.....  horse went out and before I knew it ...  I realised that helmets are important even during testing...  you should never ride horses or autobikes without one...  :roll:

Now, please tell me, is that expected or just a stroke of luck that the enemy AI got stuck and don't move??? LOL

AI will take the defensive if outnumbered 1:2... The AI on the battlefield now ought to better reflect behavior on the strategic map. If it was running from you there, it's not going to attack in battle.

As for why they chose your hero to pincushion, I don't know. Maybe he's just UGLY. :smile:

othr said:
Have you considered using a subversion server for your code Motomataru?  Google code offers free subversion repositories, I'm old fashioned...  I like to merge the code myself and subversion would make it really easy :smile:

I'll check it out. Never heard of "Google code."
 
Here is the link, all you need is a google account and some code:

https://www.google.com/accounts/ServiceLogin?service=code&ltmpl=phosting&continue=http%3A%2F%2Fcode.google.com%2Fhosting%2F&followup=http%3A%2F%2Fcode.google.com%2Fhosting%2F
 
motomataru said:
Just updated the code with many of your suggestions from the last couple weeks. Sorry to miss the boat, sphere...

Sorry, I changed the naming convention. Extensions ending in _mb are Mount&Blade 1.011 alternative scripts, and it's the non-extended ones that are for Warband.

That's why above I say I've realized that the various versions could probably be handled by the modmerger from a single file. Like a WB codeblock and a M&B codeblock. Do you have a suggestion for how to proceed for that?


hmm, then I means i may have been messing around with mixed version source? (I actually used _wb versions for the other files).  wondered why it still seem to work... LOL... think I'll do another merge from scratch leaving out the wb files for now.

BTW, I was thinking maybe I can try to keep a variables in an option file somewhere (probably modmerger_options.py for the latest version) for user to set  (e.g. "version" : 1127), so when writing your own injection code, you could do things like check if the game is warband (probably when "version" > 1011) or if it is the latest warband that some code supports (e.g. if only supported after 1125, then check for "version" >= 1125).  That way, even the "wb" version of the file can be placed into same file, and the merging instructions could just try to check for version and use older merging method if version is older, use latest version if version is correct or absent (if no version, assume latest), or if version is way older than what you support, choose to print an error message or something.  I can try to do it in the next attempt at merge, but need to confirm with you:

So is this the right idea?:, if version is 1011 (any range?), use the _wb versions of the files where they exists?  Other-wise use the latest one ( just 1127, or can we put  "version"  > 1011 or "version" not specified).  Which means that if version < 1011, we can choose not to do anything.



EDIT: Note sure if I am right about this observation, since I haven't looked into the code for details:
it seems that after advance forward command is issued, the center of the formation is not updated.  So when I use the hold F1-F1 (Hold Position) key to set the position flag some distance away, instead of formation going there, it forms up at some displaced position.



EDIT2: ok, this is the combined pack, which does Warband and Vanilla injecting in the same source files (yeah, no more manual file renaming, score 1 for lazy mod users!).  Built and tested for warband and not for vanilla (I don't have module system for vanilla atm).  Prob need play-testers to confirm no prob.  Other than the hold-F1-F1-release don't make formations go to the highlighted flag correctly, other parts seems to be ok, including enemy using formations (now those cowards will wait in line if you army is too strong).  instructions in readme, but below's a cut-pasted version for quick reference:

http://www.filedropper.com/mmformationsmodmultiversion

This archive contains motomataru's formations + formAI, combined repacked for ModMerger 0.2.1 or Warband and Vanilla

initial wrapping by sphere (so if there are wrapping mistakes, it's probably my fault)


Installation (Warband and Vanilla)

1) You will need to install ModMerger 0.2.1 (not included in this archive)
http://www.mbrepository.com/file.php?id=2151

2) Put all the the files in this archive in the module system directory

3) Include the mods in modmerger and set module system version (determine if using warband or vanilla) as follows:

3a) Edit modmerger_options.py, put "formations" into mods_active list (or create one if there isn't a mods_active list)

3b) Add "formAI" into the "mods_active" list if you want to enable ai to use formations

E.g.

mods_active = [
  "formations",  # motomataru's formations v3   
    "formAI",      # motomataru's formations v3 AI extension.  Comment this line out if you don't want ai to use formations
]


3c) (Optional) If you are not building using the current module system, in modmerger_options.py, look for "module_sys_info={...}"  or if not found, create a new one.  Add/update a new key, "version" as follows:

E.g.

module_sys_info = {
        "version": 1127,  # version of module system (not game). version <= 1011 will be regarded as vanilla
}

The value for version is simply you module system (NOT GAME)'s version with the periods removed.

If "version" is left out or "version" > 1011, we will assume that it is "warband".

4) Build (and profit... or not) :wink:
 
sphere said:
hmm, then I means i may have been messing around with mixed version source? (I actually used _wb versions for the other files).  wondered why it still seem to work... LOL... think I'll do another merge from scratch leaving out the wb files for now.

That's correct. For my 8/5 release, I removed the "_wb" extension for the Warband files (making Warband the "default") and added a "_mb" extension for the Mount&Blade alternative files (making them the "alternative version").

sphere said:
BTW, I was thinking maybe I can try to keep a variables in an option file somewhere (probably modmerger_options.py for the latest version) for user to set  (e.g. "version" : 1127), so when writing your own injection code, you could do things like check if the game is warband (probably when "version" > 1011) or if it is the latest warband that some code supports (e.g. if only supported after 1125, then check for "version" >= 1125).  That way, even the "wb" version of the file can be placed into same file, and the merging instructions could just try to check for version and use older merging method if version is older, use latest version if version is correct or absent (if no version, assume latest), or if version is way older than what you support, choose to print an error message or something.

Exactly what I was thinking. I'm also looking ahead to a "nightmare" scenario in which a future Taleworlds module system release messes with one of my mods' "handles" for modmerger. Then we'll need to switch for multiple Warband versions!

BTW, doesn't the module system have a version number stored in a global or constant somewhere? That would be more reliable than the end-modder figuring it out...

sphere said:
So is this the right idea?:, if version is 1011 (any range?), use the _wb versions of the files where they exists?  Other-wise use the latest one ( just 1127, or can we put  "version"  > 1011 or "version" not specified).  Which means that if version < 1011, we can choose not to do anything.

Almost. "if version is 1011 (any range?), use the _mb versions of the files where they exist" and "if version > 1011, we can choose not to do anything."

sphere said:
EDIT: Note sure if I am right about this observation, since I haven't looked into the code for details:
it seems that after advance forward command is issued, the center of the formation is not updated.  So when I use the hold F1-F1 (Hold Position) key to set the position flag some distance away, instead of formation going there, it forms up at some displaced position.

One of the fixes in 8/5 post. Now, when only one formation is placed with Hold-F1, it will center at the given position. For multiple (all) formations, they will place as if the player is at the given position.

sphere said:
EDIT2: ok, this is the combined pack, which does Warband and Vanilla injecting in the same source files (yeah, no more manual file renaming, score 1 for lazy mod users!). 

Hey, that's me! :smile: I'll go over it in the next three days (weekend chores, you know)...

@othr
Thanks for the link. I'll check it out...
 
BTW, doesn't the module system have a version number stored in a global or constant somewhere? That would be more reliable than the end-modder figuring it out...

None that I could fine.  I ran several in-file search for all the files.  The only "version" that comes is on the archive file module system arrives in.  I even tried getting the target module path from module_info and parse the module.ini file.  But then I realised that even if a version is there, it doesn't guarantee the "version" of the module system itself.

So I gave up and put a variable and let the USER of the module system decides what version of the module system are they really using.  If the dev decides to embed the version number in the future, I can alter the scripts to pick it up and put it in the current variable name I choose, so that solves the "backward compatibility"...  :mrgreen:
 
Motomataru,

I have a quick question!  I have some troops in the mod whose main purpose is to toss javelins and other sharp objects at the enemy.  They are treated as 'archers' however their range is rather short, is there any way I can make factions with this type of troop advance closer with the javeliniers?  Right now they think they're archers and stop advancing while still way too far away.
 
othr said:
I have a quick question!  I have some troops in the mod whose main purpose is to toss javelins and other sharp objects at the enemy.  They are treated as 'archers' however their range is rather short, is there any way I can make factions with this type of troop advance closer with the javeliniers?  Right now they think they're archers and stop advancing while still way too far away.

Unfortunately, there's no support right now in the code. I suppose we could do something like I did for horse archers -- have the archer unit behave differently depending on its majority equipment. The faction-specific route would require a foundation to be designed and laid, but I have seen a need for it. In Brytenwalda, for example, only Saxon and I think other Germanic invaders ought have access to the shieldwall.

In a sense, I've only laid the barest groundwork for the AI. Partly because I'm adhering to the three-class division for non-player troops. Partly because of the sheer breadth of the subject. The AI doesn't quite fit Brytenwalda, for example, not only for the javelin issue but because cavalry was pretty much mobilized foot-soldiers until the invention of the stirrup. They rode up and shot/threw things or got off their horses to make an infantry formation, only charging with spears when the enemy had routed. Back then, it was basically mounted hunting applied to battle.

EDIT: What about not guaranteeing ranged for javeliners, so they end up in infantry?
 
Then they won't all have javelins, hrm.

What does this constant control AI_firing_distance?

I added this in team_field_ranged_tactics which may or may not make them behave the way I want:

This piece to obtain the faction:
Code:
(team_get_leader, ":fleader", ":team_no"),
(agent_get_troop_id, ":fleader_troop", ":fleader"),
(store_troop_faction, ":ffaction", ":fleader_troop"),

then later on:

Code:
(else_try),
  (assign, ":shot_distance", AI_firing_distance),
  (try_begin),
    (eq, ":ffaction", "fac_kingdom_2"), # this is the javelin heavy faction
    (assign, ":shot_distance", 2500),
  (try_end),

It seems like it did the trick but there is lots of code to read to understand what this did exactly.
 
othr said:
Then they won't all have javelins, hrm.

Yeah, I was coming out of a Brytenwalda mentality. Since heavy armor is not common, javeliners are not really auxillary. Most infantry is light to medium, and they all tend to take something to throw.

othr said:
What does this constant control AI_firing_distance?

That is the number of cm AI ranged troops try to maintain to the average position of the enemy.

othr said:
I added this in team_field_ranged_tactics which may or may not make them behave the way I want:

This piece to obtain the faction:
Code:
(team_get_leader, ":fleader", ":team_no"),
(agent_get_troop_id, ":fleader_troop", ":fleader"),
(store_troop_faction, ":ffaction", ":fleader_troop"),

then later on:

Code:
(else_try),
  (assign, ":shot_distance", AI_firing_distance),
  (try_begin),
    (eq, ":ffaction", "fac_kingdom_2"), # this is the javelin heavy faction
    (assign, ":shot_distance", 2500),
  (try_end),

It seems like it did the trick but there is lots of code to read to understand what this did exactly.

Yeah, it ought to work, except for the old problem of the leader getting killed. In get_default_formation() from my most recent release, I added a loop through agents to get faction from ordinary troops. I found out Warband did complete the faction info for ordinary troops.
 
Sorry Motomataru, there is one more thing I'd like to ask then I'm going away (I promise).

The wedge and later the diamond formations were utilized by cavalry because they allowed them to change direction rapidly without breaking the formation.  They were not charging formations.

A lancer charge would start far away from the enemy formation with the lancers advancing slowly in a loose 2 rank formation.  At around 100m away from the enemy they would slowly start picking up speed, the 2nd rank would join up with the 1st rank to fill in for any casualties and to form a tight line, so tight in fact that the knees of the lancers would nearly touch.  This line would then lower their lances and crash into the enemy formation.  Lances would either break or be discarded after this point and they would switch to other weapons.  If the enemy formation didn't break, only then would they fall back, reform and try again.

The cavalry AI makes them really vulnerable, they ride through the infantry with their shields raised most of the time.  So I'd like to have cavalry charge in a tight line, then I'd like them to abandon their formation and just do whatever they please at this time.

Can you please give me some pointers on how to achieve this?

 
Back
Top Bottom