Results 1 to 6 of 6

Thread: Scripted 'Historical' Battles (v3.0)

  1. #1
    Commissar Caligula_'s Avatar The Ecstasy of Potatoes
    Join Date
    Dec 2013
    Location
    The alcoves in the Koningin Astridpark
    Posts
    5,876

    Default Scripted 'Historical' Battles (v3.0)

    Have you ever wanted to create the Battle of Winterfell in Total War: Attila? The Battle of Agincourt? The Sack of Rome? To provide players with a scenario full of cutscenes, reinforcements, and unique objectives? Well now you can, with a new tutorial created by Caligula on how to script 'historical' battles. This tutorial was made possible by DETrooper, Farfadet, Elessar, DrunkFlamingo, and Case who provided immeasurable support by creating the unique scripts in the accompanying Historical Battle Template. Check out the examples below, and create something unique!

    Scripted Battle Examples


    The Dawnless Days (Battle of Five Armies and Battle of the Fords of Isen)
    The Dawnless Days






    Ambush in Ithilien
    Ambush in Ithilien


    The War of Elves and Sauron
    The War of Elves and Sauron


    The Battle of the Bastards
    The Battle of the Bastards



    What You Can Do
    I have made a number of historical battles in which I have sought to include unique gameplay mechanics. Examples of these are detailed below:

    The Battle of the Bastards has the following features...
    • A custom battle map.
    • A one-minute long cutscene with custom audio from the Battle of the Bastards episode of Jon, Davos and Tormund talking about their battle plan, and a visual overview of the map.
    • Stark units positioned in the treeline on one side of the field with Bolton soldiers advancing towards them from the other side.
    • Knights of the Vale who arrive as reinforcements after 4.5 minutes.

    The First Battle of the Fords of Isen features four difficulty settings. The difficulty chosen by the player affects the amount of friendly and enemy units that spawn.
    • Normal
    • Hard
    • Legendary
    • Legendary Plus (the camera is restricted, no mini-map, and no slo-mo)

    Ambush in Ithilien includes...
    • a 2 minute cutscene (skippable) that features custom narration, music, and sound effects
    • the player must engage in a difficult fighting retreat as increasingly larger waves of Haradrim advance upon you
    • the player must defend against cavalry, infantry, archers, and mumakil

    You can do a lot of other stuff, check the vanilla historical battles from Attila and Rome 2; and I would highly advise that you check out this documentation created by CA.

    Required Resources




    Step-by-Step Tutorial
    Step 1 (Basic Data Entry)
    Spoiler Alert, click show to read: 
    [1] Refer to the post below this one to learn what each table/entry does, and how they affect your battle. Constantly refer back to this post throughout this tutorial.

    [2] Download the Historical Battle Template that DETrooper, Farfadet, Elessar, DrunkFlamingo, Case and I have created. Use PFM or RPFM to open it up and use it as the basis for your mod.

    [3] Go to all of the following tables/entries and replace the template_ and tut2_ prefix for each table with the prefix for your mod. battle. Eg change template_historical_battles to mktw_historical_battles and tut2_battle.xml to agincourt_battle.xml
    db
    battles_tables
    historical_battles_ui_locations_tables
    script
    tut2_battle.xml
    tut2_cutscenes.lua
    tut2_declarations.lua
    tut2_start.lua
    text
    template_historical_battles.loc


    [4] Go to all of the following tables and edit them.
    campaign_maps
    main_attila_map.png
    If you want a custom map as the background of the historical battle selection screen, then you need to follow the following steps.
    db
    battles_tables
    In this table you put the name of the battle, where the battle.xml is found and where the preview screenshot is found.

    The only entries in this table you will need to change are:
    • key; (the name of the battle)
    • specification; (the path of the battle.xml)
    • screenshot_path (the path of the preview screenshot).
    historical_battles_ui_locations_tables
    So now that you have done that, you want to get your historical battles located in the right area on the map.

    lua_scripts
    frontend_hbs.lua
    This lua script contains a list of the historical battles that may be played. Below is the relevant section. Change tut2_template to the name of your battle.
    Code:
    Historic_Battle_List = {
    	"Catalaunian_Plains",
    	"Utus",
    	"Ravenna",
    	"Frigidus_River",
    	"Cap_Bon",
    	"Samarra",
    	"Cartagena",
    	"Soissons",
    	"Ad_Decimum",
    	"Adrianople",
    	"Dara",
    	"tut_tutorial_battle",
    	"tut2_template"
    };
    script
    tut2_template
    screenshot_small.png
    This is a 512x256 png file that acts as a little preview image of your historical battle. Here are three examples I've used, and two pictures of them actually in-game.
    Example 1
    Example 2
    Example 3

    In Game 1
    In Game 2
    (prefix)_battle.xml
    Scroll down to the very bottom and change
    Code:
    (<battle_script prepare_for_fade_in="false">tut2_start.lua</battle_script>)
    to the name of your battle.

    text
    db
    battles.loc
    This is a text file where you put in the name, and the description of your historical battles. For example...

    battles_localised_name_battleofthebastardsBattle of the Bastards
    battles_description_battleofthebastardsThe Bastard of the Dreadfort and Warden of the North, Ramsay Bolton, holds Winterfell – the ancestral seat of House Stark. Jon Snow, the Bastard of Winterfell has come to reclaim his home at the head of a ragged army of Wildlings, and bannermen loyal to his cause. The bastards will clash outside the walls of Winterfell, where only one may emerge victorious.


    [5] Go back to (prefix)_battle.xml and we're going to set up what factions are involved in the historical battle; what map the battle will be fought on; what weather and lighting will be present; what the victory condition is; where the deployment area is; and how big the playable area is.
    script
    tut2_template
    (prefix)_battle.xml
    The Factions
    The following example comes from the Battle of the Bastards. Look at the alliance id and <army> tags below. You can see that House Stark and the Vale are two factions on the same team (alliance 0). The Vale is controlled by the AI. You can also see that the two factions have different deployment areas.

    The faction/alliance that is listed FIRST in the battle.xml will always be controlled by the player.

    You may want to check out other historical battles from Rome 2 or Attila to discover different victory conditions, or ways of doing the deployment area. I generally just leave the victory condition as to kill or rout all enemy units and the deployment area to be bigger than the entire map. This means units can spawn anywhere, and the loading screen won't show a specific deployment area which allows the location of reinforcements/enemies to be a surprise. This makes it impossible to position units with the guerrilla deployment trait however.
    Code:
    	<alliance id="0">
    	
    		<army>
    		
    			<faction>historical_house_stark</faction>
    			
    			<deployment_area>
    				<centre x="160.00" y="-170.00"/>
    				<width metres="250.00"/>
    				<height metres="125.00"/>
    				<orientation radians="0.00"/>
    			</deployment_area>
    			
    			<unit script_name="stark1" hide_prebattle="true">
    				<unit_type type="Historical_Jon"/>
    				<position x="160.70" y="-130.35"/>
    				<orientation radians="0.00"/>
    				<width metres="21.70"/>
    			</unit>
    		</army>
    
    		<army>
    			<faction>historical_vale</faction>
    			
    			<deployment_area>
    				<centre x="-330.00" y="-131.00"/>
    				<width metres="250.00"/>
    				<height metres="125.00"/>
    				<orientation radians="1.00"/>
    			</deployment_area>
    			
    			<unit script_name="valereinforcements1" hide_prebattle="true">
    				<unit_type type="Vale_Arryn_2_Heavy_Cavalry"/>
    				<position x="-250" y="-206"/>
    				<orientation radians="1"/>
    				<width metres="30"/>
    				<unit_experience level="4"/>
    			</unit>
    		</army>		
    		<victory_condition>
    			<kill_or_rout_enemy></kill_or_rout_enemy>
    		</victory_condition>
    		<rout_position x="0.00" y="0.00"/>
    		
    	</alliance>
    Battle Map
    Now you need to choose what exact battle map you want to use for your historical battle. You can choose to use a custom battle map, such as
    Code:
    	<battle_map_definition>
      <name>terrain/tiles/battle/assembly_kit/battle_of_the_bastards/battlefield</name>
    	</battle_map_definition>
    Or you can use a vanilla battle map, such as
    Code:
    	<battle_map_definition>
    		<name>Terrain/battles/main_attila_map/</name>
    		<tile_map_position x="0.089" y="0.094">/</tile_map_position>
    		<tile_upgrade>level1</tile_upgrade>
    		<tile_upgrade>escalation3</tile_upgrade>
    	</battle_map_definition>
    It is recommended that you just test random custom battles to find the battle map you’d like to use.
    If you use a vanilla siege map, you need to decide whether you want to use an upgraded version of the map, and whether there should be siege escalation (destroyed buildings/walls).

    If you want to use a type of battle map other than a normal land battle (for example a port, ambush, river crossing, siege), you need to change the following entry
    Code:
    	<battle_description>
    		<type>land_normal</type>
    	</battle_description>
    The options available to you are:
    Code:
    coastal_battle
    land_ambush
    land_bridge
    land_normal
    naval_blockade
    naval_breakout
    naval_normal
    port_assault
    settlement_relief
    settlement_sally
    settlement_standard
    settlement_unfortified
    unfortified_port
    You also need to consider how big you want the playable area dimensions to be. CA's documentation says the maximum size is 1950. You may tweak this if you want to remove access to certain parts of a pre-existing map, eg for "Muster at Dunharrow" I made the playable area smaller and slightly offset so the player couldn't use a side passage to get behind Dunharrow.
    Code:
    	<playable_area dimension="1500" centre_x="250" centre_y="-25" />
    Weather
    You can also choose the precise weather that you want to occur in the battle, for example
    Code:
    	<weather>
    		<environment_key>weather\default\default\land\day\snow\snow_3_heavy.environment</environment_key>
    		<prevailing_wind x="1.00" y="0.00"/>
    	</weather>
    I don’t know what the prevailing wind does, it’s probably just for naval battles. Anyways, to choose the environment key you go to data.pack – weather and choose what type of weather you want. You have to test them one by one within the historical battle if you’re trying to get a precise one.

    The time_of_day, season and precipitation_type settings under <battle_description> do not seem to have any effect.

    Step 2 (Friendly Units)
    Spoiler Alert, click show to read: 
    Background Information
    Look at the code below. This example comes from the Battle of the Fist of the First Men from my Battles of the North mod.
    Code:
    			<unit>
    				<unit_type type="Wall_Watch_1_Jeor_Mormont"/>
    				<position x="-21.70" y="400.35"/>
    				<orientation radians="3.14"/>
    				<width metres="21.70"/>
    				<unit_experience level="0"/>
    				<general>
    					<name>2147363108</name>
    					<star_rating level="0"/>
    				</general>
    			</unit>
    As you can see here, the unit is a custom general unit for Jeor Mormont. It's x and y co-ordinates; orientation radians; width; experience level; and unique name are al listed. You can also do other things such as give it special abilities via script, or make it start at 50% strength.

    Width determines how stretched out the unit is/how many rows.

    In the Battle of the Bastards historical battle script, you may have noticed that the units look like this.
    Code:
    			<unit script_name="stark1" hide_prebattle="true">
    
    			<unit script_name="stark3">
    hide_prebattle="true" means that the unit will not appear on the loading screen at the start, so when they appear (eg due to a reinforcement script), it will come as a surprise to the plawyer.

    The reason I have unit script_name rather than just plain <unit> is because I have referenced this unit in a reinforcement script in that battle.

    Decide how your battle will work.
    • How many units will each side have? Eg 10 infantry, 4 cavalry, 5 archers.
    • What specific units will each side have? Eg 5 Palatina Guard, 5 Cohors, 2 Scout Equites, ect.

    Once you have worked that out go back to [prefix]_battle.xml

    [1] Go to the deployment area for your faction (the very first faction), and change the width and height metres to something insane, this will mean you can position units anywhere on the map. Eg:
    Code:
    			<deployment_area>
    				<centre x="100.00" y="-220.00"/>
    				<width metres="4000.00"/>
    				<height metres="4000.00"/>
    				<orientation radians="0.00"/>
    			</deployment_area>
    [2] Then delete all of the existing <unit> </unit> codes, and paste in the following code.
    Code:
    			<unit script_name="template_01">
    				<unit_type type="att_rom_palatina_guards"/>
    				<position x="0.00" y="-50.00"/>
    				<orientation radians="0.00"/>
    				<width metres="21.70"/>
    			</unit>
    [3] Copy and paste this exact line of code for the amount of units you want, eg 19 units. Change the unit script_name for each, eg template_01, template_02, template_03, ect.

    [4] Then replace the unit_type with the specific units you want, eg Cohors or Scout Equites

    [5] Then give the enemy faction a single unit. This is a custom unit I've made that cannot move, and has very high health. This means it won't interfere with you setting up your battle/cutscenes, and won't be killed off - prematurely ending the battle.
    Code:
    			<unit script_name="enemy_01">
    				<unit_type type="tutorial_placeholder_unit"/>
    				<position x="0" y="50.00"/>
    				<orientation radians="3.14"/>
    				<width metres="23.60"/>
    			</unit>
    [6] Now go to [prefix]_declarations.lua and create the SUnit script. This will tie all of the units together, and allow you to create orders for the units and position them.
    "Player" refers to the name of the army, and template_01 to the unit script_name in [prefix]_battle.xml.
    Ensure that the SUnit group, eg "SUnits_Template_All", matches the SUnit group referenced in [prefix]_start.lua function Start_Battle(). An example is provided below:
    Code:
    SUnit_Tutorial_01 = script_unit:new(Stark, "tutorial_01");
    SUnit_Tutorial_02 = script_unit:new(Stark, "tutorial_02");
    SUnit_Tutorial_03 = script_unit:new(Stark, "tutorial_03");
    
    SUnits_Tutorial_All = {
    	SUnit_Tutorial_01,
    	SUnit_Tutorial_02,
    	SUnit_Tutorial_03
    };

    Step 3 (Positioning Friendly Units)
    Spoiler Alert, click show to read: 
    Lets do the battle co-ordinates now.
    [1] Launch the mod, and your historical battle. After you finish loading, you will see all of your units on top of each other and a big "Start Battle" button. DO NOT click it.

    [2] Move all of your units to the positions you want them to be in at the start of your battle.

    [3] Once they are all positioned, click the "Start Battle" button, alt tab and go to C:\Program Files (x86)\Steam\steamapps\common\Total War Attila\data, and open Historical_Battle_Camera_log.txt. Each unit's position, orientation, and width will have been logged. The log will look like this:
    Spoiler Alert, click show to read: 
    Code:
    Log file does not exist, created new
    
    --------------------------------------------------------
    --------------------------------------------------------
    --
    --	HISTORICAL BATTLE CUTSCENE AND UNIT POSITION SCRIPT
    --
    --------------------------------------------------------
    --------------------------------------------------------
    
    Wednesday, 09/28/22 18:28:53
    	unit:1
    	<position x="160" y="-136"/>
    	<orientation radians="6.28"/>
    	<width metres="21.70"/>
    
    	unit:2
    	<position x="230" y="-136"/>
    	<orientation radians="0.01"/>
    	<width metres="21.70"/>
    
    	unit:3
    	<position x="160" y="-196"/>
    	<orientation radians="6.28"/>
    	<width metres="21.70"/>
    
    	unit:4
    	<position x="115" y="-220"/>
    	<orientation radians="0.01"/>
    	<width metres="27.00"/>
    
    	unit:5
    	<position x="130" y="-138"/>
    	<orientation radians="0.01"/>
    	<width metres="35.00"/>
    
    	unit:6
    	<position x="117" y="-196"/>
    	<orientation radians="5.90"/>
    	<width metres="21.70"/>
    
    	unit:7
    	<position x="205" y="-196"/>
    	<orientation radians="0.00"/>
    	<width metres="21.70"/>
    
    	unit:8
    	<position x="205" y="-220"/>
    	<orientation radians="0.01"/>
    	<width metres="27.00"/>
    
    	unit:9
    	<position x="195" y="-138"/>
    	<orientation radians="0.00"/>
    	<width metres="35.00"/>
    
    	unit:10
    	<position x="99" y="-136"/>
    	<orientation radians="6.28"/>
    	<width metres="21.70"/>
    
    	unit:11
    	<position x="71" y="-197"/>
    	<orientation radians="6.28"/>
    	<width metres="21.70"/>
    
    	unit:12
    	<position x="250" y="-196"/>
    	<orientation radians="6.28"/>
    	<width metres="21.70"/>

    [4] Now close Attila, and go to [prefix]_battle.xml of your mod.

    [5] Replace each unit’s position, orientation radians, and width metres code with the ones that have been generated in Historical_Battle_Camera_log.txt.

    [6] Save your mod.

    Step 4 (Enemy Units + Positioning Enemy Units)
    Spoiler Alert, click show to read: 
    Now we will do the same for the enemy units.
    [1] Go to [prefix]_battle.xml and copy everything between the <army> </army> tags for your faction. Save this in a separate text folder.

    [2] Now move everything between YOUR <army> tags to the bottom, so it is in <alliance id="1"> and everything from there to <alliance id="0">. This will make it so you are playing as the enemy.

    [3] Now repeat Step 2 (Friendly Units) and Step 3 (Positioning Friendly Units) for the enemy, except make sure that the position and orientation radians are as below:
    Code:
    				<position x="50" y="250"/>
    				<orientation radians="3.14"/>
    [4] In case you have forgotten, this means copy and paste a unit x amount of times on the same position, give the “enemy” faction a single tutorial placeholder unit, go in-game and set up the units, get their co-ordinates + orientation + width and paste this data into [prefix]_battle.xml.

    [5] Once you have done that, swap the <army> tags around again so you have your entire army with its co-ordinates, and the enemy has their entire army with their co-ordinates.

    Step 5 (Cutscenes)
    Spoiler Alert, click show to read: 
    [1] The way I set up a cutscene is to make all of the units spawn 50m backwards from the position I set them to in Steps 3 and 4, and then make them walk to the start position during the cutscene whilst I chain together shots of them walking. Alternatively, you can chain together a path of co-ordinates for units to walk (eg see Ambush in Ithilien cutscene.lua and the code below)
    Code:
    			SUnit_Cutscene_Harad_12.uc:goto_location_angle_width(v(-16, 955), r_to_d(2.81), 18.77, false);
    			SUnit_Cutscene_Harad_12.uc:goto_location_angle_width_q(v(-3, 933), r_to_d(2.60), 18.77, false);
    			SUnit_Cutscene_Harad_12.uc:goto_location_angle_width_q(v(3, 909), r_to_d(3.17), 18.77, false);
    			SUnit_Cutscene_Harad_12.uc:goto_location_angle_width_q(v(-1, 883), r_to_d(3.41), 18.77, false);
    			SUnit_Cutscene_Harad_12.uc:goto_location_angle_width_q(v(-11, 858), r_to_d(3.67), 18.77, false);
    [2] To set up a cutscene my way, go to [prefix]_cutscenes.lua and look at the following entries:
    Code:
    	local Cutscene_Intro = cutscene:new(
    		"Cutscene_Intro",				-- unique string name for cutscene
    		ga_player_01:get_unitcontroller(),		-- unitcontroller over player's army
    		2000,						-- duration of cutscene in ms
    		function() Start_Battle() end			-- what to call when cutscene is finished
    	);
    [3] 2,000 is the length of the cutscene in milliseconds (so 2 seconds). Change this to 100 (1/10th of a second) so that the cutscene will end immediately, but the units will still be walking to their position. This will let us put together the shots for our own cutscene.

    [4] Now look at "teleport_to_start_location_offset". I have added "--" to disable this function. Remove "--" to re-enable it. The -50 in location offset means the units start 50m behind their start position. Keep this (or make it longer/shorter, eg 100m). It will depend on the units of course, but it takes roughly 40 seconds for vanilla infantry to walk 50m. A 40s cutscene seems a good length.
    Code:
    	Cutscene_Intro:action(function() ga_player_01:teleport_to_start_location_offset(0, -50); end, 0);
    	Cutscene_Intro:action(function() ga_enemy_01:teleport_to_start_location_offset(0, -50); end, 0);
    [5] Now go to Cutscene_Intro:action(function() cam:fade(false, 0.5) end, 0); and disable this line by adding -- to the front of it. i.e. -- Cutscene_Intro:action(function() cam:fade(false, 0.5) end, 0);
    This will mean the camera does not take half a second to fade in. Once you have finished your cutscene, remember to remove the -- so it functions again.

    [6] Now save the mod and launch it. Click Start Battle, and immediately click “P” to pause it.

    [7] Move the camera to where you want the cutscene to start, and looking in the direction you want; click the button in the middle bottom of the screen to trigger the camera log script which will write down the co-ordinates that the camera was in at that time; start the battle; pause again after a certain amount of time, eg 5 seconds, and move the camera to where you want it to end up; and click the button again.
    These logs will be saved to "Historical_Battle_Camera_log.txt" in C:\Program Files (x86)\Steam\steamapps\common\Total War Attila\data in a format looking like this:
    Code:
    Camera Info:Tuesday, 09/27/22 18:16:45
    	Cutscene_NAME:action(function() cam:move_to(v(171, 121, -56), v(175, 13, 46), [CUTSCENE LENGTH #], true, [FOV #]) end, [START TIME #]);
    [8] It may be useful to open Historical_Battle_Camera_log.txt and write notes such as those below. These will remind you how long the cutscene should be. Make sure to save the file after each edit you make, so your notes are not overridden by the next set of co-ordinates. Eg:
    Code:
    	Cutscene_Intro:action(function() cam:move_to(v(-118, 272, -250), v(-81, 257, -277), 0, true, 35) end, [START TIME #]);
    	Cutscene_Intro:action(function() cam:move_to(v(-69, 261, -260), v(-101, 246, -292), 10, true, 33) end, [START TIME #]);
    From 0-10 seconds
    
    	Cutscene_Intro:action(function() cam:move_to(v(-54, 260, -250), v(-12, 251, -272), 0, true, 35) end, [START TIME #]);
    	Cutscene_Intro:action(function() cam:move_to(v(-36, 261, -242), v(5, 253, -265), 5, true, 33) end, [START TIME #]);
    From 10-15 seconds
    
    	Cutscene_Intro:action(function() cam:move_to(v(152, 274, -217), v(194, 258, -198), 0, true, 35) end, [START TIME #]);
    	Cutscene_Intro:action(function() cam:move_to(v(176, 275, -202), v(218, 260, -184), 5, true, 33) end, [START TIME #]);
    From 15-20 seconds
    [9] Rinse and repeat for the cutscene co-ordinates you want.

    [10] The final co-ordinates you need are for the shot that the cutscene will end on, and that players will be teleported to if they decide to skip the cutscene. This is broken into two parts – where the camera actually is, and where its looking. Eg the first set of code should be near the top, the 2nd set of code is the final cutscene shot.
    Code:
    	POS_Cam_Cutscene_Intro_Final = v(8, 285, -398);
    	Targ_Cam_Cutscene_Intro_Final = v(4, 275, -350);
    Code:
    	Cutscene_Intro:action(function() cam:move_to(v(4, 280, -362), v(3, 255, -320), 0, true, 35) end, 20000);
    	Cutscene_Intro:action(function() cam:move_to(POS_Cam_Cutscene_Intro_Final, Targ_Cam_Cutscene_Intro_Final, 2, false, 0) end, 20000);
    [11] Finally, change the duration of the cutscene at the start to however long your cutscene is. eg:
    Code:
    local Cutscene_Intro = cutscene:new(
    	"Cutscene_Intro", 		 -- unique string name for cutscene
    	ga_player_01:get_unitcontroller(), -- unitcontroller over player's army
    	22000 				 -- duration of cutscene in ms
    );


    Optional Extras
    Step 6 (Subtitles + Advisor)
    Spoiler Alert, click show to read: 
    [1] You can add subtitles to your cutscenes by editing scripted_subtitles_tables and scripted_subtitles.loc, then putting the cutscenes in [prefix]_cutscenes.lua.
    It is very self explanatory and easily worked out.

    [2] You can also add messages that pop-up mid-battle from the advisor. Eg when a general dies, when you’re winning, when the battle starts. You do this by editing advice_levels_tables; advice_threads_tables; advice_levels.loc; and [prefix]_start.lua.
    As above, this is very self-explanatory and easily worked out. Look at Att.HB.AD.001 for example. You MAY need to do advice_levels_tables in the Assembly Kit so it will automatically generate a key for you. Otherwise, just override a vanilla advice entry.

    [3] If you want to change the audio that plays, check this tutorial.

    [4] If you want the change what the advisor looks like, make sure the Porthole Quality is set to 3D in Graphics Settings and change att_advisor_monk.variantmeshdefinition.
    Unfortunately EVERY historical battle will use the SAME advisor, you can’t have a different advisor per battle.

    Step 7 (Difficulty Levels)
    Spoiler Alert, click show to read: 
    There are a number of interesting scripts that we have created and saved in script - _historical_battle_library. I will explain difficulty_script_remove_units_per_difficulty.lua and difficulty_script_prevent_reinforcements.lua

    [1] Decide whether you want:
    a) all the units to spawn at the start, but for the amount of units to be dependent on the difficulty you choose (eg -4 enemy units on easy difficulty; 0 change on normal difficulty; -4 friendly units on hard difficulty)
    OR
    b) You want extra units to arrive as reinforcements after a certain amount of time (which can also be dependent on difficulty, eg reinforcements only arrive on easy difficulty)
    Step 7a (difficulty_script_remove_units_per_difficulty)
    [1] If you want all the units to spawn at the start, but for certain units to be automatically killed at the start of the battle depending on the difficulty you choose, then add difficulty_script_remove_units_per_difficulty.lua to your battle, eg tut_tutorial_battle, alongside all your other scripts. Make sure to add your prefix to the start, eg tut_difficulty_script_remove_units_per_difficulty.lua

    [2] Now go to go to [prefix]_start.lua and add
    Code:
     require (battle_shortform .. "_difficulty_script_remove_units_per_difficulty");
    underneath
    Code:
    require (battle_shortform .. "_Cutscenes");
    require (battle_shortform .. "_Declarations");
    require (battle_shortform .. "_Reinforcements");
    [3] Now determine what units you want to remove on each difficulty level. Eg:
    Easy (1) Remove 2 Enemy Units
    Normal (0)Remove 0 Units
    Hard (-1)Remove 2 Friendly Units
    Very Hard (-2)Remove 4 Friendly Units
    Legendary (-3)Remove 6 Friendly Units
    [4] I have provided an example of what the above would look like in the template pack.

    [5] I bundle Easy and Normal together, and Very Hard and Legendary together by giving them the same options, and renaming the difficulty levels in random_localisation_strings.loc. You may want to do the same.

    [6] Make sure you do NOT remove the first unit in an army, this is the general. If you remove it, that army will immediately suffer a morale penalty as their general has died.
    Step 7b (difficulty_script_prevent_reinforcements)
    [1] If you instead want extra units to arrive as reinforcements after a certain amount of time, then:
    - replace [prefix]_reinforcements.lua with reinforcements_script.lua from _historical_battle_library; and
    - add difficulty_script_prevent_reinforcements.lua to your battle, eg tut_tutorial_battle, alongside all your other scripts. Make sure to add your prefix to the start, eg tut_difficulty_script_prevent_reinforcements.lua

    [2] Now go to go to [prefix]_start.lua and add
    Code:
    require (battle_shortform .. "_difficulty_script_prevent_reinforcements");
    underneath
    Code:
    require (battle_shortform .. "_Cutscenes");
    require (battle_shortform .. "_Declarations");
    require (battle_shortform .. "_Reinforcements");
    [3] This script is a bit more complicated.
    At the top of the new reinforcements script, it says "Isengard_Reinforcements_1_Countdown = 45000". This means that after 45 seconds this function (Isengard reinforcements) are called. You can also see that it takes another 0.5 seconds for the units to spawn. And then, after another 25 seconds the Isengard reinforcements will go to x103, z-171 and attempt to defend it in a 200m radius. This is a way of directing the AI towards a particular destination and telling it to attack anyone nearby.

    [4] If you want you can make a cutscene trigger when the reinforcements spawn.

    [5] If you look at [prefix]_difficulty_script_prevent_reinforcements you’ll see that:
    a. Isengard Reinforcements 1 ALWAYS spawn;
    b. Isengard Reinforcements 2 (which I have deleted) only spawn on Easy or Normal difficulty (1 or 0);
    c. Rohan Reinforcements only spawn on Very Hard or Legendary difficulty (-2 or -3).
    Last edited by Commissar Caligula_; January 07, 2024 at 05:22 AM.



  2. #2
    Commissar Caligula_'s Avatar The Ecstasy of Potatoes
    Join Date
    Dec 2013
    Location
    The alcoves in the Koningin Astridpark
    Posts
    5,876

    Default Re: Scripted 'Historical' Battles (v2.0)

    In the process of rewriting the entire tutorial
    Last edited by Commissar Caligula_; January 06, 2024 at 10:33 PM.



  3. #3
    Commissar Caligula_'s Avatar The Ecstasy of Potatoes
    Join Date
    Dec 2013
    Location
    The alcoves in the Koningin Astridpark
    Posts
    5,876

    Default Re: Scripted 'Historical' Battles (v2.0)

    I've recently updated the tutorial to v2.0, this is a first draft, so can you please give me feedback and whether it is clear enough for you to make a historical battle?

    The template pack now includes quite a few cool scripts including:

    • A script which makes it very easy way to position your units at the start.
    • A script which automatically logs the co-ordinates, width, and orientation of every unit when you start the battle.
    • A script which logs the camera's co-ordinates every time you press a certain button so you can create stunning cutscenes.
    • A script which lets you spawn reinforcements
    • A script which lets you kill off and/or damage certain units at the start of a battle, to make the difficulty level easier or harder
    • A script which lets you prevent certain reinforcements from spawning, depending on the difficulty level chosen



  4. #4
    Commissar Caligula_'s Avatar The Ecstasy of Potatoes
    Join Date
    Dec 2013
    Location
    The alcoves in the Koningin Astridpark
    Posts
    5,876

    Default Re: Scripted 'Historical' Battles (v2.0)

    I'm going to update the pack and this tutorial with a few tips n tricks soon, but here's the biggest one that I just came up with.

    If you extract the contents of your script folder to Steam\steamapps\common\Total War Attila\data and delete them from the actual pack, you can edit the lua and xml files whilst in-game! This means that you don't need to shut down Attila, edit the pack, save it, then re-launch Attila just to correct a minor problem. Instead just fix the .xml or .lua file, quit to the main menu, and relaunch the battle.



  5. #5
    Commissar Caligula_'s Avatar The Ecstasy of Potatoes
    Join Date
    Dec 2013
    Location
    The alcoves in the Koningin Astridpark
    Posts
    5,876

    Default Re: Scripted 'Historical' Battles (v2.0)

    This post can be deleted.
    Last edited by Commissar Caligula_; January 07, 2024 at 05:21 AM.



  6. #6
    Commissar Caligula_'s Avatar The Ecstasy of Potatoes
    Join Date
    Dec 2013
    Location
    The alcoves in the Koningin Astridpark
    Posts
    5,876

    Default Re: Scripted 'Historical' Battles (v2.0)

    I'm going to rewrite the entire tutorial, so I'm moving the first 2 posts down here in case I want to re-use any of the information.

    Spoiler Alert, click show to read: 
    Further Information On The Tables Involved
    audio

    719809957.wem
    If you want to have custom audio narration during your cutscene, or custom audio when the battle advisor says something, you will need to override vanilla audio files.

    A tutorial on how to do this can be found here: https://www.twcenter.net/forums/show...g-Custom-Audio
    A list of all the audio files directly related to historical battles can be found here: https://docs.google.com/spreadsheets...#gid=861993959



    campaign_maps
    main_attila_map
    main_attila_map.png
    If you want a custom map as the background of the historical battle selection screen, then you need to follow the following steps.



    db
    battles_tables
    In this table you put the name of the battle, where the battle.xml is found and where the preview screenshot is found.

    The only entries in this table you will need to change are:
    • key; (the name of the battle)
    • specification; (the path of the battle.xml)
    • screenshot_path (the path of the preview screenshot).
    historical_battles_ui_locations_tables
    So now that you have done that, you want to get your historical battles located in the right area on the map.

    scripted_subtitles_tables
    If you want subtitles during cutscenes at the start, middle or end of your historical battle then you have to make entries for them here. For example: "HB.BoB.Intro_01" (Historical Battle, Battle of Bastards, Intro 1). There will be no audio for these cutscenes.
    These subtitles are also referenced in [prefix]_scripted_subtitles.loc and [prefix]_cutscenes.lua
    If you want to make custom audio for these scripted subtitles, change character_for_vo key to “Narrator”. This tutorial will teach you how to import custom audio, and this spreadsheet will help you identify the audio files to override.


    lua_scripts
    dev.lua and logging_callbacks.lua and util.lua
    These three lua scripts contain a camera co-ordinates logger script that is a combination of work by the Rome 2 Total Realism team; DETrooper; Case; DrunkFlamingo; Farfadet; and myself. This script helps in creating historical battles as:

    Every time you click "Start Battle" a text file will write down the co-ordinates, width, and orientation/bearing of every unit in your army (so long as you also set this up in [prefix]_battle.xml; [prefix]_declarations.lua and [prefix]_start.lua). This greatly assists in positioning units in battle.xml. The format will look like this:
    Code:
    	unit:1
    	<position x="160" y="-136"/>
    	<orientation radians="0.00"/>
    	<width metres="21.70"/>
    In addition, every time you click the button in the middle bottom of the screen a text file will write down the co-ordinates that the camera was in at that time. This greatly assists in creating cutscenes. The log is created in "Historical_Battle_Camera_log.txt" which is saved in C:\Program Files (x86)\Steam\steamapps\common\Total War Attila\data in a format looking like this:
    Code:
    Camera Info:Tuesday, 09/27/22 18:16:45
    	Cutscene_NAME:action(function() cam:move_to(v(171, 121, -56), v(175, 13, 46), [CUTSCENE LENGTH #], true, [FOV #]) end, [START TIME #]);
    If you want to change what button activates the script, change "mon_crest" in logging_callbacks.lua

    If you are creating historical battles for a mod that has disabled historical battles (such as The Dawnless Days), you may need to edit that mod’s “frontend_scripted.lua” to remove:
    Code:
    	UIComponent(scripting.m_root:Find("button_historical_battle")):SetState("inactive");
    frontend_hbs.lua
    This lua script contains a list of the historical battles that are available in your mod. Below is the relevant section.
    Code:
    Historic_Battle_List = {
        "Catalaunian_Plains",
        "Utus",
        "Ravenna",
        "Frigidus_River",
        "Cap_Bon",
        "Samarra",
        "Cartagena",
        "Soissons",
        "Ad_Decimum",
        "Adrianople",
        "Dara"
    };
    Code:
    Historic_Battle_List = {
        "battleofthebastards",
        "fistoffirstmen"
    };


    script
    (prefix)_battle

    I would highly advise that you check out this documentation created by CA. It tells you all kinds of cool things you can put in your historical battles such as:
    • You can make gates of a settlement be forced open;
    • You can spawn siege equipment for the attackers;
    • You can make it so immediately after a historical battle, the game launches either a campaign as a specific faction, or another historical battle. The 2nd option would let you make a "campaign" out of historical battles;
    • You can set it up so the game hides reinforcing armies from appearing in the opening loading screen. So reinforcements will just appear without warning.

    screenshot_small.png
    This is a 512x256 png file that acts as a little preview image of your historical battle. Here are three examples I've used, and two pictures of them actually in-game.
    Example 1
    Example 2
    Example 3

    In Game 1
    In Game 2
    (prefix)_battle.xml
    This file determines quite a lot of what happens in the historical battle. Such as what factions are involved in the historical battle, how many (and what) units each faction has, the co-ordinates/orientation/width of the units, whether they have chevrons in experience, what the victory condition is, where the deployment area is, the type of weather and lighting, the battle map and how big the playable area is.
    The Factions
    The following example comes from the Battle of the Bastards. Look at the alliance id and <army> tags below. You can see that House Stark and the Vale are two factions on the same team. The Vale is controlled by the AI. You can also see that the two factions have different deployment areas.
    Code:
    	<alliance id="0">
    	
    		<army>
    		
    			<faction>historical_house_stark</faction>
    			
    			<deployment_area>
    				<centre x="160.00" y="-170.00"/>
    				<width metres="250.00"/>
    				<height metres="125.00"/>
    				<orientation radians="0.00"/>
    			</deployment_area>
    			
    			<unit script_name="stark1" hide_prebattle="true">
    				<unit_type type="Historical_Jon"/>
    				<position x="160.70" y="-130.35"/>
    				<orientation radians="0.00"/>
    				<width metres="21.70"/>
    			</unit>
    		</army>
    
    		<army>
    			<faction>historical_vale</faction>
    			
    			<deployment_area>
    				<centre x="-330.00" y="-131.00"/>
    				<width metres="250.00"/>
    				<height metres="125.00"/>
    				<orientation radians="1.00"/>
    			</deployment_area>
    			
    			<unit script_name="valereinforcements1" hide_prebattle="true">
    				<unit_type type="Vale_Arryn_2_Heavy_Cavalry"/>
    				<position x="-250" y="-206"/>
    				<orientation radians="1"/>
    				<width metres="30"/>
    				<unit_experience level="4"/>
    			</unit>
    		</army>		
    		<victory_condition>
    			<kill_or_rout_enemy></kill_or_rout_enemy>
    		</victory_condition>
    		<rout_position x="0.00" y="0.00"/>
    		
    	</alliance>
    The Units
    Look at the code below. This example comes from the Battle of the Fist of the First Men from my Battles of the North mod.
    Code:
    			<unit>
    				<unit_type type="Wall_Watch_1_Jeor_Mormont"/>
    				<position x="-21.70" y="400.35"/>
    				<orientation radians="3.14"/>
    				<width metres="21.70"/>
    				<unit_experience level="0"/>
    				<general>
    					<name>2147363108</name>
    					<star_rating level="0"/>
    				</general>
    			</unit>
    As you can see here, the unit is a custom general unit for Jeor Mormont. It's x and y co-ordinates are detailed, it's orientation radians is listed (I honestly don't have a clue how you work this out, and it is incredibly annoying), it's width is listed, its experience level and because it is the general I have given it a custom name (which requires files like names_tables and names.loc).

    Width determines how stretched out the unit is/how many rows. For infantry units I generally give them 21.70 width, archers get 27.00 and cavalry get 35.00

    In the Battle of the Bastards historical battle script, you may have noticed that the units look like this.
    Code:
    			<unit script_name="stark1" hide_prebattle="true">
    
    			<unit script_name="stark3">
    hide_prebattle="true" means that the unit will not appear on the loading screen at the start, so when they appear (eg due to a reinforcement script), it will come as a surprise to the plawyer.

    The reason I have unit script_name rather than just plain <unit> is because I have referenced this unit in a reinforcement script in that battle.
    Weather
    With historical battles, you can choose the precise weather that you want to occur in the battle, for example
    Code:
    	<weather>
    		<environment_key>weather\default\default\land\day\snow\snow_3_heavy.environment</environment_key>
    		<prevailing_wind x="1.00" y="0.00"/>
    	</weather>
    I don’t know what the prevailing wind does, it’s probably just for naval battles. Anyways, to choose the environment key you go to data.pack – weather and choose what type of weather you want. You have to test them one by one within the historical battle if you’re trying to get a precise one.

    The time_of_day, season and precipitation_type settings under <battle_description> do not seem to have any effect.
    Battle Map
    First off, you have to choose what exact battle map you want to use as your historical battle. You can choose to use a custom battle map, such as
    Code:
    	<battle_map_definition>
      <name>terrain/tiles/battle/assembly_kit/battle_of_the_bastards/battlefield</name>
    	</battle_map_definition>
    Or you can use a vanilla battle map, such as
    Code:
    	<battle_map_definition>
    		<name>Terrain/battles/main_attila_map/</name>
    		<tile_map_position x="0.089" y="0.094">/</tile_map_position>
    		<tile_upgrade>level1</tile_upgrade>
    		<tile_upgrade>escalation3</tile_upgrade>
    	</battle_map_definition>
    It is recommended that you just test random custom battles to find the battle map you’d like to use.
    If you use a vanilla siege map, you need to decide whether you want to use an upgraded version of the map, and whether there should be siege escalation.

    If you want to use a type of battle map other than a normal land battle (for example a port, ambush, river crossing, siege), you need to change the following entry
    Code:
    	<battle_description>
    		<type>land_normal</type>
    	</battle_description>
    The options available to you are:
    Code:
    coastal_battle
    land_ambush
    land_bridge
    land_normal
    naval_blockade
    naval_breakout
    naval_normal
    port_assault
    settlement_relief
    settlement_sally
    settlement_standard
    settlement_unfortified
    unfortified_port
    You also need to consider how big you want the playable area dimensions to be.
    Code:
    	<playable_area dimension="1924"></playable_area>
    (prefix)_cutscenes.lua
    This controls how long the cutscenes are, how long each individual shot is, the co-ordinates each individual shot starts at and tracks to, the subtitles that appear, when the subtitles appear and for how long, whether the two factions march into position during the cutscene and whether there are additional cutscenes such as reinforcements or at the end of the battle.

    Code:
    POS_Cam_Cutscene_Intro_Final = v(162, 100, -350);
    Targ_Cam_Cutscene_Intro_Final = v(162, 50, -210);
    I believe this is telling the camera what co-ordinates it should be at (more below on co-ordinates), and what it should be looking at when the cutscene ends, or if you skip the cutscene. You will need to play around with this to work it out.


    Code:
    	Cutscene_Intro:action(function() ga_franks_01:teleport_to_start_location_offset(0, -50); end, 0);	
    	Cutscene_Intro:action(function() ga_soissons_01:teleport_to_start_location_offset(0, -50); end, 0);	
    	Cutscene_Intro:action(function() ga_soissons_01:set_visible_to_all(true); end, 0);	
    	
    	Cutscene_Intro:action(function() ga_franks_01:goto_start_location(false); end, 0);
    	Cutscene_Intro:action(function() ga_soissons_01:goto_start_location(false); end, 0);
    This is telling all ga_franks_01 and ga_soissons_01 units to start 50m away from their start position that is set in battles.xml, and to walk to the start position as the cutscene plays. I believe there are modifiers where you can make them walk or run. Presumably you could even make them walk to numerous different co-ordinates during the cutscenes.


    When you use the camera position log script in-game you will notice that the following text is created:
    Code:
    	Cutscene_NAME:action(function() cam:move_to(v(-591, 586, 408), v(-248, 388, 52), [CUTSCENE LENGTH #], true, [FOV #]) end, [START TIME #]);
    You have to:
    1. Give the cutscene a name (eg Cutscene_Intro);
    2. Input the length of the cutscene (this is essentially the speed at which the camera transitions from point A to point B in seconds. Eg it’ll go very slowly if you write 22 seconds, or very fast if you write 2 seconds. You can make it go slowly by writing 22 seconds, but then START the next cutscene after just 8 seconds)
    3. Input the field of view (eg 45 degrees)
    4. Input a start time (this is in milliseconds. Eg if you want the 1st shot to last 20 seconds and the 2nd shot to last 8 seconds then the start time for the first shot is 0, start time for the 2nd shot is 20000, and start time for the 3rd shot is 8000.

    All cutscenes come in pairs. Eg 1 and 2; 3 and 4; 5 and 6.
    The cutscene length for the first of the pair is ALWAYS 0.
    The start time is ALWAYS the same for each pair.

    An example of a finished cutscene is below.
    • Pair 1 and 2 start at 0 seconds, and last for 22 seconds.
    • Pair 3 and 4 start at 22 seconds and last for 20 seconds
    • Pair 5 and 6 start at 42 seconds and last for 10 seconds
    Code:
    	Cutscene_Intro:action(function() cam:move_to(v(382, 76, 217), v(486, 96, 582), 0, true, 45) end, 0);
    	Cutscene_Intro:action(function() cam:move_to(v(382, 72, 185), v(486, 96, 582), 22, true, 43) end, 0);
    
    	
    	Cutscene_Intro:action(function() cam:move_to(v(150, 52, 39), v(167, 7, 416), 0, true, 45) end, 22000);
    	Cutscene_Intro:action(function() cam:move_to(v(150, 52, 23), v(167, 7, 416), 20, true, 43) end, 22000);
    
    
    	Cutscene_Intro:action(function() cam:move_to(v(217, 48, 210), v(-539, -163, 1082), 0, true, 45) end, 42000);
    	Cutscene_Intro:action(function() cam:move_to(v(217, 48, 209), v(-525, -163, 1082), 10, true, 43) end, 42000);
    You can also add subtitles to the cutscene as seen below (also referenced in “scripted_subtitles_tables” and “[prefix]_scripted_subtitles.loc”).
    You can see each subtitle has a start time, and then a function to end that subtitle at a certain time (eg AT 20 seconds, NOT AFTER 20 seconds).
    Code:
    	Cutscene_Intro:action(function() subtitles:set_text("Att.HB.BoB.Intro_01") end, 3000);
    	Cutscene_Intro:action(function() subtitles:clear() end, 12000);
    
    
    	Cutscene_Intro:action(function() subtitles:set_text("Att.HB.BoB.Intro_02") end, 14000);
    	Cutscene_Intro:action(function() subtitles:clear() end, 20000);
    
    
    	Cutscene_Intro:action(function() subtitles:set_text("Att.HB.BoB.Intro_03") end, 23000);
    	Cutscene_Intro:action(function() subtitles:clear() end, 31000);
    
    
    	Cutscene_Intro:action(function() subtitles:set_text("Att.HB.BoB.Intro_04") end, 33000);
    	Cutscene_Intro:action(function() subtitles:clear() end, 40000);
    
    
    	Cutscene_Intro:action(function() subtitles:set_text("Att.HB.BoB.Intro_05") end, 43000);
    	Cutscene_Intro:action(function() subtitles:clear() end, 51000);

    You can also trigger cutscenes to occur after reinforcements arrive.
    (prefix)_declarations.lua
    This file contains parts of the logging scripts, and the unit scripts. The unit scripts section is necessary if you want to reference units in scripts, eg the logging scripts, reinforcement scripts, or difficulty handicap scripts.

    There must be two alliances, and then you list each army in those alliances.

    You then type in the script names for those units, and what army they’re part of.

    SUnits_ binds certain units together, eg so you can issue them all commands in a script.
    (prefix)_script_reinforcements.lua
    This file contains the reinforcement scripts, if you want to use them.

    The countdown at the top is in milliseconds. Therefore, 5000 = 5 seconds and 360000 = 6 minutes.

    You can also tie the reinforcement scripts to trigger certain cutscenes when the reinforcements arrive. Check vanilla historical battles, or “Battle of the Bastards” to see how this may be done.

    “SAI_Isengard_Reinforcement_1:defend_position(v(103, -171), 200)” directs this reinforcement army to go to, and defend the position x103 y-171 in a radius of 200m. This should force it to attack any enemy units in that radius. This function does not appear to kick in until 25 seconds have elapsed.
    (prefix)_start.lua
    [prefix]_start.lua requires very little editing.
    • You may turn the logging on/off by typing true or false (not sure whether this actually works anymore);
    • You can swap between dev mode and battle mode by changing "false" to "true"
      Code:
      gb = generated_battle:new(
      	false,                                      -- screen starts black. Should match the prepare_for_fade_in flag in the battle xml
      	false,                                      -- prevents deployment. Set to false if you want the player to be able to deploy.
      	function() Play_Cutscene_Intro() end,      -- intro cutscene callback. Supply a function that runs your intro cutscene here
      	false                                      -- debug mode
      );
      You will also need to change the SUnits referred to in function Start_Battle() to match [prefix]_declarations.lua
    • You can decide whether the battle starts with the AI immediately attacking you;
    • You can prevent certain scripts from working by adding -- to the start, eg:
    Code:
    require (battle_shortform .. "_Cutscenes");
    require (battle_shortform .. "_Script_Misc");
    require (battle_shortform .. "_Script_Difficulty_Selector");
    -- require (battle_shortform .. "_Script_Reinforcements");

    • If you want to add allied armies, you add them as seen below.
    Code:
    ga_franks_01 = gb:get_army(1, 1);
    
    ga_soissons_01 = gb:get_army(2, 1);
    ga_isengard_reinforcements_1 = gb:get_army(2, 2);

    • You can make the Advisor say stuff when the battle starts, when your general/the enemy general dies, and when you win/lose. See vanilla examples or Battle of the Bastards:
    Code:
    -- advice on battle start
    gb:advice_on_message("cutscene_ended", "SK.HB.BA.001", 5000);
    
    
    -- advice on player's general dying
    ga_franks_01:message_on_commander_death("player_general_dies");
    gb:advice_on_message("player_general_dies", "SK.HB.BA.002", 2500);
    
    
    -- advice on enemy general dying
    ga_soissons_01:message_on_commander_death("enemy_general_dies");
    gb:advice_on_message("enemy_general_dies", "SK.HB.BA.003", 2500);
    
    
    -- advice on player winning
    ga_franks_01:message_on_victory("player_wins");
    gb:advice_on_message("player_wins", "SK.HB.BA.004");
    
    
    -- advice on player losing
    ga_franks_01:message_on_defeat("player_loses");
    gb:advice_on_message("player_loses", "SK.HB.BA.005");


    text
    db
    random_localisation_strings.loc
    This is a text file where you can change what each difficulty level is called (if you want to). The default difficulties are Easy, Normal, Hard, Very Hard, Legendary. In “The War of the Ring” I changed the difficulties as follows:
    random_localisation_strings_string_difficulty_level_1Normal
    random_localisation_strings_string_difficulty_level_2Normal
    random_localisation_strings_string_difficulty_level_3Hard
    random_localisation_strings_string_difficulty_level_4Legendary
    random_localisation_strings_string_difficulty_level_5Legendary Plus
    battles.loc
    This is a text file where you put in the name, and the description of your historical battles. For example...

    battles_localised_name_battleofthebastardsBattle of the Bastards
    battles_description_battleofthebastardsThe Bastard of the Dreadfort and Warden of the North, Ramsay Bolton, holds Winterfell – the ancestral seat of House Stark. Jon Snow, the Bastard of Winterfell has come to reclaim his home at the head of a ragged army of Wildlings, and bannermen loyal to his cause. The bastards will clash outside the walls of Winterfell, where only one may emerge victorious.
    scripted_subtitles.loc
    This is a text file where you put in the subtitles for your cutscenes. For example...

    scripted_subtitles_localised_text_Att.HB.BoB.Intro_01Jon Snow: If he was smart, he’d stay inside the walls of Winterfell and wait us out.
    The subtitles, eg “Att.HB.BoB.Intro_01”, are referenced in scripted_subtitles_tables and [prefix]_cutscenes.lua
    As noted earlier, if you want to make custom audio for these scripted subtitles, this tutorial will teach you how to import custom audio, and this spreadsheet will help you identify the audio files to override.
    uied_component_texts.loc
    This is a text file where you can change the text displaying "Historical Battles" to whatever custom text you want, for example "Battles of the North" or "The War of the Ring". These are the three strings that you would change:

    uied_component_texts_localised_string_string_NewState_Text_3a000cm
    uied_component_texts_localised_string_button_txt_NewState_Text_49000c
    uied_component_texts_localised_string_string_NewState_Text_3a000c


    misc
    All other tables and entries in the tutorial pack are not strictly required for a historical battle, but you may end up using them eg if you want to have custom units, custom maps, custom UI, ect, in your battles.



Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •