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

Users who are viewing this thread

Caba`drin said:
motomataru said:
Now as far as TROOP level AI switches, this would involve more thought & effort & a troop slot...

Maybe it wouldn't need a slot...might a caveat in cf_valid_formation_member that, by troop ID, makes it so bandits (and perhaps green recruits) are not valid formation members work?

imho, bad idea.  troop is just a template for agents for non-heroes.  Anything that troop have should only be taken as sample or average for armies using that troop.  Using the information can be tricky. e.g. faction of a regular troop could be the ORIGINAL cultural faction of the troop, not necessary that the agent based on the troop is fighting for that faction.

A better way is to deal with this at party level.  i.e. best if the overal strategy capability and preference can be set/get from party level.  Then can have better control. e.g. usually bandit parties are unorganized perhaps due to the fact that they don't have the capability to choose a strategy, so they do their mad rush.  But say if some mod introduce some bandit king (hero), then the bandit party : same party type etc, but now lead by hero, will have slots set so that capable of some strategy which can be determined by hero's tactics skill + army's penalty/bonus (e.g. bandits and outlaws may have penalty on hero's skill due to being unorganized. whereas some very organized troop type may give a small bonus, and will actually be capable of some strategy (translate to some formations accessible) even when not lead by hero.

In short, strategy (includes formation chosen if any), should be a function of the party's capability as well as preference.  The handling should best be common for all party types (adjustable by slots or default values), instead of hard-coded for specific troop/party types.
 
othr said:
I'm anxiously awaiting your new release motomataru! :smile:

Nothing major -- I'm holding off until the release of Brytenwalda 1.0 for stability's sake. But with this exercise with having non-kingdom troops opt out, I did discover that I had put in the wrong function for getting troop faction. I tend to copy & paste, thinking I save time and improve accuracy, but this is the second serious oversight I've found in my code in two weeks...

@Caba`drin: AI actually is more than formations. Unformed troops will actually follow AI in Native line formation (formation_none). E.g., sea raiders under AI won't spread out so much as they charge up, limited by an AI function meant to keep fancier formations together under the same circumstances.

@sphere: I was looking at the troop slot so a modder could put in EXCEPTIONS to the party line (so to speak). Like for horse archers, javeliners, ninja, the Rhodoks' Varangian guard...

I did put in a hard-coded exception for deserters, figuring they've had military training and so are exempt from the non-kingdom opt-out. Also, I ended up putting the faction search to run from the start of battle -- running multiple try_for_agent every second turned out to visibly worsen fps, and the information does not need to be constantly updated.
 
I just had a small revelation (now that BW 1.0 is being released today, and I'm thinking ahead a little):

Since modmerger writes compile-dynamic code, I can use it to write whole functions, like loading tuples into slots. So now, instead of demanding that a modder using my code find and modify a setup script, I just have him load a tuple and modmerger does the rest. In other words, what Taleworlds does with tuple-to-text for runtime, we can do (but to script-code) for compile.

So now I can have a tuple like
#faction, default formation, battle opening... =
[[Swadian, ranks, cavalry charge],
[Khergit, none, arrow volley],...
]

and have modmerger insert the faction slot load lines in a waiting script shell. Similarly, I can have it load compile-time available info like weapon length into item slots so I can (finally) have it available at run-time.

This sort of solves my fixed array difficulties. It's a tuple-to-slot translator.

A similar strategy can be used to generate any such long, repetitive scripts. Hm.
 
motomataru said:
I just had a small revelation (now that BW 1.0 is being released today, and I'm thinking ahead a little):

Since modmerger writes compile-dynamic code, I can use it to write whole functions, like loading tuples into slots. So now, instead of demanding that a modder using my code find and modify a setup script, I just have him load a tuple and modmerger does the rest. In other words, what Taleworlds does with tuple-to-text for runtime, we can do (but to script-code) for compile.

So now I can have a tuple like
#faction, default formation, battle opening... =
[[Swadian, ranks, cavalry charge],
[Khergit, none, arrow volley],...
]

and have modmerger insert the faction slot load lines in a waiting script shell. Similarly, I can have it load compile-time available info like weapon length into item slots so I can (finally) have it available at run-time.

This sort of solves my fixed array difficulties. It's a tuple-to-slot translator.

A similar strategy can be used to generate any such long, repetitive scripts. Hm.

now you get it :wink:

compile-time stuff can do a lot of stuff.  In fact, you can make use of any of the module*.py data. e.g. write a script that parses module_items.py and classify the items there to be hooked up to strategy.  so that formations can work with ANY mod with different item definitions, but just incorporating the info from other modules at run-time.

catchline: if it makes you do less work, then it has the potential of becoming a good idea.

EDIT: pertaining to what I think you want to do, one way is to parse module_troops.py for the regular non-hero troops and then classify them according to their equipment and whether they are mounted or not.  so we don't have to hardcode the troop types to be used with each formation options, but rather it will be derived from whatever troop definitions is avaialble during build time. iow, say I add a new troop which is mounted and is primarily armed for melee, it will automatically be included in formations as applicable for cavalry charge (but say if lightly armored and have ranged, formations may want to classify it as mounted skirmishers?)

the price (there's always a price) is that the processing will take up some cpu resources making building module a little slower (esp when it is called multiple times, since each process_*.py called in build_module.bat is actually an independent operation)
 
EDIT: pertaining to what I think you want to do, one way is to parse module_troops.py for the regular non-hero troops and then classify them according to their equipment and whether they are mounted or not.  so we don't have to hardcode the troop types to be used with each formation options, but rather it will be derived from whatever troop definitions is avaialble during build time. iow, say I add a new troop which is mounted and is primarily armed for melee, it will automatically be included in formations as applicable for cavalry charge (but say if lightly armored and have ranged, formations may want to classify it as mounted skirmishers?)

Now this is what I like to hear!
 
This kind of parsing and python-list-to-slots automatic script generation was first developed by rubik for his autoloot algo. we are using it extensively in an optimized form in TLD.
Really helps with data management, as apart from using original lists you can also create your own additional python lists containing data, and not have this data scattered in scripts. It increases lag at gamestart though due to all the set_slot scripts  :smile:
 
Oh...I like this. Capturing weapon length and itp_twohand from the items and slotting that would be mighty useful. And slotting troops melee vs ranged when mounted, heavy vs light infantry vs spears/pikes. This indeed would reduce the need for subsequent try_for_agent loops at a mission start. Very interesting!
 
only problem I find with the tuple to slot approach is that it is usually done at game_start, so hard to update an existing save game, unless an alternate way is available to trigger the updating of the slot data.  I tried implementing a lazy initialization myself (does a check for global indicating the "version" of some data, and if missing or outdated, calls a script to reinitialize all the data) and though it seems to work, it does have some problems:

1) have to check (and update) before use
2) more complicated if it is dependent on other data types like items. e.g. we;ve initialized items before, but a recent modification adds more items, or change existing items. Need a way to detect that item data is changed (adding new items is easy to detect by tracking total number of items) and perform initialization again.
3) an alternate method is to perform a bruteforce update periodically.  But this results is wasted processing if nothing is changed.

Was wondering how other people solve similar problems like this?

anyway, if BTK switches to using tuple to slots approach, putting it just in gamestart will probably break save-games in the future, unless alternative way to initialize the data is available.

Just for reference, another method I've used before is a pseudo-slot via scripts.  I.e. the values instead of initialized in slots, is stored hard-coded in a function, so no slots nor initialization is required.  The script functions are programatically generated by parsing the tuples in python but are fixed once the module is built.  It has benefit of not requiring new slots, initialization (so 100% save-game compatible) but could have a slight performance impact if there are too many if-else cases in the generated functions (though can be possibly optimized to log N by generating scripts performing binary-search)

EDIT: on second thought, if this is only required in battle, then force calling the update script during battle initialization may solve all problems. no need to put in game_start at all, and ensure that future changes to items/troops will not break anything.
 
Any chance I can download your latest release Motomataru?  I'm going to make a new version of my mod and would like to include whatever bug fixes you have made.
 
othr said:
Any chance I can download your latest release Motomataru?  I'm going to make a new version of my mod and would like to include whatever bug fixes you have made.

Sorry not to report its update.

http://www.mbrepository.com/file.php?id=2207

I recommend setting the AI archer clock in mission_templates to every FIVE seconds instead of ten. Moves the battle along better (will be in my NEXT release).

I.e., try

Code:
(store_mod, reg0, "$ranged_clock", 5),

I haven't found an out-and-out bug in that release yet, though I'm not sure I'm happy with the cavalry AI either...
 
I think I know what's going on with cavalry. I'd adopted my player hit & run tactics, but in formation cavalry bungles up. Warband has added individual cavalry troop hit&run (though it can be greatly improved, like clearing the target before turning back).

But I don't have to throw out all that great code I wrote for identifying and accessing targets -- I just tweak hit & run into seek & destroy. Then add the grand charge. As far as considerations for archers during the grand charge go, it's basically move 'em back to make room for the charge and then d* the arrows, full speed ahead!

So the logic I propose is:

If cavalry has no threats, do a grand charge
--setup archers at long range (80m) instead of medium (40m)
--undo cavalry formation and HOLD 60m from enemy (20m in front of archers)
--once 80% of cavalry in line AND archers set up, change HOLD position to average enemy position
--once >0% of cavalry arrives to melee position, order CHARGE
--if enemy avg position shifts > 40m away from cavalry average position, reset (if not mopping up)...

Else if cavalry has a target
--use current logic BUT
--once >0% of cavalry arrives to melee position, order CHARGE
--if target avg position shifts > 40m away from cavalry average position, reset (if not mopping up)...
 
I found one problem with the update.  I assume in Brytenwalda troops are assigned faction in the troops module.  Warband native doesn't do that (as far as I know) and in my mod some troop trees are shared between factions so most troops are assigned the commoners faction.  That made formations not work for me.

I had to chage module_mission_templates.py, where you calculate the average faction for a team:

Code:
# Start troops in formation
	(0, formation_delay_for_spawn, ti_once, [], [
		(get_player_agent_no, "$fplayer_agent_no"),
		(agent_get_team, "$fplayer_team_no", "$fplayer_agent_no"),
		
		#get team fixed data
		# (assign, ":team0_avg_faction", 0),
		# (assign, ":team1_avg_faction", 0),
		# (assign, ":team2_avg_faction", 0),
		# (assign, ":team3_avg_faction", 0),
		(assign, "$team0_size", 0),
		(assign, "$team1_size", 0),
		(assign, "$team2_size", 0),
		(assign, "$team3_size", 0),
		(try_for_agents, ":cur_agent"),
			(agent_is_human, ":cur_agent"),
			(agent_get_team, ":cur_team", ":cur_agent"),
			#(agent_get_troop_id, ":cur_troop", ":cur_agent"),
			#(store_troop_faction, ":cur_faction", ":cur_troop"),
			(try_begin),
				(eq, ":cur_team", 0),
				#(val_add, ":team0_avg_faction", ":cur_faction"),
				(val_add, "$team0_size", 1),
			(else_try),
				(eq, ":cur_team", 1),
				#(val_add, ":team1_avg_faction", ":cur_faction"),
				(val_add, "$team1_size", 1),
			(else_try),
				(eq, ":cur_team", 2),
				#(val_add, ":team2_avg_faction", ":cur_faction"),
				(val_add, "$team2_size", 1),
			(else_try),
				(eq, ":cur_team", 3),
				#(val_add, ":team3_avg_faction", ":cur_faction"),
				(val_add, "$team3_size", 1),
			(try_end),
		(try_end),
		(try_begin),
			(gt, "$team0_size", 0),
      (team_get_leader, ":team_leader", 0),
      (agent_get_troop_id, ":leader_id", ":team_leader"),
      (store_troop_faction, "$team0_faction", ":leader_id"),
		(try_end),
		(try_begin),
			(gt, "$team1_size", 0),
      (team_get_leader, ":team_leader", 1),
      (agent_get_troop_id, ":leader_id", ":team_leader"),
      (store_troop_faction, "$team1_faction", ":leader_id"),
		(try_end),
		(try_begin),
			(gt, "$team2_size", 0),
      (team_get_leader, ":team_leader", 2),
      (agent_get_troop_id, ":leader_id", ":team_leader"),
      (store_troop_faction, "$team2_faction", ":leader_id"),
		(try_end),
		(try_begin),
			(gt, "$team3_size", 0),
      (team_get_leader, ":team_leader", 3),
      (agent_get_troop_id, ":leader_id", ":team_leader"),
      (store_troop_faction, "$team3_faction", ":leader_id"),
		(try_end),

 
othr said:
I found one problem with the update.  I assume in Brytenwalda troops are assigned faction in the troops module.  Warband native doesn't do that (as far as I know) and in my mod some troop trees are shared between factions so most troops are assigned the commoners faction.  That made formations not work for me.
I thought WB did finish assigning faction troops to factions, but at any rate, the leader code is in get_default_formation called two lines after the section you changed -- kind of an artifact from when I had the troop code there as well. You'll probably want to comment out the parallel code in get_default_formation that reassigns the globals.

Your code will set a default formation for a team for the entire battle. I'm heading that direction anyway -- these functions will someday load globals to track all that stuff -- but for now default formation may change during battle as leaders die off and troop faction may assert itself. To tell the truth, troops could legitimately behave according to the faction of the: leader's culture, leader's kingdom, or troop culture (which may not be constant from one trooper to the next). Perhaps troop culture should dominate if uniform and kingdom-related, otherwise leader culture/allegiance.
 
motomataru said:
othr said:
I found one problem with the update.  I assume in Brytenwalda troops are assigned faction in the troops module.  Warband native doesn't do that (as far as I know) and in my mod some troop trees are shared between factions so most troops are assigned the commoners faction.  That made formations not work for me.
I thought WB did finish assigning faction troops to factions, but at any rate, the leader code is in get_default_formation called two lines after the section you changed -- kind of an artifact from when I had the troop code there as well. You'll probably want to comment out the parallel code in get_default_formation that reassigns the globals.

...BUT get_default_formation not called when the kingdoms_only flag is tested. Sorry guys!  :oops:

This fix and others in latest update...
http://www.mbrepository.com/file.php?id=2207
 
Hi motomataru.. A question here about your formations mod:

When you have a large amount of archers in your troop.. they are positioned in a very long row, too long, so it seems unreal. Could it be possible to add a key/formation to make archers to get a 2-rows or a 3-rows formation?
I mean instead of :
(Archer = ! )
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

but:
!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!

?
Thanks!
 
Everthen said:
Could it be possible to add a key/formation to make archers to get a 2-rows or a 3-rows formation?

Hi Everthen!

I was unsure of whether back ranks of archers would fire. From what I've since seen of javelins in infantry formations, the rear rank will sometimes attempt a shot, especially if the spacing is not close.

At any rate, in script_form_archer there is code to stagger archers that I commented out (two ranks). You could uncomment that or go to the mission_templates triggers and bring down the spacing a step or two. Just be aware that the closer the archers are spaced, the more difficult it is for other troops to walk through them.

The AI archers use vanilla M&B Hold for simplicity's sake, so their only option is to change spacing -- also in triggers.

#Edit: You know, now that I look at it, the stagger gives three rows, and you have to decrease archer spacing regardless.
--M
 
THanks for your answer, although I know almost nothing about editing..
I was just wondering if it could be possible.. I imagine there should be some space among rows of archers so they could fire properly, but... perhaps it could be good to have 2 or 3 "kind" of archers so we can put them in rows with enough space among them. Couse seriously, when leading a 100 party with about 40 archers, they stack  all in a row covering almost the whole map side :sad:

As if you were at point X in battle map and say to Archers group 1: Stay here (HOld this possition= F1->F1), .. then you advance 12 meters and say to archers group 2: Stay here (Hold this possition ). So you could have 2 separated row of archers. THis way:

!!!!!!!!!!!!!!

(10-15 meters gap)

!!!!!!!!!!!!!

I´m also a newbie here, so sorry but I don't know what you are talking about :sad:
 
Everthen said:
but... perhaps it could be good to have 2 or 3 "kind" of archers so we can put them in rows with enough space among them. Couse seriously, when leading a 100 party with about 40 archers, they stack  all in a row covering almost the whole map side :sad:
Formations really doesn't do anything for archers more than Native Hold does, other than make them play nicely with infantry and cavalry that ARE in formation.

You can always assign other archer troops types to the other battlegroups, then set them up with the Hold-F1 or battle display. Just be aware that M&B will start these extra battlegroups to far right of your starting formations.

Oh, and let me know if archers 12m behind another line on a level surface will attempt to fire, and whether they cause friendly fire casualties. I died in one battle when I inadvertantly wandered in front of one of my Jedi that was just unleashing the Force!

Edit: There are a couple of these disabled sections in my code. I'll put switches on them for modders to have at least the option.
 
Back
Top Bottom