<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://tw-modding.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vandy</id>
	<title>Total War Modding - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://tw-modding.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vandy"/>
	<link rel="alternate" type="text/html" href="https://tw-modding.com/wiki/Special:Contributions/Vandy"/>
	<updated>2026-04-15T03:58:42Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=1365</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=1365"/>
		<updated>2025-09-30T01:18:28Z</updated>

		<summary type="html">&lt;p&gt;Vandy: Add Discord links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== THIS IS A WIKI ==&lt;br /&gt;
Hi! Just wanted to shout that you can '''sign up for an account to help contribute any changes to the wiki!''' It's a wiki! It's not just one guy!&lt;br /&gt;
&lt;br /&gt;
If you request an account, just let us know in the #modding_wiki channel in the [https://discord.gg/moddingden Modding Den Discord], and we'll let you in as soon as we can!&lt;br /&gt;
&lt;br /&gt;
please help.&lt;br /&gt;
== Help Out ==&lt;br /&gt;
To give a hand, please check out the page [[Meta]] for the various bits of stuff we've marked as necessary. There are also pages in [[:Category:To Edit]] which have listed changes needed.&lt;br /&gt;
&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/moddingden Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=1277</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=1277"/>
		<updated>2024-07-06T16:12:22Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:GoogleCustomWikiSearch|Search&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=1276</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=1276"/>
		<updated>2024-07-06T16:10:33Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:GoogleCustomWikiSearch|Search&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=1275</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=1275"/>
		<updated>2024-07-06T16:09:56Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** Special:GoogleCustomWikiSearch&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=1271</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=1271"/>
		<updated>2024-07-06T00:38:11Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* THIS IS A WIKI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== THIS IS A WIKI ==&lt;br /&gt;
Hi! Just wanted to shout that you can '''sign up for an account to help contribute any changes to the wiki!''' It's a wiki! It's not just one guy!&lt;br /&gt;
&lt;br /&gt;
If you request an account, just let us know in the #modding_wiki channel in the Modding Den Discord, and we'll let you in as soon as we can!&lt;br /&gt;
&lt;br /&gt;
please help.&lt;br /&gt;
== Help Out ==&lt;br /&gt;
To give a hand, please check out the page [[Meta]] for the various bits of stuff we've marked as necessary. There are also pages in [[:Category:To Edit]] which have listed changes needed.&lt;br /&gt;
&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/dd4TUDm Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=1270</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=1270"/>
		<updated>2024-07-06T00:37:50Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== THIS IS A WIKI ==&lt;br /&gt;
Hi! Just wanted to shout that you can '''sign up for an account to help contribute any changes to the wiki!''' It's a wiki! It's not just one guy!&lt;br /&gt;
&lt;br /&gt;
If you request an account, just let us know in the #modding_wiki channel in the Modding Den Discord, and we'll let you in as soon as we can!&lt;br /&gt;
&lt;br /&gt;
please help.&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/dd4TUDm Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
== Help Out ==&lt;br /&gt;
To give a hand, please check out the page [[Meta]] for the various bits of stuff we've marked as necessary. There are also pages in [[:Category:To Edit]] which have listed changes needed.&lt;br /&gt;
&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=1269</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=1269"/>
		<updated>2024-07-06T00:29:06Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* NEW WEBSITE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== THIS IS A WIKI ==&lt;br /&gt;
Hi! Just wanted to shout that you can '''sign up for an account to help contribute any changes to the wiki!''' It's a wiki! It's not just one guy!&lt;br /&gt;
&lt;br /&gt;
If you request an account, just let us know in the #modding_wiki channel in the Modding Den Discord, and we'll let you in as soon as we can!&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/dd4TUDm Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
== Help Out ==&lt;br /&gt;
To give a hand, please check out the page [[Meta]] for the various bits of stuff we've marked as necessary. There are also pages in [[:Category:To Edit]] which have listed changes needed.&lt;br /&gt;
&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Category:DB_Table&amp;diff=1261</id>
		<title>Category:DB Table</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Category:DB_Table&amp;diff=1261"/>
		<updated>2024-05-29T20:57:03Z</updated>

		<summary type="html">&lt;p&gt;Vandy: Created blank page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Tutorial:Pooled_Resource_Unit_Costs&amp;diff=1005</id>
		<title>Tutorial:Pooled Resource Unit Costs</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Tutorial:Pooled_Resource_Unit_Costs&amp;diff=1005"/>
		<updated>2023-07-14T00:00:42Z</updated>

		<summary type="html">&lt;p&gt;Vandy: Vandy moved page Tutorial:Pooled Resource Costs to Tutorial:Pooled Resource Unit Costs over a redirect without leaving a redirect&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Total War: Warhammer 3 Guide by Pear =&lt;br /&gt;
This guide and the [[:File:!units_cost_pooled_resource.pack|example mod]] are my submission for '''Mod Jam #7'''.&lt;br /&gt;
&lt;br /&gt;
[https://tw-modding.com/wiki/Tutorial:Pooled_Resources_Updated Pooled Resources] are cool. The problem is their application is often limited. This tutorial aims to fix that by explaining how to use Pooled Resources as costs for units in the main recruitment panel and providing an [[:File:!units_cost_pooled_resource.pack|example mod]] for reference. The method used here can be applied to a range of other things such as RoRs, lords, agents, buildings, technologies, or anything like that.&lt;br /&gt;
&lt;br /&gt;
There's currently nothing in the tables to make units cost Pooled Resources except for a few faction-specific things so we have to use Lua UI scripting instead. It works by checking when the player has clicked certain units, taking away the defined cost of those units, and creating some UI components (UICs) to visualise all this. The process consists of two main parts:&lt;br /&gt;
&lt;br /&gt;
# [https://tw-modding.com/wiki/Tutorial:Pooled_Resource_Costs#%F0%9F%8E%A8_Making_the_UI '''Making the UI''']: making UICs, enabling and disabling UICs, and setting text, tooltips, and icons.&lt;br /&gt;
# [https://tw-modding.com/wiki/Tutorial:Pooled_Resource_Costs#%F0%9F%8E%AE_Triggering_the_UI '''Triggering the UI''']: creating the UI at the right time, accounting for UI refreshes, and taking away / returning the Pooled Resource to the player in a multiplayer-friendly way.&lt;br /&gt;
&lt;br /&gt;
Before we get started I'd recommend using my [[:File:!units_cost_pooled_resource.pack|example mod]] as a reference, as well as Groove Wizard's [https://github.com/chadvandy/tw_autogen Visual Studio development environment] for your scripting, and Groove's [https://steamcommunity.com/sharedfiles/filedetails/?id=2791799449 Modding Development Tools: Lua Console] to test the code in game (yes this man is a machine). This guide assumes some knowledge of RPFM and scripting.&lt;br /&gt;
&lt;br /&gt;
== 🧑‍🎓 Some UI Basics ==&lt;br /&gt;
If you're not familiar with UI modding then you may find this section useful. If you're too kool for skool, move along!&lt;br /&gt;
&lt;br /&gt;
=== 🔍 Finding UI Components ===&lt;br /&gt;
[[File:Recruitment cost component.png|right|thumb|Recruitment Cost Component in the Context Viewer]]&lt;br /&gt;
In order to modify a part of the UI you need to find where it's located. To do this we can use the [https://tw-modding.com/wiki/Tutorial:Context_Viewer_(Warhammer_3) Context Viewer]. A quick way to do this is by having the Context Viewer open and clicking on the screen with your mouse wheel.&lt;br /&gt;
&lt;br /&gt;
For the purpose of this tutorial, try clicking the unit card you want to add a Pooled Resource to then expanding the unit card path in the Context Viewer until you find the &amp;quot;RecruitmentCost&amp;quot; UIC. Once you've found it, paste &amp;lt;code&amp;gt;CopyFullPathToClipboard()&amp;lt;/code&amp;gt; in the expression tester box. This copies the path to that UIC. &lt;br /&gt;
&lt;br /&gt;
When copied it will look like this: &amp;quot;:root:units_panel:main_units_panel:...&amp;quot; and so on. &lt;br /&gt;
&lt;br /&gt;
Referencing my example mod, you can write the path to the recruitment cost UIC for the Swordsmen unit like this: &lt;br /&gt;
 &amp;lt;code&amp;gt;local recruitment_uic = find_uicomponent(core:get_ui_root(), &amp;quot;units_panel&amp;quot;, &amp;quot;main_units_panel&amp;quot;, &amp;quot;recruitment_docker&amp;quot;, &amp;quot;recruitment_options&amp;quot;, &amp;quot;recruitment_listbox&amp;quot;, &amp;quot;local1&amp;quot;, &amp;quot;unit_list&amp;quot;, &amp;quot;listview&amp;quot;, &amp;quot;list_clip&amp;quot;, &amp;quot;list_box&amp;quot;, &amp;quot;wh_main_emp_inf_swordsmen_recruitable&amp;quot;, &amp;quot;unit_icon&amp;quot;, &amp;quot;RecruitmentCost&amp;quot;)&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
It is fine as it is however it can be split into smaller, easier-to-access parts like this: &lt;br /&gt;
 &amp;lt;code&amp;gt;local recruitment_uic = find_uicomponent(core:get_ui_root(), &amp;quot;units_panel&amp;quot;, &amp;quot;main_units_panel&amp;quot;, &amp;quot;recruitment_docker&amp;quot;, &amp;quot;recruitment_options&amp;quot;, &amp;quot;recruitment_listbox&amp;quot;, recruitment_type)&lt;br /&gt;
 local listview_uic = find_uicomponent(recruitment_uic, &amp;quot;unit_list&amp;quot;, &amp;quot;listview&amp;quot;)&lt;br /&gt;
 local unit_uic = find_uicomponent(listview_uic, &amp;quot;list_clip&amp;quot;, &amp;quot;list_box&amp;quot;, &amp;quot;wh_main_emp_inf_swordsmen_recruitable&amp;quot;)&lt;br /&gt;
 local recruitment_cost_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;RecruitmentCost&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 📷 Creating / Copying Components ===&lt;br /&gt;
For our purposes we will probably only need to create copies of pre-existing UICs. To do that you need to use &amp;lt;code&amp;gt;[https://chadvandy.github.io/tw_modding_resources/WH3/campaign/uicomponent.html#function:uicomponent:CopyComponent uicomponent:CopyComponent()]&amp;lt;/code&amp;gt; which is being used here to copy the recruitment cost UIC for the Swordsmen unit and naming the new UIC &amp;quot;prestige cost&amp;quot;:&lt;br /&gt;
 &amp;lt;code&amp;gt;UIComponent(recruitment_cost_uic:CopyComponent(&amp;quot;prestige_cost&amp;quot;))&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the paths we've previously established, the path for this new &amp;quot;prestige_cost&amp;quot; UIC we've created is therefore:&lt;br /&gt;
 &amp;lt;code&amp;gt;local prestige_cost_parent_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;prestige_cost&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ⬇️ Repositioning Components ===&lt;br /&gt;
This part is a bit more tedious. You will need to use the console (shift + f3) from Groove's Modding Dev Tools to test where the new &amp;quot;prestige_cost&amp;quot; UIC we've created should be repositioned. To do that you need to use &amp;lt;code&amp;gt;[https://chadvandy.github.io/tw_modding_resources/WH3/campaign/uicomponent.html#function:uicomponent:SetDockOffset uicomponent:SetDockOffset()]&amp;lt;/code&amp;gt;. Using the code below you can test coordinates e.g. x = 0, y = 5 until the new UIC looks like it's in the right place:&lt;br /&gt;
 &amp;lt;code&amp;gt;local prestige_cost_parent_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;prestige_cost&amp;quot;)&lt;br /&gt;
 prestige_cost_parent_uic:SetDockOffset(x, y)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you ''really'' want to make sure it's in the right place take a screenshot and do a bit of pixel peeping in a photo editor and count the pixels between e.g. the original recruitment cost and the upkeep cost UICs and that's how many pixels your new component should be below the recruitment cost UIC. &lt;br /&gt;
&lt;br /&gt;
Using my example mod, we can see that the correct coordinates for the new component in the normal recruitment panel are:&lt;br /&gt;
 &amp;lt;code&amp;gt;prestige_cost_parent_uic:SetDockOffset(8, 19)&amp;lt;/code&amp;gt;&lt;br /&gt;
this may change depending on the faction or panel e.g. RoRs or lords.&lt;br /&gt;
&lt;br /&gt;
=== ↗️ Resizing Components ===&lt;br /&gt;
Resizing components may be necessary if you're adding UICs, especially resizing list clips which would otherwise cut off the new UICs you've made. To do that you need to use [https://chadvandy.github.io/tw_modding_resources/WH3/campaign/uicomponent.html#function:uicomponent:Resize Resize] like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;unit_uic:SetCanResizeHeight(true)&lt;br /&gt;
 unit_uic:SetCanResizeWidth(true)&lt;br /&gt;
 local width, height= unit_uic:Dimensions()&lt;br /&gt;
 unit_uic:Resize(width, (height +  + 10), false)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 🪟 Finding panels ===&lt;br /&gt;
To find the name of the panel that you want to check is opened or closed you can check the log produced by Groove's Modding Dev Tools. In the log it will look something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;[ui] &amp;lt;97.6s&amp;gt;    Panel opened units_panel&lt;br /&gt;
 [ui] &amp;lt;98.8s&amp;gt;    Panel opened recruitment_options&lt;br /&gt;
 [ui] &amp;lt;98.8s&amp;gt;    Panel opened units_recruitment&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 🎨 Making the UI ==&lt;br /&gt;
So let's start! First we'll be looking at two functions — &amp;lt;code&amp;gt;initialise_uics()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;finalise_uics()&amp;lt;/code&amp;gt; . In short, the two functions apply the UI knowledge we covered earlier (and a little extra) to create UICs, resize UICs, and set their docking points, text, and icons. The functions are seperated even though they do similar things because the first one has to run only when the panel is opened, whereas the second has to run every time the UI is refreshed while the panel is open. For the purpose of the guide we will be keeping the vanilla treasury costs and making one new Pooled Resource cost which will go below the unit card. &lt;br /&gt;
&lt;br /&gt;
'''IMPORTANT''': Make sure you change the '''listener and saved value names''' from the examples to avoid incompatibilities.&lt;br /&gt;
&lt;br /&gt;
=== 🚀 Initialising UICs ===&lt;br /&gt;
First, we need a table for the units we want to have Pooled Resource costs. It should contain the loc key for the unit's onscreen name, the unit's UIC (which is just the unit's key plus &amp;quot;_recruitable&amp;quot;), and the Pooled Resource cost. Together it should look like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;local pr_units = {&lt;br /&gt;
    {unit_name_loc = &amp;quot;land_units_onscreen_name_wh_main_emp_inf_spearmen_1&amp;quot;, unit_uic = &amp;quot;wh_main_emp_inf_spearmen_1_recruitable&amp;quot;, prestige_cost = 18},&lt;br /&gt;
    {unit_name_loc = &amp;quot;land_units_onscreen_name_wh_main_emp_inf_swordsmen&amp;quot;, unit_uic = &amp;quot;wh_main_emp_inf_swordsmen_recruitable&amp;quot;, prestige_cost = 19}&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This table is then used in the functions &amp;lt;code&amp;gt;initialise_uics()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;finalise_uics()&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
The first function &amp;lt;code&amp;gt;initialise_uics()&amp;lt;/code&amp;gt; handles resizing the parents for UICs to make sure the list clips are displaying our new components and everything else appears correctly. The first part of that runs in a loop, once for local and once for global recruitment if the UIC exists then it proceeds:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;local function initialise_uics()&lt;br /&gt;
    out(&amp;quot;PR UNIT COST LOG - Initialising components.&amp;quot;)&lt;br /&gt;
    local recruitment_type&lt;br /&gt;
    local b&lt;br /&gt;
    if cm:get_saved_value(&amp;quot;EXAMPLE_ENCAMP_CLICKED&amp;quot;) == true then&lt;br /&gt;
        b = 2&lt;br /&gt;
    else&lt;br /&gt;
        b = 1&lt;br /&gt;
    end&lt;br /&gt;
    for g = b, 2 do&lt;br /&gt;
        if g == 1 then&lt;br /&gt;
            recruitment_type = &amp;quot;local1&amp;quot;&lt;br /&gt;
        elseif g == 2 then&lt;br /&gt;
            recruitment_type = &amp;quot;global&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        local recruitment_uic = find_uicomponent(core:get_ui_root(), &amp;quot;units_panel&amp;quot;, &amp;quot;main_units_panel&amp;quot;, &amp;quot;recruitment_docker&amp;quot;, &amp;quot;recruitment_options&amp;quot;, &amp;quot;recruitment_listbox&amp;quot;, recruitment_type)&lt;br /&gt;
        if recruitment_uic then&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next it finds the UICs we'll be using and deals with a weird UI quirk with changing stances several times:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;local recruitment_docker_uic = find_uicomponent(core:get_ui_root(), &amp;quot;units_panel&amp;quot;, &amp;quot;main_units_panel&amp;quot;, &amp;quot;recruitment_docker&amp;quot;)&lt;br /&gt;
            local unit_list = find_uicomponent(recruitment_uic, &amp;quot;unit_list&amp;quot;)&lt;br /&gt;
            local listview_uic = find_uicomponent(unit_list, &amp;quot;listview&amp;quot;)&lt;br /&gt;
            local hslider_uic = find_uicomponent(listview_uic, &amp;quot;hslider&amp;quot;)&lt;br /&gt;
            local list_clip_uic = find_uicomponent(listview_uic, &amp;quot;list_clip&amp;quot;)&lt;br /&gt;
            local list_box_uic = find_uicomponent(list_clip_uic, &amp;quot;list_box&amp;quot;)&lt;br /&gt;
            -- to prevent some weird quirk with UI when you switch between army stances several times&lt;br /&gt;
            if recruitment_type == &amp;quot;global&amp;quot; and cm:get_saved_value(&amp;quot;pr_cost_encamp_clicked&amp;quot;) ~= true then&lt;br /&gt;
                cm:set_saved_value(&amp;quot;pr_cost_encamp_clicked&amp;quot;, true)&lt;br /&gt;
            end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next part uses a unit from our table as a reference. If none of the units exist, the function ends.&lt;br /&gt;
 &amp;lt;code&amp;gt;local reference_unit&lt;br /&gt;
        for i = 1, #pr_units do&lt;br /&gt;
            reference_unit = pr_units[i].unit_uic&lt;br /&gt;
            local unit_uic = find_uicomponent(list_box_uic, reference_unit)&lt;br /&gt;
            if unit_uic then&lt;br /&gt;
                break&lt;br /&gt;
            elseif unit_uic == false then&lt;br /&gt;
                reference_unit = nil&lt;br /&gt;
                break&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
 if reference_unit ~= nil then&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next part makes the UIC's we found earlier able to be resized, and resizes according to the dimensions of adding another recruitment cost UIC and whether the slider for multiple units exists. There is also some fine-tuning to make sure the UI doesn't clip anything. Finally it then runs &amp;lt;code&amp;gt;finalise_uics()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;local unit_uic = find_uicomponent(list_box_uic, reference_unit)&lt;br /&gt;
                local recruitment_cost_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;RecruitmentCost&amp;quot;)&lt;br /&gt;
                -- dimensions for resizing components&lt;br /&gt;
                local width_rcc, height_rcc = recruitment_cost_uic:Dimensions()&lt;br /&gt;
                -- if the slider if there to scroll through multiple units we need to resize things differently&lt;br /&gt;
                if hslider_uic then&lt;br /&gt;
                    -- resizing recruitment_docker&lt;br /&gt;
                    local width_rdc, height_rdc = recruitment_docker_uic:Dimensions()&lt;br /&gt;
                    recruitment_docker_uic:SetCanResizeHeight(true)&lt;br /&gt;
                    recruitment_docker_uic:SetCanResizeWidth(true)&lt;br /&gt;
                    recruitment_docker_uic:Resize(width_rdc, (height_rdc + (height_rcc * 4)), false) &lt;br /&gt;
                    -- resizing unit_list&lt;br /&gt;
                    local width_lrc, height_lrc = unit_list:Dimensions()&lt;br /&gt;
                    unit_list:SetCanResizeHeight(true)&lt;br /&gt;
                    unit_list:SetCanResizeWidth(true)&lt;br /&gt;
                    unit_list:Resize(width_lrc, (height_lrc + (height_rcc * 2)), false) &lt;br /&gt;
                else&lt;br /&gt;
                    -- resizing recruitment_docker&lt;br /&gt;
                    local width_rdc, height_rdc = recruitment_docker_uic:Dimensions()&lt;br /&gt;
                    recruitment_docker_uic:SetCanResizeHeight(true)&lt;br /&gt;
                    recruitment_docker_uic:SetCanResizeWidth(true)&lt;br /&gt;
                    recruitment_docker_uic:Resize(width_rdc, (height_rdc + (height_rcc * 2)), false) &lt;br /&gt;
                    -- resizing unit_list&lt;br /&gt;
                    local width_lrc, height_lrc = unit_list:Dimensions()&lt;br /&gt;
                    unit_list:SetCanResizeHeight(true)&lt;br /&gt;
                    unit_list:SetCanResizeWidth(true)&lt;br /&gt;
                    unit_list:Resize(width_lrc, (height_lrc + height_rcc), false) &lt;br /&gt;
                end&lt;br /&gt;
                -- resizing list_clip&lt;br /&gt;
                local width_lcc, height_lcc = list_clip_uic:Dimensions()&lt;br /&gt;
                list_clip_uic:SetCanResizeHeight(true)&lt;br /&gt;
                list_clip_uic:SetCanResizeWidth(true)&lt;br /&gt;
                list_clip_uic:Resize(width_lcc, (height_lcc + (height_rcc * 2) + 5), false) -- the plus 5 is to make sure there's no clipping at the bottom of the upkeep cost component&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    -- handling pr cost components&lt;br /&gt;
    out(&amp;quot;PR UNIT COST LOG - finalise_uics() from initialise_uics().&amp;quot;)&lt;br /&gt;
    finalise_uics()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 👋 Finalising UICs ===&lt;br /&gt;
&lt;br /&gt;
The second function &amp;lt;code&amp;gt;finalise_uics()&amp;lt;/code&amp;gt; handles the creation of our new UICs, setting the Pooled Resource costs, text, tooltips, icons, and handling anything that gets refreshed when UICs are clicked. The first part loops the whole function for local and global recruitment, if one of those doesn't exist in the UI then that part of the function doesn't run. So if your army is not encamped then it won't cause a script error by trying to run the global part of the function.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;local recruitment_type&lt;br /&gt;
    for g = 1, 2 do&lt;br /&gt;
        if g == 1 then&lt;br /&gt;
            recruitment_type = &amp;quot;local1&amp;quot;&lt;br /&gt;
        elseif g == 2 then&lt;br /&gt;
            recruitment_type = &amp;quot;global&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        local recruitment_uic = find_uicomponent(core:get_ui_root(), &amp;quot;units_panel&amp;quot;, &amp;quot;main_units_panel&amp;quot;, &amp;quot;recruitment_docker&amp;quot;, &amp;quot;recruitment_options&amp;quot;, &amp;quot;recruitment_listbox&amp;quot;, recruitment_type)&lt;br /&gt;
        if recruitment_uic then&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next part finds the UICs we'll be using in the function and creates our new &amp;quot;prestige_cost&amp;quot; UIC:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;for i = 1, #pr_units do&lt;br /&gt;
                local unit_name = common.get_localised_string(pr_units[i].unit_name_loc)&lt;br /&gt;
                local prestige_cost = pr_units[i].prestige_cost&lt;br /&gt;
                local listview_uic = find_uicomponent(recruitment_uic, &amp;quot;unit_list&amp;quot;, &amp;quot;listview&amp;quot;)&lt;br /&gt;
                local hslider_uic = find_uicomponent(listview_uic, &amp;quot;hslider&amp;quot;)&lt;br /&gt;
                local unit_uic = find_uicomponent(listview_uic, &amp;quot;list_clip&amp;quot;, &amp;quot;list_box&amp;quot;, pr_units[i].unit_uic)&lt;br /&gt;
                if unit_uic then&lt;br /&gt;
                    local recruitment_cost_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;RecruitmentCost&amp;quot;)&lt;br /&gt;
                    local upkeep_cost_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;UpkeepCost&amp;quot;)&lt;br /&gt;
                    local prestige_cost_uic_check = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;prestige_cost&amp;quot;)&lt;br /&gt;
                    if prestige_cost_uic_check == false then&lt;br /&gt;
                        UIComponent(recruitment_cost_uic:CopyComponent(&amp;quot;prestige_cost&amp;quot;))&lt;br /&gt;
                    end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next part resizes and repositions the UICs we found above, including the new &amp;quot;prestige_cost&amp;quot; UIC we just created:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;                    -- dimensions for resizing components&lt;br /&gt;
                    local width_rcc, height_rcc = recruitment_cost_uic:Dimensions()&lt;br /&gt;
                    -- resizing unit component&lt;br /&gt;
                    local width_uc, height_uc = unit_uic:Dimensions()&lt;br /&gt;
                    unit_uic:SetCanResizeHeight(true)&lt;br /&gt;
                    unit_uic:SetCanResizeWidth(true)&lt;br /&gt;
                    unit_uic:Resize(width_uc, (height_uc + (height_rcc * 2) + 5), false)&lt;br /&gt;
                    -- repositioning list_view&lt;br /&gt;
                    listview_uic:SetDockOffset(0, -24)&lt;br /&gt;
                    -- repositioning cost components&lt;br /&gt;
                    local prestige_cost_parent_uic = find_uicomponent(unit_uic, &amp;quot;unit_icon&amp;quot;, &amp;quot;prestige_cost&amp;quot;)&lt;br /&gt;
                    local prestige_cost_uic = find_uicomponent(prestige_cost_parent_uic, &amp;quot;Cost&amp;quot;)&lt;br /&gt;
                    prestige_cost_parent_uic:SetDockOffset(8, 19)&lt;br /&gt;
                    upkeep_cost_uic:SetDockOffset(8, 42)&lt;br /&gt;
                    -- repositioning the hslider_uic&lt;br /&gt;
                    if hslider_uic then&lt;br /&gt;
                        hslider_uic:SetDockOffset(8, 49)&lt;br /&gt;
                    end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, we then set the text, tooltip, and icon, disable the unit card UICs if the player doesn't have enough of the Pooled Resource, and hide the cost modified icon for ease.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;local faction = cm:get_faction(cm:get_local_faction_name(true))&lt;br /&gt;
                    local player_prestige = faction:pooled_resource_manager():resource(&amp;quot;emp_prestige&amp;quot;):value()&lt;br /&gt;
                    if player_prestige &amp;gt;= prestige_cost then&lt;br /&gt;
                        -- setting cost text&lt;br /&gt;
                        prestige_cost_uic:SetStateText(tostring(prestige_cost), &amp;quot;&amp;quot;)&lt;br /&gt;
                    else&lt;br /&gt;
                        -- setting cost text&lt;br /&gt;
                        prestige_cost_uic:SetStateText(tostring(&amp;quot;[[col:red]]&amp;quot;..prestige_cost..&amp;quot;[[/col]]&amp;quot;), &amp;quot;&amp;quot;)&lt;br /&gt;
                        local unit_uic_tooltip = unit_uic:GetTooltipText()&lt;br /&gt;
                        local cannot_recruit_loc = common.get_localised_string(&amp;quot;random_localisation_strings_string_StratHudbutton_Cannot_Recruit_Unit0&amp;quot;)&lt;br /&gt;
                        local insufficient_pr_loc = common.get_localised_string(&amp;quot;pear_insufficient_pr_prestige_tooltip&amp;quot;)&lt;br /&gt;
                        local unit_uic_tooltip_gsub = unit_uic_tooltip:gsub('[%W]', '')&lt;br /&gt;
                        local left_click_loc_gsub = (common.get_localised_string(&amp;quot;random_localisation_strings_string_StratHud_Unit_Card_Recruit_Selection&amp;quot;)):gsub('[%W]', '')&lt;br /&gt;
                        if string.match(unit_uic_tooltip_gsub, left_click_loc_gsub) then&lt;br /&gt;
                            unit_uic:SetTooltipText(unit_name..&amp;quot;\n\n&amp;quot;..cannot_recruit_loc..&amp;quot;\n\n&amp;quot;..insufficient_pr_loc, &amp;quot;&amp;quot;, true)&lt;br /&gt;
                            out(&amp;quot;PR UNIT COST LOG - Tooltip for just insufficient prestige.&amp;quot;)&lt;br /&gt;
                        else&lt;br /&gt;
                            unit_uic:SetTooltipText(unit_uic_tooltip..&amp;quot;\n&amp;quot;..insufficient_pr_loc, &amp;quot;&amp;quot;, true) &lt;br /&gt;
                            out(&amp;quot;PR UNIT COST LOG - Tooltip for prestige plus stuff.&amp;quot;)&lt;br /&gt;
                        end&lt;br /&gt;
                        -- disabling recruitment of unit&lt;br /&gt;
                        unit_uic:SetState(&amp;quot;inactive&amp;quot;)&lt;br /&gt;
                        unit_uic:SetDisabled(true)&lt;br /&gt;
                    end&lt;br /&gt;
                    -- setting cost icon&lt;br /&gt;
                    prestige_cost_uic:SetImagePath(&amp;quot;ui/skins/default/prestige_bar_icon.png&amp;quot;, 0)&lt;br /&gt;
                    -- setting cost tooltip&lt;br /&gt;
                    prestige_cost_parent_uic:SetTooltipText(common.get_localised_string(&amp;quot;pear_pr_prestige_cost_tooltip&amp;quot;), &amp;quot;&amp;quot;, true) &lt;br /&gt;
                    -- setting the cost modified icon to invisible as the CCO is still for recruitment cost so make it appear when intended&lt;br /&gt;
                    local cost_modified_icon_uic = find_uicomponent(prestige_cost_uic, &amp;quot;cost_modified_icon&amp;quot;)&lt;br /&gt;
                    cost_modified_icon_uic:SetVisible(false)&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 🎮 Triggering the UI ==&lt;br /&gt;
To make the UI components work we need listeners! The first one is &amp;lt;code&amp;gt;PanelOpenedCampaign&amp;lt;/code&amp;gt;. We can use this to tell when the main recruitment panel &amp;lt;code&amp;gt;&amp;quot;units_recruitment&amp;quot;&amp;lt;/code&amp;gt; is open so we can start setting up our UI. This is important because the UI usually refreshes when certain UICs are clicked which causes the panel to re-open. We also need a saved value to make sure the listener doesn't continually resize the parent UI components every time something is clicked. Together the listener looks like this:&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;code&amp;gt;    core:add_listener(&lt;br /&gt;
        &amp;quot;EXAMPLE_PANEL_OPENED&amp;quot;,&lt;br /&gt;
        &amp;quot;PanelOpenedCampaign&amp;quot;,&lt;br /&gt;
        function(context)&lt;br /&gt;
            return context.string == &amp;quot;units_recruitment&amp;quot;&lt;br /&gt;
        end,&lt;br /&gt;
        function()&lt;br /&gt;
            out(&amp;quot;PR UNIT COST LOG - units_recruitment panel opened.&amp;quot;)&lt;br /&gt;
            if cm:get_saved_value(&amp;quot;EXAMPLE_UICS_INITIALISED&amp;quot;) ~= true then&lt;br /&gt;
                cm:set_saved_value(&amp;quot;EXAMPLE_UICS_INITIALISED&amp;quot;, true)&lt;br /&gt;
                initialise_uics()&lt;br /&gt;
            else&lt;br /&gt;
                out(&amp;quot;PR UNIT COST LOG - finalise_uics() from pr_unit_cost_units_recruitment_opened.&amp;quot;)&lt;br /&gt;
                finalise_uics()&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
        true&lt;br /&gt;
    )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A refresh to the UI occurs when switching army stance. This messes up the sizing of the parent panels. To account for this we need to use &amp;lt;code&amp;gt;ComponentLClickUp&amp;lt;/code&amp;gt; which checks when the stance changes occur like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;core:add_listener(&lt;br /&gt;
        &amp;quot;EXAMPLE_UICS_CLICKED&amp;quot;,&lt;br /&gt;
        &amp;quot;ComponentLClickUp&amp;quot;,&lt;br /&gt;
        true,&lt;br /&gt;
        function(context)&lt;br /&gt;
            if string.match(context.string, &amp;quot;button_MILITARY_FORCE_ACTIVE_STANCE_TYPE_SET_CAMP&amp;quot;) then&lt;br /&gt;
                cm:callback(&lt;br /&gt;
                    function()&lt;br /&gt;
                        if cm:get_saved_value(&amp;quot;EXAMPLE_ENCAMP_CLICKED&amp;quot;) ~= true then&lt;br /&gt;
                            cm:set_saved_value(&amp;quot;EXAMPLE_ENCAMP_CLICKED&amp;quot;, true)&lt;br /&gt;
                            initialise_uics()&lt;br /&gt;
                        else&lt;br /&gt;
                            out(&amp;quot;PR UNIT COST LOG - finalise_uics() from pr_unit_cost_finalise_uics.&amp;quot;)&lt;br /&gt;
                            finalise_uics()&lt;br /&gt;
                        end&lt;br /&gt;
                    end, &lt;br /&gt;
                    0.1&lt;br /&gt;
                )&lt;br /&gt;
            elseif string.match(context.string, &amp;quot;button_MILITARY_FORCE_ACTIVE_STANCE_TYPE&amp;quot;) then&lt;br /&gt;
                cm:callback(&lt;br /&gt;
                    function()&lt;br /&gt;
                        out(&amp;quot;PR UNIT COST LOG - finalise_uics() from pr_unit_cost_finalise_uics.&amp;quot;)&lt;br /&gt;
                        finalise_uics()&lt;br /&gt;
                    end, &lt;br /&gt;
                    0.1&lt;br /&gt;
                )&lt;br /&gt;
            end&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''*'''This listener is '''used again later''' and combined with something else.&lt;br /&gt;
&lt;br /&gt;
Now we need to use &amp;lt;code&amp;gt;PanelClosedCampaign&amp;lt;/code&amp;gt; to reset our saved values when the entire &amp;lt;code&amp;gt;&amp;quot;units_panel&amp;quot;&amp;lt;/code&amp;gt; closes.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;core:add_listener(&lt;br /&gt;
        &amp;quot;EXAMPLE_PANEL_CLOSED&amp;quot;,&lt;br /&gt;
        &amp;quot;PanelClosedCampaign&amp;quot;,&lt;br /&gt;
        function(context)&lt;br /&gt;
            return context.string == &amp;quot;units_panel&amp;quot;&lt;br /&gt;
        end,&lt;br /&gt;
        function()&lt;br /&gt;
            out(&amp;quot;PR UNIT COST LOG - units_panel panel closed.&amp;quot;)&lt;br /&gt;
            cm:set_saved_value(&amp;quot;EXAMPLE_UICS_INITIALISED&amp;quot;, false)&lt;br /&gt;
            cm:set_saved_value(&amp;quot;EXAMPLE_ENCAMP_CLICKED&amp;quot;, false)&lt;br /&gt;
        end,&lt;br /&gt;
        true&lt;br /&gt;
    )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next we need to use &amp;lt;code&amp;gt;ComponentLClickUp&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;UITrigger&amp;lt;/code&amp;gt;. These listeners act as a pair — &amp;lt;code&amp;gt;ComponentLClickUp&amp;lt;/code&amp;gt; sends a message using &amp;lt;code&amp;gt;TriggerCampaignScriptEvent&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;UITrigger&amp;lt;/code&amp;gt; to keep things multiplayer-friendly (for more info on how that works see [https://tw-modding.com/wiki/Multiplayer_Desyncs this guide]). &lt;br /&gt;
&lt;br /&gt;
What is that message you may ask? Well, when the mouse hovers over a unit card, the stats panel for the unit becomes visible. At the moment the unit card is clicked, &amp;lt;code&amp;gt;ComponentLClickUp&amp;lt;/code&amp;gt; gets the name of the unit from the stats panel and makes a saved value for it. It checks it against our onscreen name loc provided in our table and if they match then&lt;br /&gt;
&lt;br /&gt;
[[File:klopp-boom2.gif|250px]]&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;code&amp;gt;local unit_info_uic = find_uicomponent(core:get_ui_root(), &amp;quot;hud_campaign&amp;quot;, &amp;quot;unit_info_panel_adopter&amp;quot;, &amp;quot;unit_information_parent&amp;quot;, &amp;quot;unit_info_panel_holder_parent&amp;quot;, &amp;quot;unit_info_panel_holder&amp;quot;, &amp;quot;unit_information&amp;quot;, &amp;quot;info_parent&amp;quot;, &amp;quot;info_panel&amp;quot;, &amp;quot;tx_unit-type&amp;quot;)&lt;br /&gt;
            if unit_info_uic then&lt;br /&gt;
                local unit_ui_name = unit_info_uic:GetStateText()&lt;br /&gt;
                for i = 1, #pr_units do&lt;br /&gt;
                    local unit_name = common.get_localised_string(pr_units[i].unit_name_loc)&lt;br /&gt;
                    if unit_ui_name == unit_name then&lt;br /&gt;
                        cm:set_saved_value(&amp;quot;EXAMPLE_UNIT_NAME&amp;quot;, unit_name)&lt;br /&gt;
                        CampaignUI.TriggerCampaignScriptEvent(cm:get_faction(cm:get_local_faction_name(true)):command_queue_index(), context.string ..&amp;quot;Clicked&amp;quot;)&lt;br /&gt;
                        return&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
        true&lt;br /&gt;
    )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''*'''This then combines with the encamp stance check into the same listener.&lt;br /&gt;
&lt;br /&gt;
Finally, you have the &amp;lt;code&amp;gt;UITrigger&amp;lt;/code&amp;gt; listener which receives the message. This then adds or subtracts the Pooled Resource from the player depending on whether they've recruited the unit or cancelled recruitment.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;core:add_listener(&lt;br /&gt;
        &amp;quot;pr_unit_cost_handle_pr_cost_ui_trigger&amp;quot;,&lt;br /&gt;
        &amp;quot;UITrigger&amp;quot;,&lt;br /&gt;
        true,&lt;br /&gt;
        function(context)&lt;br /&gt;
            for i = 1, #pr_units do&lt;br /&gt;
                local unit_name = common.get_localised_string(pr_units[i].unit_name_loc)&lt;br /&gt;
                if unit_name == cm:get_saved_value(&amp;quot;EXAMPLE_UNIT_NAME&amp;quot;) then&lt;br /&gt;
                    local unit_uic = pr_units[i].unit_uic&lt;br /&gt;
                    local prestige_cost = pr_units[i].prestige_cost&lt;br /&gt;
                    if context:trigger() == unit_uic..&amp;quot;Clicked&amp;quot; then&lt;br /&gt;
                        local faction_cqi = context:faction_cqi();&lt;br /&gt;
                        local faction_key = cm:model():faction_for_command_queue_index(faction_cqi):name() &lt;br /&gt;
                        cm:faction_add_pooled_resource(faction_key, &amp;quot;emp_prestige&amp;quot;, &amp;quot;events_negative&amp;quot;, -prestige_cost)&lt;br /&gt;
                        return&lt;br /&gt;
                    elseif context:trigger():starts_with(&amp;quot;Queued&amp;quot;) then&lt;br /&gt;
                        local faction_cqi = context:faction_cqi();&lt;br /&gt;
                        local faction_key = cm:model():faction_for_command_queue_index(faction_cqi):name() &lt;br /&gt;
                        cm:faction_add_pooled_resource(faction_key, &amp;quot;emp_prestige&amp;quot;, &amp;quot;events_negative&amp;quot;, prestige_cost)&lt;br /&gt;
                        return&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end,&lt;br /&gt;
        true&lt;br /&gt;
    )&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And that's it!&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=699</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=699"/>
		<updated>2023-07-01T14:56:23Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* Help Out */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== NEW WEBSITE ==&lt;br /&gt;
Yes, yes, we're on our sixth or seventh or eight iteration of this website!&lt;br /&gt;
&lt;br /&gt;
This newest version is built upon MediaWiki (same thing Wikipedia uses), and is very much a work in progress, but it's hopefully a much better time all around.&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/dd4TUDm Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
== Help Out ==&lt;br /&gt;
To give a hand, please check out the page [[Meta]] for the various bits of stuff we've marked as necessary. There are also pages in [[:Category:To Edit]] which have listed changes needed.&lt;br /&gt;
&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=698</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=698"/>
		<updated>2023-07-01T14:55:52Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
[[:Category:To Edit]]&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
* &amp;lt;s&amp;gt;Look into WYSIWYG editor for the wiki. Previously used version was buggy, but it might be better on the latest update of MediaWiki.&amp;lt;/s&amp;gt;&lt;br /&gt;
** Works perfectly on the new version!&lt;br /&gt;
* Search for better moderation tools, more all-in-one packages.&lt;br /&gt;
* Setup a more robust sidebar, include links to the Modding Den and such.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Move&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;br /&gt;
* Pages for each tool - RPFM, Assembly Kit, mod manager[s], etc. Sections for installation, usage, glossary, and helpful tips (ie. MyMod in RPFM)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=697</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=697"/>
		<updated>2023-07-01T14:54:49Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=696</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=696"/>
		<updated>2023-07-01T14:54:22Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* Help Out */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== NEW WEBSITE ==&lt;br /&gt;
Yes, yes, we're on our sixth or seventh or eight iteration of this website!&lt;br /&gt;
&lt;br /&gt;
This newest version is built upon MediaWiki (same thing Wikipedia uses), and is very much a work in progress, but it's hopefully a much better time all around.&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/dd4TUDm Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
== Help Out ==&lt;br /&gt;
[[Meta]]&lt;br /&gt;
&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
&lt;br /&gt;
- [[Tutorial:Main Page|Tutorials]] should be named &amp;quot;Tutorial:Tutorial Name Here&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- Any other page can be named anything else, it doesn't matter. Please mind that only one page can exist with that name, of course, so be proper with your names.&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=695</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=695"/>
		<updated>2023-07-01T14:43:39Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
** ../../tw_modding_resources/index.html|Testing!&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=694</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=694"/>
		<updated>2023-07-01T14:43:19Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
** ../tw_modding_resources/index.html|Testing!&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=693</id>
		<title>Lua/First Script</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=693"/>
		<updated>2023-06-11T22:51:30Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this first step tutorial, we're going to learn:&lt;br /&gt;
&lt;br /&gt;
* How to load &amp;amp; run a custom Lua script&lt;br /&gt;
* How timing works, at a large level, with scripts&lt;br /&gt;
* How to print out game information to interrogate the state of the game&lt;br /&gt;
* How simple variables work&lt;br /&gt;
&lt;br /&gt;
Let's create our first script together!&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
First thing's first, let's crack open RPFM to create our new Mod. In RPFM, I'm going to use MyMod -&amp;gt; New MyMod, to create a new easy-to-use mod system. If you haven't already, follow the setup guides in [[RPFM]] for setting up preferences and paths.&lt;br /&gt;
&lt;br /&gt;
[[File:First Script 01.png|frameless|712x712px]]&lt;br /&gt;
&lt;br /&gt;
RPFM will then open up our new MyMod. Within it, use MyMod -&amp;gt; Export, which will unload the contents of the newly created (almost entirely empty) MyMod into your specified MyMods folder. I have this folder pinned to my quick access, but you can also get there with MyMod -&amp;gt; Open MyMod Folder, and navigating down to the newly created MyMod.&lt;br /&gt;
&lt;br /&gt;
Now we can right click this folder and use the newly added &amp;quot;Open with Code&amp;quot; button, which will take the targeted mod folder and open it within Visual Studio Code!&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Navigation ==&lt;br /&gt;
When we open up in Visual Studio Code, we'll see something that looks a little bit like this - it might differ slightly, that's totally okay!&lt;br /&gt;
[[File:First script 2.png|none|thumb|1061x1061px|It might seem like quite a lot at first, but we'll get used to it! Just make sure to set the settings to dark mode if you're not insane.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before we get too far, let's break down some of the parts of what we're looking at here, and set up our windows so we have everything we need.&lt;br /&gt;
&lt;br /&gt;
=== Primary Bar ===&lt;br /&gt;
On the very left, we have what VSCode calls the &amp;quot;Primary Bar&amp;quot;. It has a few things here - the top has the two files stacked on each other, a search button below that, three buttons we don't have to worry too much about yet, and a Bookmark button. The bottom has our Account and Manage button. '''If you haven't already''', click into the Manage button and set our Profile to the correct one. I have mine saved as &amp;quot;TW Lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The part of the primary bar we care most about is the top button, the &amp;quot;Explorer&amp;quot;. Think of this as your file navigation - it's effectively the same as navigating the Windows File Explorer, but it has some extra goodies that will be nice for us.&lt;br /&gt;
[[File:First script 3.png|left|thumb|578x578px]]&lt;br /&gt;
At the top of the Explorer, we have &amp;quot;Open Editors&amp;quot;. This will show us all of our actively opened files - we'll see this shortly!&lt;br /&gt;
&lt;br /&gt;
Below that, we have a tab for the currently opened folder. My folder is named babys_first_script, so that's what shows as the name here. Inside are all of the folders AND files that exist within my folder on my PC. We can open, create, rename, and delete any file within to our heart's content, and edit as long as Visual Studio Code can edit it. VSCode can edit essentially any text file, which is what all code files are, effectively. Based on the type of text file, VSCode will handle it differently - it knows the difference between a .lua and a .json file, and will react accordingly to the specifications of either language.&lt;br /&gt;
&lt;br /&gt;
Below that, we had &amp;quot;TODOs: Tree&amp;quot;, which is an extension preloaded with our Profile. This is one of my favorite tabs, because I can leave notes for myself to do stuff later and they will be displayed in this window.&lt;br /&gt;
&lt;br /&gt;
Below that are Outline and Timeline, which I rarely use but can sometimes be nice. Outline will show us the layout of our code, and Timeline will show us previous local history for saving/editing these files, and more details if we're using GitHub or another version control software.&lt;br /&gt;
&lt;br /&gt;
The Search button is also incredibly useful, for reasons that may be obvious.&lt;br /&gt;
&lt;br /&gt;
=== Menu Bar ===&lt;br /&gt;
On the very top, we have our conveniently named Top Bar, or Menu Bar. You've seen these a billion times before. There's a LOT of stuff up here, but in my five years of using this program for TW Lua I've only really cared about a couple buttons within.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File&amp;quot; is going to be our best friend, for opening new windows, saving, and creating new files. Edit/Selection/View have a load of commands in them, and they may be good to reference often early on to see shortcuts for saving and other helpful code shortcuts, like duplicating text or renaming stuff.&lt;br /&gt;
&lt;br /&gt;
For now, what we should do is click View -&amp;gt; Problems, which will open up a new bottom bar for us. We only care about the &amp;quot;Problems&amp;quot; tab that shows up.&lt;br /&gt;
&lt;br /&gt;
=== Customizabilitization ===&lt;br /&gt;
Let's introduce the idea here that VSCode is '''super duper''' flexible with its layout. Anything on your screen right now can be put somewhere else, including individual tabs, buttons, anything. We can move Problems as a button to the Primary Bar, the Explorer as a tab on the bottom, and TODOs on the right all alone.&lt;br /&gt;
[[File:First script 4.png|thumb|824x824px]]&lt;br /&gt;
It's a bit clunky and not exactly what I need, but it's as good time as any to show you how flexible it can get.&lt;br /&gt;
&lt;br /&gt;
For now, I'm going to plop Search and TODOs on my new right sidebar stacked on one another, I'm going to right click one of the tabs at the bottom and deselect &amp;quot;Terminal&amp;quot;, &amp;quot;Output&amp;quot;, and &amp;quot;Debug Console&amp;quot;, and keep my left Primary Bar as is otherwise and open back up the Explorer.&lt;br /&gt;
&lt;br /&gt;
== Script Creation ==&lt;br /&gt;
Okay, enough preamble. Let's get it started.&lt;br /&gt;
&lt;br /&gt;
=== The Plan ===&lt;br /&gt;
Our standard first step for creating a new script is the first step we should do whenever making a new mod or system: having a plan, something we want. For this one, our goal is going to be simple. I want the following:&lt;br /&gt;
&lt;br /&gt;
* When the game starts, I want to output a message to a text file that tells me the game started, and tells me where my starting faction leader and capital region are.&lt;br /&gt;
* On every turn after that, I want to give my faction some extra gold.&lt;br /&gt;
* If I'm playing as Karl Franz, I want to give my faction another two armies.&lt;br /&gt;
* I swear it's balanced.&lt;br /&gt;
&lt;br /&gt;
=== Make It ===&lt;br /&gt;
[[File:First script 5.png|left|thumb|Second button from the left!]]&lt;br /&gt;
In VSC, go to the Explorer, and hover over the currently-opened-folder tab. You can either right click within the white space and press &amp;quot;New Folder&amp;quot;, or press the New Folder button on the tab for the currently opened folder.&lt;br /&gt;
&lt;br /&gt;
Name the empty folder that's created `script`. All scripts we write will be in this main folder. With this folder selected, create a new folder again, and call this one &amp;quot;campaign&amp;quot;. Do it again, calling the third &amp;quot;mod&amp;quot;, making our full path script/campaign/mod.&amp;lt;blockquote&amp;gt;'''NOTE:''' This folder path is one of several that is specified by Creative Assembly in more recent games, for modders to add scripts to which get automatically loaded. This behavior exists in Warhammer II, Warhammer III, Three Kingdoms, and Troy. It may continue for future games, but any game before Warhammer II needs a different way to load scripts.&lt;br /&gt;
&lt;br /&gt;
For more information, check out [[Lua/Loading Scripts]].&amp;lt;/blockquote&amp;gt;Within script/campaign/mod, now either right click the folder and press &amp;quot;New Text File&amp;quot;, or use the first button on the tab to create a new file. I'm going to name mine &amp;quot;totally_not_cheats.lua&amp;quot;. '''The .lua extension is required, don't skip it!'''&lt;br /&gt;
&lt;br /&gt;
=== Start It ===&lt;br /&gt;
With our newly created file, our VSC layout will change ever so slightly. In &amp;quot;Open Editors&amp;quot;, we'll see our fresh new baby script created; and in the central window, we'll see a new tab that's named the same as our new file, and an empty text file in the center with just the number &amp;quot;1&amp;quot; in it.&lt;br /&gt;
[[File:First script 6.png|none|thumb|894x894px|Notice the lil' moon symbol next to our file? That's because Lua is Portuguese for moon!]]&lt;br /&gt;
We'll kick off our script with the first piece of the puzzle, outputting some text to a file so we can read and interface with our scripts.&lt;br /&gt;
&lt;br /&gt;
Let's get it going with a function called `out()`. This is a CA-defined function that they use all over their scripts, to print out to a text file various bits of info about the game, for debugging and logging purposes. It's a really handy system that'll let you know for certain what's actually going on in your scripts at runtime, since we can't truly test our script outside of the game.&lt;br /&gt;
&lt;br /&gt;
To use the `out` function, we just have to write that word, put an open parenthesis, put in what we want to output, and then write a closing parenthesis. Let's try the old standard, and toss in the following:&amp;lt;blockquote&amp;gt;out( Hello World! )&amp;lt;/blockquote&amp;gt;And we should be goo- oh no! Everything's red! Why are there so many problems?!&lt;br /&gt;
[[File:First script 7.png|thumb|563x563px|If you don't see the above problems or red text, you probably didn't do the setup correctly in the previous lesson. Do it!]]&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
This will be something we'll see maybe a million times as we go forward, and it's important to not get too stressed out about it early on.&lt;br /&gt;
&lt;br /&gt;
Because of our work in [[Lua/Setup]], we now have access to a right proper debugging system that will yell at us when we do something wrong.&lt;br /&gt;
&lt;br /&gt;
There's a lot of confusing bits here, and honestly, none of the problems listed are going to be specific enough to tell us what to do to fix it - at least in this situation. Some of them are telling us that we're arguing too much, one is talking about undefined globals, and one is just absolute pig latin saying it expected &amp;lt;exp&amp;gt;. None of those mean anything to us, but let's check out something that does - some documentation!&lt;br /&gt;
&lt;br /&gt;
If you hover over the word &amp;quot;out&amp;quot;, you'll see a popup that gives us some information about the function `out`. The most important bit is the following:&lt;br /&gt;
[[File:First script 8.png|none|thumb]]&lt;br /&gt;
This is our '''function definition'''. It tells us what the function is called, and what it expects within the parentheses. It's asking for something it calls &amp;quot;output&amp;quot;, and output is a string. '''String''' is the first of several Lua &amp;quot;types&amp;quot; we'll go over in this tutorial series. A '''string''' is text - and it's called such because it's a string of ''characters'' that make up a long piece of text. The issue we've had here is that, while `Hello World!` is text, Lua needs to be told that it's a string type. To do that, we just need to wrap quotation marks - either single or double, doesn't matter, but it can't be backticks or &amp;quot;pretty&amp;quot; quotations like what mobile phones default to. I learned that the hard way.&lt;br /&gt;
&lt;br /&gt;
The easiest way to do that is to highlight the entirety of Hello World! and type in the quotation mark, just one. VSCode will plop a quotation mark on either part of your selection, and all SEVEN of our problems will vanish through air.&lt;br /&gt;
[[File:First script 9.png|thumb|The white dot on our tab means this is an unsaved file; use Ctrl+S to save it!]]&lt;br /&gt;
&lt;br /&gt;
== Getting It In-Game ==&lt;br /&gt;
We have now an incredibly basic script that I'd like to test out.&lt;br /&gt;
&lt;br /&gt;
Now, the `out` function is defined by Creative Assembly within their games, but it comes '''disabled by default''' for retail. That means that while your code runs, it won't actually write anything to a log file. That way they can have their debugging tools, and we can opt into it, but it doesn't automatically happen for every single user.&lt;br /&gt;
&lt;br /&gt;
This disable-by-default can be overridden in different ways, depending on the game. As of the time of writing this guide, my favorite methods are:&lt;br /&gt;
&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2927955021 Mod Configuration Tool]'s  setting for enabling game logging, if available for that game.&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2789857593&amp;amp;searchtext=script+debug+activator Script Debug Activator] mod, if available for that game.&lt;br /&gt;
* Creating a file in your mod at `script/enable_console_logging`, with no extension. You can use VSCode and use add text file at that destination, add any text inside the file and save it.&lt;br /&gt;
&lt;br /&gt;
These may change or evolve as time goes on.&lt;br /&gt;
&lt;br /&gt;
=== Loading ===&lt;br /&gt;
Once you've got your script ready, and your game is set up to have script logs printed out, we'll want to load up our .pack file and get it set in game. For the sake of my soul and time, I'm going to assume we know how packs work, creating them and loading them, and the like.&lt;br /&gt;
&lt;br /&gt;
Step one, we've got to save our stuff in VSCode. Use File -&amp;gt; Save All.&amp;lt;blockquote&amp;gt;Worth a shout here - I altered the shortcut in Visual Studio Code for Save All, since it's maybe my most-used shortcut combination.&lt;br /&gt;
&lt;br /&gt;
If you go to Manage -&amp;gt; Keyboard Shortcuts and type in &amp;quot;save all&amp;quot; in the search bar, you can click on that shortcut and type in on your keyboard what you'd prefer. I use Ctrl+Alt+S, but set it to whatever makes you happy.&amp;lt;/blockquote&amp;gt;Then, in RPFM, use MyMod -&amp;gt; Import. Again, I added a keyboard shortcut here through RPFM - I set Import/Export to Ctrl+Alt+I/E. You can get there through PackFile -&amp;gt; Preferences -&amp;gt; Shortcuts.&lt;br /&gt;
&lt;br /&gt;
Import '''pulls in all the stuff from your MyMod folder into your pack''', while '''export does the opposite'''. I use these all the time, since I externally edit Lua files but internally edit database tables. You'll want to keep in mind where you're working, because if you edit a Lua file externally, and then a table file internally, without adding the changes from one to the other, you may end up overwriting some of your work. Because of that, I will only ever work in one sphere, then use Import/Export to make sure the folder and my .pack line up, and then edit in the other sphere.&lt;br /&gt;
&lt;br /&gt;
Save in RPFM, and use PackFile -&amp;gt; Install to move your .pack to the game folder. Tick it in your mod manager of choice, and load up a fresh campaign!&lt;br /&gt;
&lt;br /&gt;
=== Log File ===&lt;br /&gt;
The game-created log files will spit out in your game's folder - ie., steam/steamapps/common/Total War WARHAMMER III/. They are created as &amp;quot;script_log_DDMMYY_HHMM.txt&amp;quot;. So if I made one right now, it'd be &amp;quot;script_log_100623_1320.txt&amp;quot;, if you were wondering when I wrote this exact line.&lt;br /&gt;
&lt;br /&gt;
The game creates a new log file every time we enter the main menu, every time we enter a campaign, and every time we enter a battle - so if you only just started using script logs, there should be two or three in there depending on if you quit to main menu or to desktop after loading up your new campaign. Navigate to the latest one and open it up.&lt;br /&gt;
&lt;br /&gt;
Worth noting here, I have a file association set up to automatically open .txt files in Visual Studio Code, because I find it easier and quicker to navigate. If you right click the script log -&amp;gt; open with -&amp;gt; target Visual Studio Code, you can get it in that way. You can also simply grab the file from your file explorer and drag it into the main VSCode window, and it will be opened up within.&lt;br /&gt;
&lt;br /&gt;
There's going to be... a ''lot'' of stuff in here. A lot a lot. CA uses double quindrillion calls to `out()` throughout the game. We'll actually find that it's pretty cumbersome to navigate, and later on we'll create our '''own custom log files!''' But for now, let's navigate this chonker.&lt;br /&gt;
&lt;br /&gt;
=== Find Your Text ===&lt;br /&gt;
&amp;lt;small&amp;gt;''Sounds kinda like a platitude you'd find on a pillow in Kohl's.''&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our opened new script log, we should search for the words &amp;quot;Hello World!&amp;quot;. We can either do that using the Search tab we have set up, or clicking into the script log in the main window and using Ctrl+F.&lt;br /&gt;
[[File:First script 10.png|none|thumb|911x911px|Our first trigger of stuff in the game!Hey, did you put a naughty word instead of &amp;quot;Hello World!&amp;quot;? You lil nasty gremlin.]]&lt;br /&gt;
WE FUCKING DID IT HELL YES.&lt;br /&gt;
&lt;br /&gt;
And that's it, you're ready to script on your own!&lt;br /&gt;
&lt;br /&gt;
Bye!&lt;br /&gt;
&lt;br /&gt;
== Timin' 'n Stuff ==&lt;br /&gt;
 You'll probably maybe notice, this text is triggered very, very early on. While it's maybe ~1000 lines of text in, it's only 1.8s seconds (at least, for me, with no other mods enabled) after the script log is created. This is earlier than it might sound. At this time, the game is still going through its loading procedures - this text was triggered before the loading bar even got to 20%!&lt;br /&gt;
Because of how early this is, the game '''is not ready to be accessed yet'''. The game doesn't yet know what factions own what regions, what turn it is, who the player is controlling, or anything like that. The game doesn't have a map object, you can't trigger a new battle, nothin'.&lt;br /&gt;
&lt;br /&gt;
What we need to do for our next step is '''learn how to listen''' and '''wait'''. Some of the most valuable things we can do in programming are listening and waiting for the right time.&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
'''''NOTE:''''' ''Not to be confused with the &amp;quot;Events&amp;quot; in-game, the messages and such that hang out with missions.''&lt;br /&gt;
&lt;br /&gt;
The game has a great deal of &amp;quot;events&amp;quot; that can be triggered. Events are a way for scripts to learn some information about things happening in the game - there are events that will inform us when a new turn has started, when a region has been destroyed, when a battle has ended, when a ritual has been completed, when a mission has been failed, among many many many more. We can even define our own - more on that later!&lt;br /&gt;
&lt;br /&gt;
The first event we care about is one of the most important - FirstTickAfterWorldCreated. This event is triggered immediately after the game is ready to access - about 80% of the way through the loading bar before the game is interactable for the user.&lt;br /&gt;
&lt;br /&gt;
Once this event happens, we can do things like ask the game what factions exist, what turn it is, where we are, who we are, etc. Before the world is created, we can only do a bare minimum of setting things up in advance.&lt;br /&gt;
&lt;br /&gt;
=== Flying the Time ===&lt;br /&gt;
To achieve our first goal - spitting out some information about our player faction - we're going to use a first tick callback and trigger our very own function!&lt;br /&gt;
&lt;br /&gt;
A first tick callback is a way to '''ask the game to run code on FirstTickAfterWorldCreated'''. Most of your mods will probably involve a first-tick-callback. We use them in the following format:&lt;br /&gt;
 cm:add_first_tick_callback(function_to_call)&lt;br /&gt;
But first, we have to create our own function. To do that, we use the following:&lt;br /&gt;
 local function my_function_name()&lt;br /&gt;
 -- do stuff&lt;br /&gt;
 end&lt;br /&gt;
where &amp;quot;my_function_name&amp;quot; can be anything you want. In this situation, I'm going to call the function &amp;quot;init&amp;quot;, short for &amp;quot;initialization&amp;quot;, because this is the startpoint of my entire script. Some people also prefer &amp;quot;main&amp;quot;. Whatever you want really, just make it clear for yourself and anyone else.&lt;br /&gt;
&lt;br /&gt;
''Eagle-eyed readers will notice that the two dashes they wrote in VSCode will be greyed out; these are called &amp;quot;comments&amp;quot;. These are incredibly useful to leave notes to ourselves and other people reading our scripts, to inform yourself and others of what's going on and how things work in our code.''&lt;br /&gt;
&lt;br /&gt;
To safely confirm that we're calling our new function at the right time, we're going to run our function, trigger another call to out(), and see if it works!&lt;br /&gt;
[[File:First script 11.png|thumb|418x418px]]&lt;br /&gt;
&lt;br /&gt;
=== Getting Our Info ===&lt;br /&gt;
With our first tick callback loading up properly, let's hop in and try to get some information about our played faction!&lt;br /&gt;
&lt;br /&gt;
In the beginning of our init() function, we need to define a fresh new &amp;lt;u&amp;gt;variable&amp;lt;/u&amp;gt; which will allow us to hold the faction &amp;quot;object&amp;quot; in memory. A variable is a piece of memory that your computer is going to set aside to hold some data for us - a variable can be a number, text, a function, or game objects like the faction.&lt;br /&gt;
&lt;br /&gt;
We'll get it using the get_local_player() function, which we can find in the scripting documentation: https://chadvandy.github.io/tw_modding_resources/WH3/campaign/campaign_manager.html#function:campaign_manager:get_local_faction&lt;br /&gt;
&lt;br /&gt;
We'll be learning a lot about how to use and read the script documentation going forward.&lt;br /&gt;
&lt;br /&gt;
In our init() function, we need to add the following line of code:&lt;br /&gt;
 local player_faction = cm:get_local_faction()&lt;br /&gt;
Where player_faction is the name of our new variable. It can be anything you want, much like init(), but it should '''make sense''' and '''be clear to read'''. It needs to be all one contiguous word, with only text, underscores, and non-leading numbers allowed (ie. my_faction_1 is allowed, 1_my_faction is not).&lt;br /&gt;
&lt;br /&gt;
Visual Studio Code should automate it for you, but make sure that it's after the init() keyword, is one line after the out() call, is before the `end` keyword, and is one tab over. I like to space my code out thought-by-thought, so this will be a bit lower than my out() code.&lt;br /&gt;
[[File:First script 12.png|none|thumb]]&lt;br /&gt;
The way we get information about this game object will be to ask it questions, using functions, or in this case '''methods'''.&lt;br /&gt;
&lt;br /&gt;
The first thing we want to ask is, hey, what's the faction's name please?&lt;br /&gt;
&lt;br /&gt;
To ask the game object questions, we need to use the variable name followed by the : sign. Our VSCode plugin will then, thankfully, list us with a great deal of suggestions that we can use. We can also reference [https://chadvandy.github.io/tw_modding_resources/WH3/scripting_doc.html#FACTION_SCRIPT_INTERFACE the scripting documentation for game objects].&lt;br /&gt;
&lt;br /&gt;
Thankfully, what we want isn't too far away:&lt;br /&gt;
[[File:First script 13.png|none|thumb|946x946px|The autofill will show us the description of this method, and what it returns - in this case, it returns a &amp;quot;string&amp;quot;, as we see after the -&amp;gt; line.]]&lt;br /&gt;
Whenever we call a function, if the function gives us something back, we have to assign it to a variable or it will go away and vanish into the ether, with no memory on your PC being used to &amp;quot;hold&amp;quot; onto it. Do that with something simple:&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local name = player_faction:name()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;I'll keep harping on it, but you can change `local name` to whatever you want - `local key`, `local bits`, `local ostrich_on_fire`, whatever.&lt;br /&gt;
&lt;br /&gt;
'''''NOTE:''''' ''It keeps saying name, but its actually referring to the faction's &amp;quot;key&amp;quot; as we'll see in a second - the &amp;quot;code name&amp;quot; is has in factions_tables.''&lt;br /&gt;
&lt;br /&gt;
Now that we have the information in our code, we can put it all together and print that out to the log file:&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
out( &amp;quot;Hello World!&amp;quot; ) &lt;br /&gt;
&lt;br /&gt;
local function init()&lt;br /&gt;
    out(&amp;quot;New game triggered!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local player_faction = cm:get_local_faction()&lt;br /&gt;
    local key = player_faction:name()&lt;br /&gt;
&lt;br /&gt;
    out(&amp;quot;Playing as &amp;quot; .. key)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
cm:add_first_tick_callback(init)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Learnin' Info ==&lt;br /&gt;
We've got something good going on, with information being spat out from the game telling us who we're playing as after the game has &amp;quot;begun&amp;quot; proper. This might seem like we've barely done anything, but this is the starting block that every game-altering script needs. We're off to a great start!&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=692</id>
		<title>Lua/First Script</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=692"/>
		<updated>2023-06-10T18:44:39Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this first step tutorial, we're going to learn:&lt;br /&gt;
&lt;br /&gt;
* How to load &amp;amp; run a custom Lua script&lt;br /&gt;
* How timing works, at a large level, with scripts&lt;br /&gt;
* How to print out game information to interrogate the state of the game&lt;br /&gt;
* How simple variables work&lt;br /&gt;
&lt;br /&gt;
Let's create our first script together!&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
First thing's first, let's crack open RPFM to create our new Mod. In RPFM, I'm going to use MyMod -&amp;gt; New MyMod, to create a new easy-to-use mod system. If you haven't already, follow the setup guides in [[RPFM]] for setting up preferences and paths.&lt;br /&gt;
&lt;br /&gt;
[[File:First Script 01.png|frameless|712x712px]]&lt;br /&gt;
&lt;br /&gt;
RPFM will then open up our new MyMod. Within it, use MyMod -&amp;gt; Export, which will unload the contents of the newly created (almost entirely empty) MyMod into your specified MyMods folder. I have this folder pinned to my quick access, but you can also get there with MyMod -&amp;gt; Open MyMod Folder, and navigating down to the newly created MyMod.&lt;br /&gt;
&lt;br /&gt;
Now we can right click this folder and use the newly added &amp;quot;Open with Code&amp;quot; button, which will take the targeted mod folder and open it within Visual Studio Code!&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Navigation ==&lt;br /&gt;
When we open up in Visual Studio Code, we'll see something that looks a little bit like this - it might differ slightly, that's totally okay!&lt;br /&gt;
[[File:First script 2.png|none|thumb|1061x1061px|It might seem like quite a lot at first, but we'll get used to it! Just make sure to set the settings to dark mode if you're not insane.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before we get too far, let's break down some of the parts of what we're looking at here, and set up our windows so we have everything we need.&lt;br /&gt;
&lt;br /&gt;
=== Primary Bar ===&lt;br /&gt;
On the very left, we have what VSCode calls the &amp;quot;Primary Bar&amp;quot;. It has a few things here - the top has the two files stacked on each other, a search button below that, three buttons we don't have to worry too much about yet, and a Bookmark button. The bottom has our Account and Manage button. '''If you haven't already''', click into the Manage button and set our Profile to the correct one. I have mine saved as &amp;quot;TW Lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The part of the primary bar we care most about is the top button, the &amp;quot;Explorer&amp;quot;. Think of this as your file navigation - it's effectively the same as navigating the Windows File Explorer, but it has some extra goodies that will be nice for us.&lt;br /&gt;
[[File:First script 3.png|left|thumb|578x578px]]&lt;br /&gt;
At the top of the Explorer, we have &amp;quot;Open Editors&amp;quot;. This will show us all of our actively opened files - we'll see this shortly!&lt;br /&gt;
&lt;br /&gt;
Below that, we have a tab for the currently opened folder. My folder is named babys_first_script, so that's what shows as the name here. Inside are all of the folders AND files that exist within my folder on my PC. We can open, create, rename, and delete any file within to our heart's content, and edit as long as Visual Studio Code can edit it. VSCode can edit essentially any text file, which is what all code files are, effectively. Based on the type of text file, VSCode will handle it differently - it knows the difference between a .lua and a .json file, and will react accordingly to the specifications of either language.&lt;br /&gt;
&lt;br /&gt;
Below that, we had &amp;quot;TODOs: Tree&amp;quot;, which is an extension preloaded with our Profile. This is one of my favorite tabs, because I can leave notes for myself to do stuff later and they will be displayed in this window.&lt;br /&gt;
&lt;br /&gt;
Below that are Outline and Timeline, which I rarely use but can sometimes be nice. Outline will show us the layout of our code, and Timeline will show us previous local history for saving/editing these files, and more details if we're using GitHub or another version control software.&lt;br /&gt;
&lt;br /&gt;
The Search button is also incredibly useful, for reasons that may be obvious.&lt;br /&gt;
&lt;br /&gt;
=== Menu Bar ===&lt;br /&gt;
On the very top, we have our conveniently named Top Bar, or Menu Bar. You've seen these a billion times before. There's a LOT of stuff up here, but in my five years of using this program for TW Lua I've only really cared about a couple buttons within.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File&amp;quot; is going to be our best friend, for opening new windows, saving, and creating new files. Edit/Selection/View have a load of commands in them, and they may be good to reference often early on to see shortcuts for saving and other helpful code shortcuts, like duplicating text or renaming stuff.&lt;br /&gt;
&lt;br /&gt;
For now, what we should do is click View -&amp;gt; Problems, which will open up a new bottom bar for us. We only care about the &amp;quot;Problems&amp;quot; tab that shows up.&lt;br /&gt;
&lt;br /&gt;
=== Customizabilitization ===&lt;br /&gt;
Let's introduce the idea here that VSCode is '''super duper''' flexible with its layout. Anything on your screen right now can be put somewhere else, including individual tabs, buttons, anything. We can move Problems as a button to the Primary Bar, the Explorer as a tab on the bottom, and TODOs on the right all alone.&lt;br /&gt;
[[File:First script 4.png|thumb|824x824px]]&lt;br /&gt;
It's a bit clunky and not exactly what I need, but it's as good time as any to show you how flexible it can get.&lt;br /&gt;
&lt;br /&gt;
For now, I'm going to plop Search and TODOs on my new right sidebar stacked on one another, I'm going to right click one of the tabs at the bottom and deselect &amp;quot;Terminal&amp;quot;, &amp;quot;Output&amp;quot;, and &amp;quot;Debug Console&amp;quot;, and keep my left Primary Bar as is otherwise and open back up the Explorer.&lt;br /&gt;
&lt;br /&gt;
== Script Creation ==&lt;br /&gt;
Okay, enough preamble. Let's get it started.&lt;br /&gt;
&lt;br /&gt;
=== The Plan ===&lt;br /&gt;
Our standard first step for creating a new script is the first step we should do whenever making a new mod or system: having a plan, something we want. For this one, our goal is going to be simple. I want the following:&lt;br /&gt;
&lt;br /&gt;
* When the game starts, I want to output a message to a text file that tells me the game started, and tells me where my starting faction leader and capital region are.&lt;br /&gt;
* On every turn after that, I want to give my faction some extra gold.&lt;br /&gt;
* If I'm playing as Karl Franz, I want to give my faction another two armies.&lt;br /&gt;
* I swear it's balanced.&lt;br /&gt;
&lt;br /&gt;
=== Make It ===&lt;br /&gt;
[[File:First script 5.png|left|thumb|Second button from the left!]]&lt;br /&gt;
In VSC, go to the Explorer, and hover over the currently-opened-folder tab. You can either right click within the white space and press &amp;quot;New Folder&amp;quot;, or press the New Folder button on the tab for the currently opened folder.&lt;br /&gt;
&lt;br /&gt;
Name the empty folder that's created `script`. All scripts we write will be in this main folder. With this folder selected, create a new folder again, and call this one &amp;quot;campaign&amp;quot;. Do it again, calling the third &amp;quot;mod&amp;quot;, making our full path script/campaign/mod.&amp;lt;blockquote&amp;gt;'''NOTE:''' This folder path is one of several that is specified by Creative Assembly in more recent games, for modders to add scripts to which get automatically loaded. This behavior exists in Warhammer II, Warhammer III, Three Kingdoms, and Troy. It may continue for future games, but any game before Warhammer II needs a different way to load scripts.&lt;br /&gt;
&lt;br /&gt;
For more information, check out [[Lua/Loading Scripts]].&amp;lt;/blockquote&amp;gt;Within script/campaign/mod, now either right click the folder and press &amp;quot;New Text File&amp;quot;, or use the first button on the tab to create a new file. I'm going to name mine &amp;quot;totally_not_cheats.lua&amp;quot;. '''The .lua extension is required, don't skip it!'''&lt;br /&gt;
&lt;br /&gt;
=== Start It ===&lt;br /&gt;
With our newly created file, our VSC layout will change ever so slightly. In &amp;quot;Open Editors&amp;quot;, we'll see our fresh new baby script created; and in the central window, we'll see a new tab that's named the same as our new file, and an empty text file in the center with just the number &amp;quot;1&amp;quot; in it.&lt;br /&gt;
[[File:First script 6.png|none|thumb|894x894px|Notice the lil' moon symbol next to our file? That's because Lua is Portuguese for moon!]]&lt;br /&gt;
We'll kick off our script with the first piece of the puzzle, outputting some text to a file so we can read and interface with our scripts.&lt;br /&gt;
&lt;br /&gt;
Let's get it going with a function called `out()`. This is a CA-defined function that they use all over their scripts, to print out to a text file various bits of info about the game, for debugging and logging purposes. It's a really handy system that'll let you know for certain what's actually going on in your scripts at runtime, since we can't truly test our script outside of the game.&lt;br /&gt;
&lt;br /&gt;
To use the `out` function, we just have to write that word, put an open parenthesis, put in what we want to output, and then write a closing parenthesis. Let's try the old standard, and toss in the following:&amp;lt;blockquote&amp;gt;out( Hello World! )&amp;lt;/blockquote&amp;gt;And we should be goo- oh no! Everything's red! Why are there so many problems?!&lt;br /&gt;
[[File:First script 7.png|thumb|563x563px|If you don't see the above problems or red text, you probably didn't do the setup correctly in the previous lesson. Do it!]]&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
This will be something we'll see maybe a million times as we go forward, and it's important to not get too stressed out about it early on.&lt;br /&gt;
&lt;br /&gt;
Because of our work in [[Lua/Setup]], we now have access to a right proper debugging system that will yell at us when we do something wrong.&lt;br /&gt;
&lt;br /&gt;
There's a lot of confusing bits here, and honestly, none of the problems listed are going to be specific enough to tell us what to do to fix it - at least in this situation. Some of them are telling us that we're arguing too much, one is talking about undefined globals, and one is just absolute pig latin saying it expected &amp;lt;exp&amp;gt;. None of those mean anything to us, but let's check out something that does - some documentation!&lt;br /&gt;
&lt;br /&gt;
If you hover over the word &amp;quot;out&amp;quot;, you'll see a popup that gives us some information about the function `out`. The most important bit is the following:&lt;br /&gt;
[[File:First script 8.png|none|thumb]]&lt;br /&gt;
This is our '''function definition'''. It tells us what the function is called, and what it expects within the parentheses. It's asking for something it calls &amp;quot;output&amp;quot;, and output is a string. '''String''' is the first of several Lua &amp;quot;types&amp;quot; we'll go over in this tutorial series. A '''string''' is text - and it's called such because it's a string of ''characters'' that make up a long piece of text. The issue we've had here is that, while `Hello World!` is text, Lua needs to be told that it's a string type. To do that, we just need to wrap quotation marks - either single or double, doesn't matter, but it can't be backticks or &amp;quot;pretty&amp;quot; quotations like what mobile phones default to. I learned that the hard way.&lt;br /&gt;
&lt;br /&gt;
The easiest way to do that is to highlight the entirety of Hello World! and type in the quotation mark, just one. VSCode will plop a quotation mark on either part of your selection, and all SEVEN of our problems will vanish through air.&lt;br /&gt;
[[File:First script 9.png|thumb|The white dot on our tab means this is an unsaved file; use Ctrl+S to save it!]]&lt;br /&gt;
&lt;br /&gt;
== Getting It In-Game ==&lt;br /&gt;
We have now an incredibly basic script that I'd like to test out.&lt;br /&gt;
&lt;br /&gt;
Now, the `out` function is defined by Creative Assembly within their games, but it comes '''disabled by default''' for retail. That means that while your code runs, it won't actually write anything to a log file. That way they can have their debugging tools, and we can opt into it, but it doesn't automatically happen for every single user.&lt;br /&gt;
&lt;br /&gt;
This disable-by-default can be overridden in different ways, depending on the game. As of the time of writing this guide, my favorite methods are:&lt;br /&gt;
&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2927955021 Mod Configuration Tool]'s  setting for enabling game logging, if available for that game.&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2789857593&amp;amp;searchtext=script+debug+activator Script Debug Activator] mod, if available for that game.&lt;br /&gt;
* Creating a file in your mod at `script/enable_console_logging`, with no extension. You can use VSCode and use add text file at that destination, add any text inside the file and save it.&lt;br /&gt;
&lt;br /&gt;
These may change or evolve as time goes on.&lt;br /&gt;
&lt;br /&gt;
=== Loading ===&lt;br /&gt;
Once you've got your script ready, and your game is set up to have script logs printed out, we'll want to load up our .pack file and get it set in game. For the sake of my soul and time, I'm going to assume we know how packs work, creating them and loading them, and the like.&lt;br /&gt;
&lt;br /&gt;
Step one, we've got to save our stuff in VSCode. Use File -&amp;gt; Save All.&amp;lt;blockquote&amp;gt;Worth a shout here - I altered the shortcut in Visual Studio Code for Save All, since it's maybe my most-used shortcut combination.&lt;br /&gt;
&lt;br /&gt;
If you go to Manage -&amp;gt; Keyboard Shortcuts and type in &amp;quot;save all&amp;quot; in the search bar, you can click on that shortcut and type in on your keyboard what you'd prefer. I use Ctrl+Alt+S, but set it to whatever makes you happy.&amp;lt;/blockquote&amp;gt;Then, in RPFM, use MyMod -&amp;gt; Import. Again, I added a keyboard shortcut here through RPFM - I set Import/Export to Ctrl+Alt+I/E. You can get there through PackFile -&amp;gt; Preferences -&amp;gt; Shortcuts.&lt;br /&gt;
&lt;br /&gt;
Import '''pulls in all the stuff from your MyMod folder into your pack''', while '''export does the opposite'''. I use these all the time, since I externally edit Lua files but internally edit database tables. You'll want to keep in mind where you're working, because if you edit a Lua file externally, and then a table file internally, without adding the changes from one to the other, you may end up overwriting some of your work. Because of that, I will only ever work in one sphere, then use Import/Export to make sure the folder and my .pack line up, and then edit in the other sphere.&lt;br /&gt;
&lt;br /&gt;
Save in RPFM, and use PackFile -&amp;gt; Install to move your .pack to the game folder. Tick it in your mod manager of choice, and load up a fresh campaign!&lt;br /&gt;
&lt;br /&gt;
=== Log File ===&lt;br /&gt;
The game-created log files will spit out in your game's folder - ie., steam/steamapps/common/Total War WARHAMMER III/. They are created as &amp;quot;script_log_DDMMYY_HHMM.txt&amp;quot;. So if I made one right now, it'd be &amp;quot;script_log_100623_1320.txt&amp;quot;, if you were wondering when I wrote this exact line.&lt;br /&gt;
&lt;br /&gt;
The game creates a new log file every time we enter the main menu, every time we enter a campaign, and every time we enter a battle - so if you only just started using script logs, there should be two or three in there depending on if you quit to main menu or to desktop after loading up your new campaign. Navigate to the latest one and open it up.&lt;br /&gt;
&lt;br /&gt;
Worth noting here, I have a file association set up to automatically open .txt files in Visual Studio Code, because I find it easier and quicker to navigate. If you right click the script log -&amp;gt; open with -&amp;gt; target Visual Studio Code, you can get it in that way. You can also simply grab the file from your file explorer and drag it into the main VSCode window, and it will be opened up within.&lt;br /&gt;
&lt;br /&gt;
There's going to be... a ''lot'' of stuff in here. A lot a lot. CA uses double quindrillion calls to `out()` throughout the game. We'll actually find that it's pretty cumbersome to navigate, and later on we'll create our '''own custom log files!''' But for now, let's navigate this chonker.&lt;br /&gt;
&lt;br /&gt;
=== Find Your Text ===&lt;br /&gt;
&amp;lt;small&amp;gt;''Sounds kinda like a platitude you'd find on a pillow in Kohl's.''&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our opened new script log, we should search for the words &amp;quot;Hello World!&amp;quot;. We can either do that using the Search tab we have set up, or clicking into the script log in the main window and using Ctrl+F.&lt;br /&gt;
[[File:First script 10.png|none|thumb|911x911px|Our first trigger of stuff in the game!Hey, did you put a naughty word instead of &amp;quot;Hello World!&amp;quot;? You lil nasty gremlin.]]&lt;br /&gt;
WE FUCKING DID IT HELL YES.&lt;br /&gt;
&lt;br /&gt;
And that's it, you're ready to script on your own!&lt;br /&gt;
&lt;br /&gt;
Bye!&lt;br /&gt;
&lt;br /&gt;
== Timin' 'n Stuff ==&lt;br /&gt;
 You'll probably maybe notice, this text is triggered very, very early on. While it's maybe ~1000 lines of text in, it's only 1.8s seconds (at least, for me, with no other mods enabled) after the script log is created. This is earlier than it might sound. At this time, the game is still going through its loading procedures - this text was triggered before the loading bar even got to 20%!&lt;br /&gt;
Because of how early this is, the game '''is not ready to be accessed yet'''. The game doesn't yet know what factions own what regions, what turn it is, who the player is controlling, or anything like that. The game doesn't have a map object, you can't trigger a new battle, nothin'.&lt;br /&gt;
&lt;br /&gt;
What we need to do for our next step is '''learn how to listen''' and '''wait'''. Some of the most valuable things we can do in programming are listening and waiting for the right time.&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
'''''NOTE:''''' ''Not to be confused with the &amp;quot;Events&amp;quot; in-game, the messages and such that hang out with missions.''&lt;br /&gt;
&lt;br /&gt;
The game has a great deal of &amp;quot;events&amp;quot; that can be triggered. Events are a way for scripts to learn some information about things happening in the game - there are events that will inform us when a new turn has started, when a region has been destroyed, when a battle has ended, when a ritual has been completed, when a mission has been failed, among many many many more. We can even define our own - more on that later!&lt;br /&gt;
&lt;br /&gt;
The first event we care about is one of the most important - FirstTickAfterWorldCreated. This event is triggered immediately after the game is ready to access - about 80% of the way through the loading bar before the game is interactable for the user.&lt;br /&gt;
&lt;br /&gt;
Once this event happens, we can do things like ask the game what factions exist, what turn it is, where we are, who we are, etc. Before the world is created, we can only do a bare minimum of setting things up in advance.&lt;br /&gt;
&lt;br /&gt;
=== Flying the Time ===&lt;br /&gt;
To achieve our first goal - spitting out some information about our player faction - we're going to use a first tick callback and trigger our very own function!&lt;br /&gt;
&lt;br /&gt;
A first tick callback is a way to '''ask the game to run code on FirstTickAfterWorldCreated'''. Most of your mods will probably involve a first-tick-callback. We use them in the following format:&lt;br /&gt;
 cm:add_first_tick_callback(function_to_call)&lt;br /&gt;
But first, we have to create our own function. To do that, we use the following:&lt;br /&gt;
 local function my_function_name()&lt;br /&gt;
 -- do stuff&lt;br /&gt;
 end&lt;br /&gt;
where &amp;quot;my_function_name&amp;quot; can be anything you want. In this situation, I'm going to call the function &amp;quot;init&amp;quot;, short for &amp;quot;initialization&amp;quot;, because this is the startpoint of my entire script. Some people also prefer &amp;quot;main&amp;quot;. Whatever you want really, just make it clear for yourself and anyone else.&lt;br /&gt;
&lt;br /&gt;
''Eagle-eyed readers will notice that the two dashes they wrote in VSCode will be greyed out; these are called &amp;quot;comments&amp;quot;. These are incredibly useful to leave notes to ourselves and other people reading our scripts, to inform yourself and others of what's going on and how things work in our code.''&lt;br /&gt;
&lt;br /&gt;
To safely confirm that we're calling our new function at the right time, we're going to run our function, trigger another call to out(), and see if it works!&lt;br /&gt;
[[File:First script 11.png|thumb|418x418px]]&lt;br /&gt;
&lt;br /&gt;
=== Getting Our Info ===&lt;br /&gt;
With our first tick callback loading up properly, let's hop in and try to get some information about our played faction!&lt;br /&gt;
&lt;br /&gt;
In the beginning of our init() function, we need to define a fresh new &amp;lt;u&amp;gt;variable&amp;lt;/u&amp;gt; which will allow us to hold the faction &amp;quot;object&amp;quot; in memory. A variable is a piece of memory that your computer is going to set aside to hold some data for us - a variable can be a number, text, a function, or game objects like the faction.&lt;br /&gt;
&lt;br /&gt;
We'll get it using the get_local_player() function, which we can find in the scripting documentation: https://chadvandy.github.io/tw_modding_resources/WH3/campaign/campaign_manager.html#function:campaign_manager:get_local_faction&lt;br /&gt;
&lt;br /&gt;
We'll be learning a lot about how to use and read the script documentation going forward.&lt;br /&gt;
&lt;br /&gt;
In our init() function, we need to add the following line of code:&lt;br /&gt;
 local player_faction = cm:get_local_faction()&lt;br /&gt;
Where player_faction is the name of our new variable. It can be anything you want, much like init(), but it should '''make sense''' and '''be clear to read'''. It needs to be all one contiguous word, with only text, underscores, and non-leading numbers allowed (ie. my_faction_1 is allowed, 1_my_faction is not).&lt;br /&gt;
&lt;br /&gt;
Visual Studio Code should automate it for you, but make sure that it's after the init() keyword, is one line after the out() call, is before the `end` keyword, and is one tab over. I like to space my code out thought-by-thought, so this will be a bit lower than my out() code.&lt;br /&gt;
[[File:First script 12.png|none|thumb]]&lt;br /&gt;
The way we get information about this game object will be to ask it questions, using functions, or in this case '''methods'''.&lt;br /&gt;
&lt;br /&gt;
The first thing we want to ask is, hey, what's the faction's name please?&lt;br /&gt;
&lt;br /&gt;
To ask the game object questions, we need to use the variable name followed by the : sign. Our VSCode plugin will then, thankfully, list us with a great deal of suggestions that we can use. We can also reference [https://chadvandy.github.io/tw_modding_resources/WH3/scripting_doc.html#FACTION_SCRIPT_INTERFACE the scripting documentation for game objects].&lt;br /&gt;
&lt;br /&gt;
Thankfully, what we want isn't too far away:&lt;br /&gt;
[[File:First script 13.png|none|thumb|946x946px|The autofill will show us the description of this method, and what it returns - in this case, it returns a &amp;quot;string&amp;quot;, as we see after the -&amp;gt; line.]]&lt;br /&gt;
Whenever we call a function, if the function gives us something back, we have to assign it to a variable or it will go away and vanish into the ether, with no memory on your PC being used to &amp;quot;hold&amp;quot; onto it. Do that with something simple:&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local name = player_faction:name()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;I'll keep harping on it, but you can change `local name` to whatever you want - `local key`, `local bits`, `local ostrich_on_fire`, whatever.&lt;br /&gt;
&lt;br /&gt;
'''''NOTE:''''' ''It keeps saying name, but its actually referring to the faction's &amp;quot;key&amp;quot; as we'll see in a second - the &amp;quot;code name&amp;quot; is has in factions_tables.''&lt;br /&gt;
&lt;br /&gt;
Now that we have the information in our code, we can put it all together and print that out to the log file:&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
out( &amp;quot;Hello World!&amp;quot; ) &lt;br /&gt;
&lt;br /&gt;
local function init()&lt;br /&gt;
    out(&amp;quot;New game triggered!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    local player_faction = cm:get_local_faction()&lt;br /&gt;
    local key = player_faction:name()&lt;br /&gt;
&lt;br /&gt;
    out(&amp;quot;Playing as &amp;quot; .. key)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
cm:add_first_tick_callback(init)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=691</id>
		<title>Lua/First Script</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=691"/>
		<updated>2023-06-10T18:43:16Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this first step tutorial, we're going to learn:&lt;br /&gt;
&lt;br /&gt;
* How to load &amp;amp; run a custom Lua script&lt;br /&gt;
* How timing works, at a large level, with scripts&lt;br /&gt;
* How to print out game information to interrogate the state of the game&lt;br /&gt;
* How simple variables work&lt;br /&gt;
&lt;br /&gt;
Let's create our first script together!&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
First thing's first, let's crack open RPFM to create our new Mod. In RPFM, I'm going to use MyMod -&amp;gt; New MyMod, to create a new easy-to-use mod system. If you haven't already, follow the setup guides in [[RPFM]] for setting up preferences and paths.&lt;br /&gt;
&lt;br /&gt;
[[File:First Script 01.png|frameless|712x712px]]&lt;br /&gt;
&lt;br /&gt;
RPFM will then open up our new MyMod. Within it, use MyMod -&amp;gt; Export, which will unload the contents of the newly created (almost entirely empty) MyMod into your specified MyMods folder. I have this folder pinned to my quick access, but you can also get there with MyMod -&amp;gt; Open MyMod Folder, and navigating down to the newly created MyMod.&lt;br /&gt;
&lt;br /&gt;
Now we can right click this folder and use the newly added &amp;quot;Open with Code&amp;quot; button, which will take the targeted mod folder and open it within Visual Studio Code!&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Navigation ==&lt;br /&gt;
When we open up in Visual Studio Code, we'll see something that looks a little bit like this - it might differ slightly, that's totally okay!&lt;br /&gt;
[[File:First script 2.png|none|thumb|1061x1061px|It might seem like quite a lot at first, but we'll get used to it! Just make sure to set the settings to dark mode if you're not insane.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before we get too far, let's break down some of the parts of what we're looking at here, and set up our windows so we have everything we need.&lt;br /&gt;
&lt;br /&gt;
=== Primary Bar ===&lt;br /&gt;
On the very left, we have what VSCode calls the &amp;quot;Primary Bar&amp;quot;. It has a few things here - the top has the two files stacked on each other, a search button below that, three buttons we don't have to worry too much about yet, and a Bookmark button. The bottom has our Account and Manage button. '''If you haven't already''', click into the Manage button and set our Profile to the correct one. I have mine saved as &amp;quot;TW Lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The part of the primary bar we care most about is the top button, the &amp;quot;Explorer&amp;quot;. Think of this as your file navigation - it's effectively the same as navigating the Windows File Explorer, but it has some extra goodies that will be nice for us.&lt;br /&gt;
[[File:First script 3.png|left|thumb|578x578px]]&lt;br /&gt;
At the top of the Explorer, we have &amp;quot;Open Editors&amp;quot;. This will show us all of our actively opened files - we'll see this shortly!&lt;br /&gt;
&lt;br /&gt;
Below that, we have a tab for the currently opened folder. My folder is named babys_first_script, so that's what shows as the name here. Inside are all of the folders AND files that exist within my folder on my PC. We can open, create, rename, and delete any file within to our heart's content, and edit as long as Visual Studio Code can edit it. VSCode can edit essentially any text file, which is what all code files are, effectively. Based on the type of text file, VSCode will handle it differently - it knows the difference between a .lua and a .json file, and will react accordingly to the specifications of either language.&lt;br /&gt;
&lt;br /&gt;
Below that, we had &amp;quot;TODOs: Tree&amp;quot;, which is an extension preloaded with our Profile. This is one of my favorite tabs, because I can leave notes for myself to do stuff later and they will be displayed in this window.&lt;br /&gt;
&lt;br /&gt;
Below that are Outline and Timeline, which I rarely use but can sometimes be nice. Outline will show us the layout of our code, and Timeline will show us previous local history for saving/editing these files, and more details if we're using GitHub or another version control software.&lt;br /&gt;
&lt;br /&gt;
The Search button is also incredibly useful, for reasons that may be obvious.&lt;br /&gt;
&lt;br /&gt;
=== Menu Bar ===&lt;br /&gt;
On the very top, we have our conveniently named Top Bar, or Menu Bar. You've seen these a billion times before. There's a LOT of stuff up here, but in my five years of using this program for TW Lua I've only really cared about a couple buttons within.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File&amp;quot; is going to be our best friend, for opening new windows, saving, and creating new files. Edit/Selection/View have a load of commands in them, and they may be good to reference often early on to see shortcuts for saving and other helpful code shortcuts, like duplicating text or renaming stuff.&lt;br /&gt;
&lt;br /&gt;
For now, what we should do is click View -&amp;gt; Problems, which will open up a new bottom bar for us. We only care about the &amp;quot;Problems&amp;quot; tab that shows up.&lt;br /&gt;
&lt;br /&gt;
=== Customizabilitization ===&lt;br /&gt;
Let's introduce the idea here that VSCode is '''super duper''' flexible with its layout. Anything on your screen right now can be put somewhere else, including individual tabs, buttons, anything. We can move Problems as a button to the Primary Bar, the Explorer as a tab on the bottom, and TODOs on the right all alone.&lt;br /&gt;
[[File:First script 4.png|thumb|824x824px]]&lt;br /&gt;
It's a bit clunky and not exactly what I need, but it's as good time as any to show you how flexible it can get.&lt;br /&gt;
&lt;br /&gt;
For now, I'm going to plop Search and TODOs on my new right sidebar stacked on one another, I'm going to right click one of the tabs at the bottom and deselect &amp;quot;Terminal&amp;quot;, &amp;quot;Output&amp;quot;, and &amp;quot;Debug Console&amp;quot;, and keep my left Primary Bar as is otherwise and open back up the Explorer.&lt;br /&gt;
&lt;br /&gt;
== Script Creation ==&lt;br /&gt;
Okay, enough preamble. Let's get it started.&lt;br /&gt;
&lt;br /&gt;
=== The Plan ===&lt;br /&gt;
Our standard first step for creating a new script is the first step we should do whenever making a new mod or system: having a plan, something we want. For this one, our goal is going to be simple. I want the following:&lt;br /&gt;
&lt;br /&gt;
* When the game starts, I want to output a message to a text file that tells me the game started, and tells me where my starting faction leader and capital region are.&lt;br /&gt;
* On every turn after that, I want to give my faction some extra gold.&lt;br /&gt;
* If I'm playing as Karl Franz, I want to give my faction another two armies.&lt;br /&gt;
* I swear it's balanced.&lt;br /&gt;
&lt;br /&gt;
=== Make It ===&lt;br /&gt;
[[File:First script 5.png|left|thumb|Second button from the left!]]&lt;br /&gt;
In VSC, go to the Explorer, and hover over the currently-opened-folder tab. You can either right click within the white space and press &amp;quot;New Folder&amp;quot;, or press the New Folder button on the tab for the currently opened folder.&lt;br /&gt;
&lt;br /&gt;
Name the empty folder that's created `script`. All scripts we write will be in this main folder. With this folder selected, create a new folder again, and call this one &amp;quot;campaign&amp;quot;. Do it again, calling the third &amp;quot;mod&amp;quot;, making our full path script/campaign/mod.&amp;lt;blockquote&amp;gt;'''NOTE:''' This folder path is one of several that is specified by Creative Assembly in more recent games, for modders to add scripts to which get automatically loaded. This behavior exists in Warhammer II, Warhammer III, Three Kingdoms, and Troy. It may continue for future games, but any game before Warhammer II needs a different way to load scripts.&lt;br /&gt;
&lt;br /&gt;
For more information, check out [[Lua/Loading Scripts]].&amp;lt;/blockquote&amp;gt;Within script/campaign/mod, now either right click the folder and press &amp;quot;New Text File&amp;quot;, or use the first button on the tab to create a new file. I'm going to name mine &amp;quot;totally_not_cheats.lua&amp;quot;. '''The .lua extension is required, don't skip it!'''&lt;br /&gt;
&lt;br /&gt;
=== Start It ===&lt;br /&gt;
With our newly created file, our VSC layout will change ever so slightly. In &amp;quot;Open Editors&amp;quot;, we'll see our fresh new baby script created; and in the central window, we'll see a new tab that's named the same as our new file, and an empty text file in the center with just the number &amp;quot;1&amp;quot; in it.&lt;br /&gt;
[[File:First script 6.png|none|thumb|894x894px|Notice the lil' moon symbol next to our file? That's because Lua is Portuguese for moon!]]&lt;br /&gt;
We'll kick off our script with the first piece of the puzzle, outputting some text to a file so we can read and interface with our scripts.&lt;br /&gt;
&lt;br /&gt;
Let's get it going with a function called `out()`. This is a CA-defined function that they use all over their scripts, to print out to a text file various bits of info about the game, for debugging and logging purposes. It's a really handy system that'll let you know for certain what's actually going on in your scripts at runtime, since we can't truly test our script outside of the game.&lt;br /&gt;
&lt;br /&gt;
To use the `out` function, we just have to write that word, put an open parenthesis, put in what we want to output, and then write a closing parenthesis. Let's try the old standard, and toss in the following:&amp;lt;blockquote&amp;gt;out( Hello World! )&amp;lt;/blockquote&amp;gt;And we should be goo- oh no! Everything's red! Why are there so many problems?!&lt;br /&gt;
[[File:First script 7.png|thumb|563x563px|If you don't see the above problems or red text, you probably didn't do the setup correctly in the previous lesson. Do it!]]&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
This will be something we'll see maybe a million times as we go forward, and it's important to not get too stressed out about it early on.&lt;br /&gt;
&lt;br /&gt;
Because of our work in [[Lua/Setup]], we now have access to a right proper debugging system that will yell at us when we do something wrong.&lt;br /&gt;
&lt;br /&gt;
There's a lot of confusing bits here, and honestly, none of the problems listed are going to be specific enough to tell us what to do to fix it - at least in this situation. Some of them are telling us that we're arguing too much, one is talking about undefined globals, and one is just absolute pig latin saying it expected &amp;lt;exp&amp;gt;. None of those mean anything to us, but let's check out something that does - some documentation!&lt;br /&gt;
&lt;br /&gt;
If you hover over the word &amp;quot;out&amp;quot;, you'll see a popup that gives us some information about the function `out`. The most important bit is the following:&lt;br /&gt;
[[File:First script 8.png|none|thumb]]&lt;br /&gt;
This is our '''function definition'''. It tells us what the function is called, and what it expects within the parentheses. It's asking for something it calls &amp;quot;output&amp;quot;, and output is a string. '''String''' is the first of several Lua &amp;quot;types&amp;quot; we'll go over in this tutorial series. A '''string''' is text - and it's called such because it's a string of ''characters'' that make up a long piece of text. The issue we've had here is that, while `Hello World!` is text, Lua needs to be told that it's a string type. To do that, we just need to wrap quotation marks - either single or double, doesn't matter, but it can't be backticks or &amp;quot;pretty&amp;quot; quotations like what mobile phones default to. I learned that the hard way.&lt;br /&gt;
&lt;br /&gt;
The easiest way to do that is to highlight the entirety of Hello World! and type in the quotation mark, just one. VSCode will plop a quotation mark on either part of your selection, and all SEVEN of our problems will vanish through air.&lt;br /&gt;
[[File:First script 9.png|thumb|The white dot on our tab means this is an unsaved file; use Ctrl+S to save it!]]&lt;br /&gt;
&lt;br /&gt;
== Getting It In-Game ==&lt;br /&gt;
We have now an incredibly basic script that I'd like to test out.&lt;br /&gt;
&lt;br /&gt;
Now, the `out` function is defined by Creative Assembly within their games, but it comes '''disabled by default''' for retail. That means that while your code runs, it won't actually write anything to a log file. That way they can have their debugging tools, and we can opt into it, but it doesn't automatically happen for every single user.&lt;br /&gt;
&lt;br /&gt;
This disable-by-default can be overridden in different ways, depending on the game. As of the time of writing this guide, my favorite methods are:&lt;br /&gt;
&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2927955021 Mod Configuration Tool]'s  setting for enabling game logging, if available for that game.&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2789857593&amp;amp;searchtext=script+debug+activator Script Debug Activator] mod, if available for that game.&lt;br /&gt;
* Creating a file in your mod at `script/enable_console_logging`, with no extension. You can use VSCode and use add text file at that destination, add any text inside the file and save it.&lt;br /&gt;
&lt;br /&gt;
These may change or evolve as time goes on.&lt;br /&gt;
&lt;br /&gt;
=== Loading ===&lt;br /&gt;
Once you've got your script ready, and your game is set up to have script logs printed out, we'll want to load up our .pack file and get it set in game. For the sake of my soul and time, I'm going to assume we know how packs work, creating them and loading them, and the like.&lt;br /&gt;
&lt;br /&gt;
Step one, we've got to save our stuff in VSCode. Use File -&amp;gt; Save All.&amp;lt;blockquote&amp;gt;Worth a shout here - I altered the shortcut in Visual Studio Code for Save All, since it's maybe my most-used shortcut combination.&lt;br /&gt;
&lt;br /&gt;
If you go to Manage -&amp;gt; Keyboard Shortcuts and type in &amp;quot;save all&amp;quot; in the search bar, you can click on that shortcut and type in on your keyboard what you'd prefer. I use Ctrl+Alt+S, but set it to whatever makes you happy.&amp;lt;/blockquote&amp;gt;Then, in RPFM, use MyMod -&amp;gt; Import. Again, I added a keyboard shortcut here through RPFM - I set Import/Export to Ctrl+Alt+I/E. You can get there through PackFile -&amp;gt; Preferences -&amp;gt; Shortcuts.&lt;br /&gt;
&lt;br /&gt;
Import '''pulls in all the stuff from your MyMod folder into your pack''', while '''export does the opposite'''. I use these all the time, since I externally edit Lua files but internally edit database tables. You'll want to keep in mind where you're working, because if you edit a Lua file externally, and then a table file internally, without adding the changes from one to the other, you may end up overwriting some of your work. Because of that, I will only ever work in one sphere, then use Import/Export to make sure the folder and my .pack line up, and then edit in the other sphere.&lt;br /&gt;
&lt;br /&gt;
Save in RPFM, and use PackFile -&amp;gt; Install to move your .pack to the game folder. Tick it in your mod manager of choice, and load up a fresh campaign!&lt;br /&gt;
&lt;br /&gt;
=== Log File ===&lt;br /&gt;
The game-created log files will spit out in your game's folder - ie., steam/steamapps/common/Total War WARHAMMER III/. They are created as &amp;quot;script_log_DDMMYY_HHMM.txt&amp;quot;. So if I made one right now, it'd be &amp;quot;script_log_100623_1320.txt&amp;quot;, if you were wondering when I wrote this exact line.&lt;br /&gt;
&lt;br /&gt;
The game creates a new log file every time we enter the main menu, every time we enter a campaign, and every time we enter a battle - so if you only just started using script logs, there should be two or three in there depending on if you quit to main menu or to desktop after loading up your new campaign. Navigate to the latest one and open it up.&lt;br /&gt;
&lt;br /&gt;
Worth noting here, I have a file association set up to automatically open .txt files in Visual Studio Code, because I find it easier and quicker to navigate. If you right click the script log -&amp;gt; open with -&amp;gt; target Visual Studio Code, you can get it in that way. You can also simply grab the file from your file explorer and drag it into the main VSCode window, and it will be opened up within.&lt;br /&gt;
&lt;br /&gt;
There's going to be... a ''lot'' of stuff in here. A lot a lot. CA uses double quindrillion calls to `out()` throughout the game. We'll actually find that it's pretty cumbersome to navigate, and later on we'll create our '''own custom log files!''' But for now, let's navigate this chonker.&lt;br /&gt;
&lt;br /&gt;
=== Find Your Text ===&lt;br /&gt;
&amp;lt;small&amp;gt;''Sounds kinda like a platitude you'd find on a pillow in Kohl's.''&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our opened new script log, we should search for the words &amp;quot;Hello World!&amp;quot;. We can either do that using the Search tab we have set up, or clicking into the script log in the main window and using Ctrl+F.&lt;br /&gt;
[[File:First script 10.png|none|thumb|911x911px|Our first trigger of stuff in the game!Hey, did you put a naughty word instead of &amp;quot;Hello World!&amp;quot;? You lil nasty gremlin.]]&lt;br /&gt;
WE FUCKING DID IT HELL YES.&lt;br /&gt;
&lt;br /&gt;
And that's it, you're ready to script on your own!&lt;br /&gt;
&lt;br /&gt;
Bye!&lt;br /&gt;
&lt;br /&gt;
== Timin' 'n Stuff ==&lt;br /&gt;
 You'll probably maybe notice, this text is triggered very, very early on. While it's maybe ~1000 lines of text in, it's only 1.8s seconds (at least, for me, with no other mods enabled) after the script log is created. This is earlier than it might sound. At this time, the game is still going through its loading procedures - this text was triggered before the loading bar even got to 20%!&lt;br /&gt;
Because of how early this is, the game '''is not ready to be accessed yet'''. The game doesn't yet know what factions own what regions, what turn it is, who the player is controlling, or anything like that. The game doesn't have a map object, you can't trigger a new battle, nothin'.&lt;br /&gt;
&lt;br /&gt;
What we need to do for our next step is '''learn how to listen''' and '''wait'''. Some of the most valuable things we can do in programming are listening and waiting for the right time.&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
'''''NOTE:''''' ''Not to be confused with the &amp;quot;Events&amp;quot; in-game, the messages and such that hang out with missions.''&lt;br /&gt;
&lt;br /&gt;
The game has a great deal of &amp;quot;events&amp;quot; that can be triggered. Events are a way for scripts to learn some information about things happening in the game - there are events that will inform us when a new turn has started, when a region has been destroyed, when a battle has ended, when a ritual has been completed, when a mission has been failed, among many many many more. We can even define our own - more on that later!&lt;br /&gt;
&lt;br /&gt;
The first event we care about is one of the most important - FirstTickAfterWorldCreated. This event is triggered immediately after the game is ready to access - about 80% of the way through the loading bar before the game is interactable for the user.&lt;br /&gt;
&lt;br /&gt;
Once this event happens, we can do things like ask the game what factions exist, what turn it is, where we are, who we are, etc. Before the world is created, we can only do a bare minimum of setting things up in advance.&lt;br /&gt;
&lt;br /&gt;
=== Flying the Time ===&lt;br /&gt;
To achieve our first goal - spitting out some information about our player faction - we're going to use a first tick callback and trigger our very own function!&lt;br /&gt;
&lt;br /&gt;
A first tick callback is a way to '''ask the game to run code on FirstTickAfterWorldCreated'''. Most of your mods will probably involve a first-tick-callback. We use them in the following format:&lt;br /&gt;
 cm:add_first_tick_callback(function_to_call)&lt;br /&gt;
But first, we have to create our own function. To do that, we use the following:&lt;br /&gt;
 local function my_function_name()&lt;br /&gt;
 -- do stuff&lt;br /&gt;
 end&lt;br /&gt;
where &amp;quot;my_function_name&amp;quot; can be anything you want. In this situation, I'm going to call the function &amp;quot;init&amp;quot;, short for &amp;quot;initialization&amp;quot;, because this is the startpoint of my entire script. Some people also prefer &amp;quot;main&amp;quot;. Whatever you want really, just make it clear for yourself and anyone else.&lt;br /&gt;
&lt;br /&gt;
''Eagle-eyed readers will notice that the two dashes they wrote in VSCode will be greyed out; these are called &amp;quot;comments&amp;quot;. These are incredibly useful to leave notes to ourselves and other people reading our scripts, to inform yourself and others of what's going on and how things work in our code.''&lt;br /&gt;
&lt;br /&gt;
To safely confirm that we're calling our new function at the right time, we're going to run our function, trigger another call to out(), and see if it works!&lt;br /&gt;
[[File:First script 11.png|thumb|418x418px]]&lt;br /&gt;
&lt;br /&gt;
=== Getting Our Info ===&lt;br /&gt;
With our first tick callback loading up properly, let's hop in and try to get some information about our played faction!&lt;br /&gt;
&lt;br /&gt;
In the beginning of our init() function, we need to define a fresh new &amp;lt;u&amp;gt;variable&amp;lt;/u&amp;gt; which will allow us to hold the faction &amp;quot;object&amp;quot; in memory. A variable is a piece of memory that your computer is going to set aside to hold some data for us - a variable can be a number, text, a function, or game objects like the faction.&lt;br /&gt;
&lt;br /&gt;
We'll get it using the get_local_player() function, which we can find in the scripting documentation: https://chadvandy.github.io/tw_modding_resources/WH3/campaign/campaign_manager.html#function:campaign_manager:get_local_faction&lt;br /&gt;
&lt;br /&gt;
We'll be learning a lot about how to use and read the script documentation going forward.&lt;br /&gt;
&lt;br /&gt;
In our init() function, we need to add the following line of code:&lt;br /&gt;
 local player_faction = cm:get_local_faction()&lt;br /&gt;
Where player_faction is the name of our new variable. It can be anything you want, much like init(), but it should '''make sense''' and '''be clear to read'''. It needs to be all one contiguous word, with only text, underscores, and non-leading numbers allowed (ie. my_faction_1 is allowed, 1_my_faction is not).&lt;br /&gt;
&lt;br /&gt;
Visual Studio Code should automate it for you, but make sure that it's after the init() keyword, is one line after the out() call, is before the `end` keyword, and is one tab over. I like to space my code out thought-by-thought, so this will be a bit lower than my out() code.&lt;br /&gt;
[[File:First script 12.png|none|thumb]]&lt;br /&gt;
The way we get information about this game object will be to ask it questions, using functions, or in this case '''methods'''.&lt;br /&gt;
&lt;br /&gt;
The first thing we want to ask is, hey, what's the faction's name please?&lt;br /&gt;
&lt;br /&gt;
To ask the game object questions, we need to use the variable name followed by the : sign. Our VSCode plugin will then, thankfully, list us with a great deal of suggestions that we can use. We can also reference [https://chadvandy.github.io/tw_modding_resources/WH3/scripting_doc.html#FACTION_SCRIPT_INTERFACE the scripting documentation for game objects].&lt;br /&gt;
&lt;br /&gt;
Thankfully, what we want isn't too far away:&lt;br /&gt;
[[File:First script 13.png|none|thumb|946x946px|The autofill will show us the description of this method, and what it returns - in this case, it returns a &amp;quot;string&amp;quot;, as we see after the -&amp;gt; line.]]&lt;br /&gt;
Whenever we call a function, if the function gives us something back, we have to assign it to a variable or it will go away and vanish into the ether, with no memory on your PC being used to &amp;quot;hold&amp;quot; onto it. Do that with something simple:&lt;br /&gt;
 local name = player_faction:name()&lt;br /&gt;
I'll keep harping on it, but you can change `local name` to whatever you want - `local key`, `local bits`, `local ostrich_on_fire`, whatever.&lt;br /&gt;
&lt;br /&gt;
'''''NOTE:''''' ''It keeps saying name, but its actually referring to the faction's &amp;quot;key&amp;quot; as we'll see in a second - the &amp;quot;code name&amp;quot; is has in factions_tables.''&lt;br /&gt;
&lt;br /&gt;
Now that we have the information in our code, we can put it all together and print that out to the log file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;out(&amp;quot;Hello World!&amp;quot;)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 out( &amp;quot;Hello World!&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 local function init()&lt;br /&gt;
&lt;br /&gt;
     out(&amp;quot;New game triggered!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
     local player_faction = cm:get_local_faction()&lt;br /&gt;
&lt;br /&gt;
     local key = player_faction:name()&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
     out(&amp;quot;Playing as &amp;quot; .. key)&lt;br /&gt;
&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
 cm:add_first_tick_callback(init)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_13.png&amp;diff=690</id>
		<title>File:First script 13.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_13.png&amp;diff=690"/>
		<updated>2023-06-10T18:29:21Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;faction name&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_12.png&amp;diff=689</id>
		<title>File:First script 12.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_12.png&amp;diff=689"/>
		<updated>2023-06-10T18:26:19Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;getting player faction&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=688</id>
		<title>Lua/First Script</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=688"/>
		<updated>2023-06-10T18:16:51Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this first step tutorial, we're going to learn:&lt;br /&gt;
&lt;br /&gt;
* How to load &amp;amp; run a custom Lua script&lt;br /&gt;
* How timing works, at a large level, with scripts&lt;br /&gt;
* How to print out game information to interrogate the state of the game&lt;br /&gt;
* How simple variables work&lt;br /&gt;
&lt;br /&gt;
Let's create our first script together!&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
First thing's first, let's crack open RPFM to create our new Mod. In RPFM, I'm going to use MyMod -&amp;gt; New MyMod, to create a new easy-to-use mod system. If you haven't already, follow the setup guides in [[RPFM]] for setting up preferences and paths.&lt;br /&gt;
&lt;br /&gt;
[[File:First Script 01.png|frameless|712x712px]]&lt;br /&gt;
&lt;br /&gt;
RPFM will then open up our new MyMod. Within it, use MyMod -&amp;gt; Export, which will unload the contents of the newly created (almost entirely empty) MyMod into your specified MyMods folder. I have this folder pinned to my quick access, but you can also get there with MyMod -&amp;gt; Open MyMod Folder, and navigating down to the newly created MyMod.&lt;br /&gt;
&lt;br /&gt;
Now we can right click this folder and use the newly added &amp;quot;Open with Code&amp;quot; button, which will take the targeted mod folder and open it within Visual Studio Code!&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Navigation ==&lt;br /&gt;
When we open up in Visual Studio Code, we'll see something that looks a little bit like this - it might differ slightly, that's totally okay!&lt;br /&gt;
[[File:First script 2.png|none|thumb|1061x1061px|It might seem like quite a lot at first, but we'll get used to it! Just make sure to set the settings to dark mode if you're not insane.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before we get too far, let's break down some of the parts of what we're looking at here, and set up our windows so we have everything we need.&lt;br /&gt;
&lt;br /&gt;
=== Primary Bar ===&lt;br /&gt;
On the very left, we have what VSCode calls the &amp;quot;Primary Bar&amp;quot;. It has a few things here - the top has the two files stacked on each other, a search button below that, three buttons we don't have to worry too much about yet, and a Bookmark button. The bottom has our Account and Manage button. '''If you haven't already''', click into the Manage button and set our Profile to the correct one. I have mine saved as &amp;quot;TW Lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The part of the primary bar we care most about is the top button, the &amp;quot;Explorer&amp;quot;. Think of this as your file navigation - it's effectively the same as navigating the Windows File Explorer, but it has some extra goodies that will be nice for us.&lt;br /&gt;
[[File:First script 3.png|left|thumb|578x578px]]&lt;br /&gt;
At the top of the Explorer, we have &amp;quot;Open Editors&amp;quot;. This will show us all of our actively opened files - we'll see this shortly!&lt;br /&gt;
&lt;br /&gt;
Below that, we have a tab for the currently opened folder. My folder is named babys_first_script, so that's what shows as the name here. Inside are all of the folders AND files that exist within my folder on my PC. We can open, create, rename, and delete any file within to our heart's content, and edit as long as Visual Studio Code can edit it. VSCode can edit essentially any text file, which is what all code files are, effectively. Based on the type of text file, VSCode will handle it differently - it knows the difference between a .lua and a .json file, and will react accordingly to the specifications of either language.&lt;br /&gt;
&lt;br /&gt;
Below that, we had &amp;quot;TODOs: Tree&amp;quot;, which is an extension preloaded with our Profile. This is one of my favorite tabs, because I can leave notes for myself to do stuff later and they will be displayed in this window.&lt;br /&gt;
&lt;br /&gt;
Below that are Outline and Timeline, which I rarely use but can sometimes be nice. Outline will show us the layout of our code, and Timeline will show us previous local history for saving/editing these files, and more details if we're using GitHub or another version control software.&lt;br /&gt;
&lt;br /&gt;
The Search button is also incredibly useful, for reasons that may be obvious.&lt;br /&gt;
&lt;br /&gt;
=== Menu Bar ===&lt;br /&gt;
On the very top, we have our conveniently named Top Bar, or Menu Bar. You've seen these a billion times before. There's a LOT of stuff up here, but in my five years of using this program for TW Lua I've only really cared about a couple buttons within.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File&amp;quot; is going to be our best friend, for opening new windows, saving, and creating new files. Edit/Selection/View have a load of commands in them, and they may be good to reference often early on to see shortcuts for saving and other helpful code shortcuts, like duplicating text or renaming stuff.&lt;br /&gt;
&lt;br /&gt;
For now, what we should do is click View -&amp;gt; Problems, which will open up a new bottom bar for us. We only care about the &amp;quot;Problems&amp;quot; tab that shows up.&lt;br /&gt;
&lt;br /&gt;
=== Customizabilitization ===&lt;br /&gt;
Let's introduce the idea here that VSCode is '''super duper''' flexible with its layout. Anything on your screen right now can be put somewhere else, including individual tabs, buttons, anything. We can move Problems as a button to the Primary Bar, the Explorer as a tab on the bottom, and TODOs on the right all alone.&lt;br /&gt;
[[File:First script 4.png|thumb|824x824px]]&lt;br /&gt;
It's a bit clunky and not exactly what I need, but it's as good time as any to show you how flexible it can get.&lt;br /&gt;
&lt;br /&gt;
For now, I'm going to plop Search and TODOs on my new right sidebar stacked on one another, I'm going to right click one of the tabs at the bottom and deselect &amp;quot;Terminal&amp;quot;, &amp;quot;Output&amp;quot;, and &amp;quot;Debug Console&amp;quot;, and keep my left Primary Bar as is otherwise and open back up the Explorer.&lt;br /&gt;
&lt;br /&gt;
== Script Creation ==&lt;br /&gt;
Okay, enough preamble. Let's get it started.&lt;br /&gt;
&lt;br /&gt;
=== The Plan ===&lt;br /&gt;
Our standard first step for creating a new script is the first step we should do whenever making a new mod or system: having a plan, something we want. For this one, our goal is going to be simple. I want the following:&lt;br /&gt;
&lt;br /&gt;
* When the game starts, I want to output a message to a text file that tells me the game started, and tells me where my starting faction leader and capital region are.&lt;br /&gt;
* On every turn after that, I want to give my faction some extra gold.&lt;br /&gt;
* If I'm playing as Karl Franz, I want to give my faction another two armies.&lt;br /&gt;
* I swear it's balanced.&lt;br /&gt;
&lt;br /&gt;
=== Make It ===&lt;br /&gt;
[[File:First script 5.png|left|thumb|Second button from the left!]]&lt;br /&gt;
In VSC, go to the Explorer, and hover over the currently-opened-folder tab. You can either right click within the white space and press &amp;quot;New Folder&amp;quot;, or press the New Folder button on the tab for the currently opened folder.&lt;br /&gt;
&lt;br /&gt;
Name the empty folder that's created `script`. All scripts we write will be in this main folder. With this folder selected, create a new folder again, and call this one &amp;quot;campaign&amp;quot;. Do it again, calling the third &amp;quot;mod&amp;quot;, making our full path script/campaign/mod.&amp;lt;blockquote&amp;gt;'''NOTE:''' This folder path is one of several that is specified by Creative Assembly in more recent games, for modders to add scripts to which get automatically loaded. This behavior exists in Warhammer II, Warhammer III, Three Kingdoms, and Troy. It may continue for future games, but any game before Warhammer II needs a different way to load scripts.&lt;br /&gt;
&lt;br /&gt;
For more information, check out [[Lua/Loading Scripts]].&amp;lt;/blockquote&amp;gt;Within script/campaign/mod, now either right click the folder and press &amp;quot;New Text File&amp;quot;, or use the first button on the tab to create a new file. I'm going to name mine &amp;quot;totally_not_cheats.lua&amp;quot;. '''The .lua extension is required, don't skip it!'''&lt;br /&gt;
&lt;br /&gt;
=== Start It ===&lt;br /&gt;
With our newly created file, our VSC layout will change ever so slightly. In &amp;quot;Open Editors&amp;quot;, we'll see our fresh new baby script created; and in the central window, we'll see a new tab that's named the same as our new file, and an empty text file in the center with just the number &amp;quot;1&amp;quot; in it.&lt;br /&gt;
[[File:First script 6.png|none|thumb|894x894px|Notice the lil' moon symbol next to our file? That's because Lua is Portuguese for moon!]]&lt;br /&gt;
We'll kick off our script with the first piece of the puzzle, outputting some text to a file so we can read and interface with our scripts.&lt;br /&gt;
&lt;br /&gt;
Let's get it going with a function called `out()`. This is a CA-defined function that they use all over their scripts, to print out to a text file various bits of info about the game, for debugging and logging purposes. It's a really handy system that'll let you know for certain what's actually going on in your scripts at runtime, since we can't truly test our script outside of the game.&lt;br /&gt;
&lt;br /&gt;
To use the `out` function, we just have to write that word, put an open parenthesis, put in what we want to output, and then write a closing parenthesis. Let's try the old standard, and toss in the following:&amp;lt;blockquote&amp;gt;out( Hello World! )&amp;lt;/blockquote&amp;gt;And we should be goo- oh no! Everything's red! Why are there so many problems?!&lt;br /&gt;
[[File:First script 7.png|thumb|563x563px|If you don't see the above problems or red text, you probably didn't do the setup correctly in the previous lesson. Do it!]]&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
This will be something we'll see maybe a million times as we go forward, and it's important to not get too stressed out about it early on.&lt;br /&gt;
&lt;br /&gt;
Because of our work in [[Lua/Setup]], we now have access to a right proper debugging system that will yell at us when we do something wrong.&lt;br /&gt;
&lt;br /&gt;
There's a lot of confusing bits here, and honestly, none of the problems listed are going to be specific enough to tell us what to do to fix it - at least in this situation. Some of them are telling us that we're arguing too much, one is talking about undefined globals, and one is just absolute pig latin saying it expected &amp;lt;exp&amp;gt;. None of those mean anything to us, but let's check out something that does - some documentation!&lt;br /&gt;
&lt;br /&gt;
If you hover over the word &amp;quot;out&amp;quot;, you'll see a popup that gives us some information about the function `out`. The most important bit is the following:&lt;br /&gt;
[[File:First script 8.png|none|thumb]]&lt;br /&gt;
This is our '''function definition'''. It tells us what the function is called, and what it expects within the parentheses. It's asking for something it calls &amp;quot;output&amp;quot;, and output is a string. '''String''' is the first of several Lua &amp;quot;types&amp;quot; we'll go over in this tutorial series. A '''string''' is text - and it's called such because it's a string of ''characters'' that make up a long piece of text. The issue we've had here is that, while `Hello World!` is text, Lua needs to be told that it's a string type. To do that, we just need to wrap quotation marks - either single or double, doesn't matter, but it can't be backticks or &amp;quot;pretty&amp;quot; quotations like what mobile phones default to. I learned that the hard way.&lt;br /&gt;
&lt;br /&gt;
The easiest way to do that is to highlight the entirety of Hello World! and type in the quotation mark, just one. VSCode will plop a quotation mark on either part of your selection, and all SEVEN of our problems will vanish through air.&lt;br /&gt;
[[File:First script 9.png|thumb|The white dot on our tab means this is an unsaved file; use Ctrl+S to save it!]]&lt;br /&gt;
&lt;br /&gt;
== Getting It In-Game ==&lt;br /&gt;
We have now an incredibly basic script that I'd like to test out.&lt;br /&gt;
&lt;br /&gt;
Now, the `out` function is defined by Creative Assembly within their games, but it comes '''disabled by default''' for retail. That means that while your code runs, it won't actually write anything to a log file. That way they can have their debugging tools, and we can opt into it, but it doesn't automatically happen for every single user.&lt;br /&gt;
&lt;br /&gt;
This disable-by-default can be overridden in different ways, depending on the game. As of the time of writing this guide, my favorite methods are:&lt;br /&gt;
&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2927955021 Mod Configuration Tool]'s  setting for enabling game logging, if available for that game.&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2789857593&amp;amp;searchtext=script+debug+activator Script Debug Activator] mod, if available for that game.&lt;br /&gt;
* Creating a file in your mod at `script/enable_console_logging`, with no extension. You can use VSCode and use add text file at that destination, add any text inside the file and save it.&lt;br /&gt;
&lt;br /&gt;
These may change or evolve as time goes on.&lt;br /&gt;
&lt;br /&gt;
=== Loading ===&lt;br /&gt;
Once you've got your script ready, and your game is set up to have script logs printed out, we'll want to load up our .pack file and get it set in game. For the sake of my soul and time, I'm going to assume we know how packs work, creating them and loading them, and the like.&lt;br /&gt;
&lt;br /&gt;
Step one, we've got to save our stuff in VSCode. Use File -&amp;gt; Save All.&amp;lt;blockquote&amp;gt;Worth a shout here - I altered the shortcut in Visual Studio Code for Save All, since it's maybe my most-used shortcut combination.&lt;br /&gt;
&lt;br /&gt;
If you go to Manage -&amp;gt; Keyboard Shortcuts and type in &amp;quot;save all&amp;quot; in the search bar, you can click on that shortcut and type in on your keyboard what you'd prefer. I use Ctrl+Alt+S, but set it to whatever makes you happy.&amp;lt;/blockquote&amp;gt;Then, in RPFM, use MyMod -&amp;gt; Import. Again, I added a keyboard shortcut here through RPFM - I set Import/Export to Ctrl+Alt+I/E. You can get there through PackFile -&amp;gt; Preferences -&amp;gt; Shortcuts.&lt;br /&gt;
&lt;br /&gt;
Import '''pulls in all the stuff from your MyMod folder into your pack''', while '''export does the opposite'''. I use these all the time, since I externally edit Lua files but internally edit database tables. You'll want to keep in mind where you're working, because if you edit a Lua file externally, and then a table file internally, without adding the changes from one to the other, you may end up overwriting some of your work. Because of that, I will only ever work in one sphere, then use Import/Export to make sure the folder and my .pack line up, and then edit in the other sphere.&lt;br /&gt;
&lt;br /&gt;
Save in RPFM, and use PackFile -&amp;gt; Install to move your .pack to the game folder. Tick it in your mod manager of choice, and load up a fresh campaign!&lt;br /&gt;
&lt;br /&gt;
=== Log File ===&lt;br /&gt;
The game-created log files will spit out in your game's folder - ie., steam/steamapps/common/Total War WARHAMMER III/. They are created as &amp;quot;script_log_DDMMYY_HHMM.txt&amp;quot;. So if I made one right now, it'd be &amp;quot;script_log_100623_1320.txt&amp;quot;, if you were wondering when I wrote this exact line.&lt;br /&gt;
&lt;br /&gt;
The game creates a new log file every time we enter the main menu, every time we enter a campaign, and every time we enter a battle - so if you only just started using script logs, there should be two or three in there depending on if you quit to main menu or to desktop after loading up your new campaign. Navigate to the latest one and open it up.&lt;br /&gt;
&lt;br /&gt;
Worth noting here, I have a file association set up to automatically open .txt files in Visual Studio Code, because I find it easier and quicker to navigate. If you right click the script log -&amp;gt; open with -&amp;gt; target Visual Studio Code, you can get it in that way. You can also simply grab the file from your file explorer and drag it into the main VSCode window, and it will be opened up within.&lt;br /&gt;
&lt;br /&gt;
There's going to be... a ''lot'' of stuff in here. A lot a lot. CA uses double quindrillion calls to `out()` throughout the game. We'll actually find that it's pretty cumbersome to navigate, and later on we'll create our '''own custom log files!''' But for now, let's navigate this chonker.&lt;br /&gt;
&lt;br /&gt;
=== Find Your Text ===&lt;br /&gt;
&amp;lt;small&amp;gt;''Sounds kinda like a platitude you'd find on a pillow in Kohl's.''&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our opened new script log, we should search for the words &amp;quot;Hello World!&amp;quot;. We can either do that using the Search tab we have set up, or clicking into the script log in the main window and using Ctrl+F.&lt;br /&gt;
[[File:First script 10.png|none|thumb|911x911px|Our first trigger of stuff in the game!Hey, did you put a naughty word instead of &amp;quot;Hello World!&amp;quot;? You lil nasty gremlin.]]&lt;br /&gt;
WE FUCKING DID IT HELL YES.&lt;br /&gt;
&lt;br /&gt;
And that's it, you're ready to script on your own!&lt;br /&gt;
&lt;br /&gt;
Bye!&lt;br /&gt;
&lt;br /&gt;
== Timin' 'n Stuff ==&lt;br /&gt;
 You'll probably maybe notice, this text is triggered very, very early on. While it's maybe ~1000 lines of text in, it's only 1.8s seconds (at least, for me, with no other mods enabled) after the script log is created. This is earlier than it might sound. At this time, the game is still going through its loading procedures - this text was triggered before the loading bar even got to 20%!&lt;br /&gt;
Because of how early this is, the game '''is not ready to be accessed yet'''. The game doesn't yet know what factions own what regions, what turn it is, who the player is controlling, or anything like that. The game doesn't have a map object, you can't trigger a new battle, nothin'.&lt;br /&gt;
&lt;br /&gt;
What we need to do for our next step is '''learn how to listen''' and '''wait'''. Some of the most valuable things we can do in programming are listening and waiting for the right time.&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
'''''NOTE:''''' ''Not to be confused with the &amp;quot;Events&amp;quot; in-game, the messages and such that hang out with missions.''&lt;br /&gt;
&lt;br /&gt;
The game has a great deal of &amp;quot;events&amp;quot; that can be triggered. Events are a way for scripts to learn some information about things happening in the game - there are events that will inform us when a new turn has started, when a region has been destroyed, when a battle has ended, when a ritual has been completed, when a mission has been failed, among many many many more. We can even define our own - more on that later!&lt;br /&gt;
&lt;br /&gt;
The first event we care about is one of the most important - FirstTickAfterWorldCreated. This event is triggered immediately after the game is ready to access - about 80% of the way through the loading bar before the game is interactable for the user.&lt;br /&gt;
&lt;br /&gt;
Once this event happens, we can do things like ask the game what factions exist, what turn it is, where we are, who we are, etc. Before the world is created, we can only do a bare minimum of setting things up in advance.&lt;br /&gt;
&lt;br /&gt;
=== Flying the Time ===&lt;br /&gt;
To achieve our first goal - spitting out some information about our player faction - we're going to use a first tick callback and trigger our very own function!&lt;br /&gt;
&lt;br /&gt;
A first tick callback is a way to '''ask the game to run code on FirstTickAfterWorldCreated'''. Most of your mods will probably involve a first-tick-callback. We use them in the following format:&lt;br /&gt;
 cm:add_first_tick_callback(function_to_call)&lt;br /&gt;
But first, we have to create our own function. To do that, we use the following:&lt;br /&gt;
 local function my_function_name()&lt;br /&gt;
 -- do stuff&lt;br /&gt;
 end&lt;br /&gt;
where &amp;quot;my_function_name&amp;quot; can be anything you want. In this situation, I'm going to call the function &amp;quot;init&amp;quot;, short for &amp;quot;initialization&amp;quot;, because this is the startpoint of my entire script. Some people also prefer &amp;quot;main&amp;quot;. Whatever you want really, just make it clear for yourself and anyone else.&lt;br /&gt;
&lt;br /&gt;
''Eagle-eyed readers will notice that the two dashes they wrote in VSCode will be greyed out; these are called &amp;quot;comments&amp;quot;. These are incredibly useful to leave notes to ourselves and other people reading our scripts, to inform yourself and others of what's going on and how things work in our code.''&lt;br /&gt;
&lt;br /&gt;
To safely confirm that we're calling our new function at the right time, we're going to run our function, trigger another call to out(), and see if it works!&lt;br /&gt;
[[File:First script 11.png|thumb|418x418px]]&lt;br /&gt;
&lt;br /&gt;
=== Getting Our Info ===&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_11.png&amp;diff=687</id>
		<title>File:First script 11.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_11.png&amp;diff=687"/>
		<updated>2023-06-10T17:58:23Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;First first tick callback&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=686</id>
		<title>Lua/First Script</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=686"/>
		<updated>2023-06-10T17:38:10Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this first step tutorial, we're going to learn:&lt;br /&gt;
&lt;br /&gt;
* How to load &amp;amp; run a custom Lua script&lt;br /&gt;
* How timing works, at a large level, with scripts&lt;br /&gt;
* How to print out game information to interrogate the state of the game&lt;br /&gt;
* How simple variables work&lt;br /&gt;
&lt;br /&gt;
Let's create our first script together!&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
First thing's first, let's crack open RPFM to create our new Mod. In RPFM, I'm going to use MyMod -&amp;gt; New MyMod, to create a new easy-to-use mod system. If you haven't already, follow the setup guides in [[RPFM]] for setting up preferences and paths.&lt;br /&gt;
&lt;br /&gt;
[[File:First Script 01.png|frameless|712x712px]]&lt;br /&gt;
&lt;br /&gt;
RPFM will then open up our new MyMod. Within it, use MyMod -&amp;gt; Export, which will unload the contents of the newly created (almost entirely empty) MyMod into your specified MyMods folder. I have this folder pinned to my quick access, but you can also get there with MyMod -&amp;gt; Open MyMod Folder, and navigating down to the newly created MyMod.&lt;br /&gt;
&lt;br /&gt;
Now we can right click this folder and use the newly added &amp;quot;Open with Code&amp;quot; button, which will take the targeted mod folder and open it within Visual Studio Code!&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Navigation ==&lt;br /&gt;
When we open up in Visual Studio Code, we'll see something that looks a little bit like this - it might differ slightly, that's totally okay!&lt;br /&gt;
[[File:First script 2.png|none|thumb|1061x1061px|It might seem like quite a lot at first, but we'll get used to it! Just make sure to set the settings to dark mode if you're not insane.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before we get too far, let's break down some of the parts of what we're looking at here, and set up our windows so we have everything we need.&lt;br /&gt;
&lt;br /&gt;
=== Primary Bar ===&lt;br /&gt;
On the very left, we have what VSCode calls the &amp;quot;Primary Bar&amp;quot;. It has a few things here - the top has the two files stacked on each other, a search button below that, three buttons we don't have to worry too much about yet, and a Bookmark button. The bottom has our Account and Manage button. '''If you haven't already''', click into the Manage button and set our Profile to the correct one. I have mine saved as &amp;quot;TW Lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The part of the primary bar we care most about is the top button, the &amp;quot;Explorer&amp;quot;. Think of this as your file navigation - it's effectively the same as navigating the Windows File Explorer, but it has some extra goodies that will be nice for us.&lt;br /&gt;
[[File:First script 3.png|left|thumb|578x578px]]&lt;br /&gt;
At the top of the Explorer, we have &amp;quot;Open Editors&amp;quot;. This will show us all of our actively opened files - we'll see this shortly!&lt;br /&gt;
&lt;br /&gt;
Below that, we have a tab for the currently opened folder. My folder is named babys_first_script, so that's what shows as the name here. Inside are all of the folders AND files that exist within my folder on my PC. We can open, create, rename, and delete any file within to our heart's content, and edit as long as Visual Studio Code can edit it. VSCode can edit essentially any text file, which is what all code files are, effectively. Based on the type of text file, VSCode will handle it differently - it knows the difference between a .lua and a .json file, and will react accordingly to the specifications of either language.&lt;br /&gt;
&lt;br /&gt;
Below that, we had &amp;quot;TODOs: Tree&amp;quot;, which is an extension preloaded with our Profile. This is one of my favorite tabs, because I can leave notes for myself to do stuff later and they will be displayed in this window.&lt;br /&gt;
&lt;br /&gt;
Below that are Outline and Timeline, which I rarely use but can sometimes be nice. Outline will show us the layout of our code, and Timeline will show us previous local history for saving/editing these files, and more details if we're using GitHub or another version control software.&lt;br /&gt;
&lt;br /&gt;
The Search button is also incredibly useful, for reasons that may be obvious.&lt;br /&gt;
&lt;br /&gt;
=== Menu Bar ===&lt;br /&gt;
On the very top, we have our conveniently named Top Bar, or Menu Bar. You've seen these a billion times before. There's a LOT of stuff up here, but in my five years of using this program for TW Lua I've only really cared about a couple buttons within.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File&amp;quot; is going to be our best friend, for opening new windows, saving, and creating new files. Edit/Selection/View have a load of commands in them, and they may be good to reference often early on to see shortcuts for saving and other helpful code shortcuts, like duplicating text or renaming stuff.&lt;br /&gt;
&lt;br /&gt;
For now, what we should do is click View -&amp;gt; Problems, which will open up a new bottom bar for us. We only care about the &amp;quot;Problems&amp;quot; tab that shows up.&lt;br /&gt;
&lt;br /&gt;
=== Customizabilitization ===&lt;br /&gt;
Let's introduce the idea here that VSCode is '''super duper''' flexible with its layout. Anything on your screen right now can be put somewhere else, including individual tabs, buttons, anything. We can move Problems as a button to the Primary Bar, the Explorer as a tab on the bottom, and TODOs on the right all alone.&lt;br /&gt;
[[File:First script 4.png|thumb|824x824px]]&lt;br /&gt;
It's a bit clunky and not exactly what I need, but it's as good time as any to show you how flexible it can get.&lt;br /&gt;
&lt;br /&gt;
For now, I'm going to plop Search and TODOs on my new right sidebar stacked on one another, I'm going to right click one of the tabs at the bottom and deselect &amp;quot;Terminal&amp;quot;, &amp;quot;Output&amp;quot;, and &amp;quot;Debug Console&amp;quot;, and keep my left Primary Bar as is otherwise and open back up the Explorer.&lt;br /&gt;
&lt;br /&gt;
== Script Creation ==&lt;br /&gt;
Okay, enough preamble. Let's get it started.&lt;br /&gt;
&lt;br /&gt;
=== The Plan ===&lt;br /&gt;
Our standard first step for creating a new script is the first step we should do whenever making a new mod or system: having a plan, something we want. For this one, our goal is going to be simple. I want the following:&lt;br /&gt;
&lt;br /&gt;
* When the game starts, I want to output a message to a text file that tells me the game started, and tells me where my starting faction leader and capital region are.&lt;br /&gt;
* On every turn after that, I want to give my faction some extra gold.&lt;br /&gt;
* If I'm playing as Karl Franz, I want to give my faction another two armies.&lt;br /&gt;
* I swear it's balanced.&lt;br /&gt;
&lt;br /&gt;
=== Make It ===&lt;br /&gt;
[[File:First script 5.png|left|thumb|Second button from the left!]]&lt;br /&gt;
In VSC, go to the Explorer, and hover over the currently-opened-folder tab. You can either right click within the white space and press &amp;quot;New Folder&amp;quot;, or press the New Folder button on the tab for the currently opened folder.&lt;br /&gt;
&lt;br /&gt;
Name the empty folder that's created `script`. All scripts we write will be in this main folder. With this folder selected, create a new folder again, and call this one &amp;quot;campaign&amp;quot;. Do it again, calling the third &amp;quot;mod&amp;quot;, making our full path script/campaign/mod.&amp;lt;blockquote&amp;gt;'''NOTE:''' This folder path is one of several that is specified by Creative Assembly in more recent games, for modders to add scripts to which get automatically loaded. This behavior exists in Warhammer II, Warhammer III, Three Kingdoms, and Troy. It may continue for future games, but any game before Warhammer II needs a different way to load scripts.&lt;br /&gt;
&lt;br /&gt;
For more information, check out [[Lua/Loading Scripts]].&amp;lt;/blockquote&amp;gt;Within script/campaign/mod, now either right click the folder and press &amp;quot;New Text File&amp;quot;, or use the first button on the tab to create a new file. I'm going to name mine &amp;quot;totally_not_cheats.lua&amp;quot;. '''The .lua extension is required, don't skip it!'''&lt;br /&gt;
&lt;br /&gt;
=== Start It ===&lt;br /&gt;
With our newly created file, our VSC layout will change ever so slightly. In &amp;quot;Open Editors&amp;quot;, we'll see our fresh new baby script created; and in the central window, we'll see a new tab that's named the same as our new file, and an empty text file in the center with just the number &amp;quot;1&amp;quot; in it.&lt;br /&gt;
[[File:First script 6.png|none|thumb|894x894px|Notice the lil' moon symbol next to our file? That's because Lua is Portuguese for moon!]]&lt;br /&gt;
We'll kick off our script with the first piece of the puzzle, outputting some text to a file so we can read and interface with our scripts.&lt;br /&gt;
&lt;br /&gt;
Let's get it going with a function called `out()`. This is a CA-defined function that they use all over their scripts, to print out to a text file various bits of info about the game, for debugging and logging purposes. It's a really handy system that'll let you know for certain what's actually going on in your scripts at runtime, since we can't truly test our script outside of the game.&lt;br /&gt;
&lt;br /&gt;
To use the `out` function, we just have to write that word, put an open parenthesis, put in what we want to output, and then write a closing parenthesis. Let's try the old standard, and toss in the following:&amp;lt;blockquote&amp;gt;out( Hello World! )&amp;lt;/blockquote&amp;gt;And we should be goo- oh no! Everything's red! Why are there so many problems?!&lt;br /&gt;
[[File:First script 7.png|thumb|563x563px|If you don't see the above problems or red text, you probably didn't do the setup correctly in the previous lesson. Do it!]]&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
This will be something we'll see maybe a million times as we go forward, and it's important to not get too stressed out about it early on.&lt;br /&gt;
&lt;br /&gt;
Because of our work in [[Lua/Setup]], we now have access to a right proper debugging system that will yell at us when we do something wrong.&lt;br /&gt;
&lt;br /&gt;
There's a lot of confusing bits here, and honestly, none of the problems listed are going to be specific enough to tell us what to do to fix it - at least in this situation. Some of them are telling us that we're arguing too much, one is talking about undefined globals, and one is just absolute pig latin saying it expected &amp;lt;exp&amp;gt;. None of those mean anything to us, but let's check out something that does - some documentation!&lt;br /&gt;
&lt;br /&gt;
If you hover over the word &amp;quot;out&amp;quot;, you'll see a popup that gives us some information about the function `out`. The most important bit is the following:&lt;br /&gt;
[[File:First script 8.png|none|thumb]]&lt;br /&gt;
This is our '''function definition'''. It tells us what the function is called, and what it expects within the parentheses. It's asking for something it calls &amp;quot;output&amp;quot;, and output is a string. '''String''' is the first of several Lua &amp;quot;types&amp;quot; we'll go over in this tutorial series. A '''string''' is text - and it's called such because it's a string of ''characters'' that make up a long piece of text. The issue we've had here is that, while `Hello World!` is text, Lua needs to be told that it's a string type. To do that, we just need to wrap quotation marks - either single or double, doesn't matter, but it can't be backticks or &amp;quot;pretty&amp;quot; quotations like what mobile phones default to. I learned that the hard way.&lt;br /&gt;
&lt;br /&gt;
The easiest way to do that is to highlight the entirety of Hello World! and type in the quotation mark, just one. VSCode will plop a quotation mark on either part of your selection, and all SEVEN of our problems will vanish through air.&lt;br /&gt;
[[File:First script 9.png|thumb|The white dot on our tab means this is an unsaved file; use Ctrl+S to save it!]]&lt;br /&gt;
&lt;br /&gt;
== Getting It In-Game ==&lt;br /&gt;
We have now an incredibly basic script that I'd like to test out.&lt;br /&gt;
&lt;br /&gt;
Now, the `out` function is defined by Creative Assembly within their games, but it comes '''disabled by default''' for retail. That means that while your code runs, it won't actually write anything to a log file. That way they can have their debugging tools, and we can opt into it, but it doesn't automatically happen for every single user.&lt;br /&gt;
&lt;br /&gt;
This disable-by-default can be overridden in different ways, depending on the game. As of the time of writing this guide, my favorite methods are:&lt;br /&gt;
&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2927955021 Mod Configuration Tool]'s  setting for enabling game logging, if available for that game.&lt;br /&gt;
* Using the [https://steamcommunity.com/sharedfiles/filedetails/?id=2789857593&amp;amp;searchtext=script+debug+activator Script Debug Activator] mod, if available for that game.&lt;br /&gt;
* Creating a file in your mod at `script/enable_console_logging`, with no extension. You can use VSCode and use add text file at that destination, add any text inside the file and save it.&lt;br /&gt;
&lt;br /&gt;
These may change or evolve as time goes on.&lt;br /&gt;
&lt;br /&gt;
=== Loading ===&lt;br /&gt;
Once you've got your script ready, and your game is set up to have script logs printed out, we'll want to load up our .pack file and get it set in game. For the sake of my soul and time, I'm going to assume we know how packs work, creating them and loading them, and the like.&lt;br /&gt;
&lt;br /&gt;
Step one, we've got to save our stuff in VSCode. Use File -&amp;gt; Save All.&amp;lt;blockquote&amp;gt;Worth a shout here - I altered the shortcut in Visual Studio Code for Save All, since it's maybe my most-used shortcut combination.&lt;br /&gt;
&lt;br /&gt;
If you go to Manage -&amp;gt; Keyboard Shortcuts and type in &amp;quot;save all&amp;quot; in the search bar, you can click on that shortcut and type in on your keyboard what you'd prefer. I use Ctrl+Alt+S, but set it to whatever makes you happy.&amp;lt;/blockquote&amp;gt;Then, in RPFM, use MyMod -&amp;gt; Import. Again, I added a keyboard shortcut here through RPFM - I set Import/Export to Ctrl+Alt+I/E. You can get there through PackFile -&amp;gt; Preferences -&amp;gt; Shortcuts.&lt;br /&gt;
&lt;br /&gt;
Import '''pulls in all the stuff from your MyMod folder into your pack''', while '''export does the opposite'''. I use these all the time, since I externally edit Lua files but internally edit database tables. You'll want to keep in mind where you're working, because if you edit a Lua file externally, and then a table file internally, without adding the changes from one to the other, you may end up overwriting some of your work. Because of that, I will only ever work in one sphere, then use Import/Export to make sure the folder and my .pack line up, and then edit in the other sphere.&lt;br /&gt;
&lt;br /&gt;
Save in RPFM, and use PackFile -&amp;gt; Install to move your .pack to the game folder. Tick it in your mod manager of choice, and load up a fresh campaign!&lt;br /&gt;
&lt;br /&gt;
=== Log File ===&lt;br /&gt;
The game-created log files will spit out in your game's folder - ie., steam/steamapps/common/Total War WARHAMMER III/. They are created as &amp;quot;script_log_DDMMYY_HHMM.txt&amp;quot;. So if I made one right now, it'd be &amp;quot;script_log_100623_1320.txt&amp;quot;, if you were wondering when I wrote this exact line.&lt;br /&gt;
&lt;br /&gt;
The game creates a new log file every time we enter the main menu, every time we enter a campaign, and every time we enter a battle - so if you only just started using script logs, there should be two or three in there depending on if you quit to main menu or to desktop after loading up your new campaign. Navigate to the latest one and open it up.&lt;br /&gt;
&lt;br /&gt;
Worth noting here, I have a file association set up to automatically open .txt files in Visual Studio Code, because I find it easier and quicker to navigate. If you right click the script log -&amp;gt; open with -&amp;gt; target Visual Studio Code, you can get it in that way. You can also simply grab the file from your file explorer and drag it into the main VSCode window, and it will be opened up within.&lt;br /&gt;
&lt;br /&gt;
There's going to be... a ''lot'' of stuff in here. A lot a lot. CA uses double quindrillion calls to `out()` throughout the game. We'll actually find that it's pretty cumbersome to navigate, and later on we'll create our '''own custom log files!''' But for now, let's navigate this chonker.&lt;br /&gt;
&lt;br /&gt;
=== Find Your Text ===&lt;br /&gt;
&amp;lt;small&amp;gt;''Sounds kinda like a platitude you'd find on a pillow in Kohl's.''&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In our opened new script log, we should search for the words &amp;quot;Hello World!&amp;quot;. We can either do that using the Search tab we have set up, or clicking into the script log in the main window and using Ctrl+F.&lt;br /&gt;
[[File:First script 10.png|none|thumb|911x911px|Our first trigger of stuff in the game!Hey, did you put a naughty word instead of &amp;quot;Hello World!&amp;quot;? You lil nasty gremlin.]]&lt;br /&gt;
WE FUCKING DID IT HELL YES.&lt;br /&gt;
&lt;br /&gt;
And that's it, you're ready to script on your own!&lt;br /&gt;
&lt;br /&gt;
Bye!&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_10.png&amp;diff=685</id>
		<title>File:First script 10.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_10.png&amp;diff=685"/>
		<updated>2023-06-10T17:36:40Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hello World! trigger&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_9.png&amp;diff=684</id>
		<title>File:First script 9.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_9.png&amp;diff=684"/>
		<updated>2023-06-10T16:54:56Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Functioning Hello World!&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_8.png&amp;diff=683</id>
		<title>File:First script 8.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_8.png&amp;diff=683"/>
		<updated>2023-06-10T16:51:04Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;out function params&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_7.png&amp;diff=682</id>
		<title>File:First script 7.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_7.png&amp;diff=682"/>
		<updated>2023-06-10T16:46:15Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;everything exploded&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=677</id>
		<title>Lua/First Script</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/First_Script&amp;diff=677"/>
		<updated>2023-06-10T16:34:35Z</updated>

		<summary type="html">&lt;p&gt;Vandy: starting progress so I don't lose it all to a power outage&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In this first step tutorial, we're going to learn:&lt;br /&gt;
&lt;br /&gt;
* How to load &amp;amp; run a custom Lua script&lt;br /&gt;
* How timing works, at a large level, with scripts&lt;br /&gt;
* How to print out game information to interrogate the state of the game&lt;br /&gt;
* How simple variables work&lt;br /&gt;
&lt;br /&gt;
Let's create our first script together!&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
First thing's first, let's crack open RPFM to create our new Mod. In RPFM, I'm going to use MyMod -&amp;gt; New MyMod, to create a new easy-to-use mod system. If you haven't already, follow the setup guides in [[RPFM]] for setting up preferences and paths.&lt;br /&gt;
&lt;br /&gt;
[[File:First Script 01.png|frameless|712x712px]]&lt;br /&gt;
&lt;br /&gt;
RPFM will then open up our new MyMod. Within it, use MyMod -&amp;gt; Export, which will unload the contents of the newly created (almost entirely empty) MyMod into your specified MyMods folder. I have this folder pinned to my quick access, but you can also get there with MyMod -&amp;gt; Open MyMod Folder, and navigating down to the newly created MyMod.&lt;br /&gt;
&lt;br /&gt;
Now we can right click this folder and use the newly added &amp;quot;Open with Code&amp;quot; button, which will take the targeted mod folder and open it within Visual Studio Code!&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Navigation ==&lt;br /&gt;
When we open up in Visual Studio Code, we'll see something that looks a little bit like this - it might differ slightly, that's totally okay!&lt;br /&gt;
[[File:First script 2.png|none|thumb|1061x1061px|It might seem like quite a lot at first, but we'll get used to it! Just make sure to set the settings to dark mode if you're not insane.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before we get too far, let's break down some of the parts of what we're looking at here, and set up our windows so we have everything we need.&lt;br /&gt;
&lt;br /&gt;
=== Primary Bar ===&lt;br /&gt;
On the very left, we have what VSCode calls the &amp;quot;Primary Bar&amp;quot;. It has a few things here - the top has the two files stacked on each other, a search button below that, three buttons we don't have to worry too much about yet, and a Bookmark button. The bottom has our Account and Manage button. '''If you haven't already''', click into the Manage button and set our Profile to the correct one. I have mine saved as &amp;quot;TW Lua&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
The part of the primary bar we care most about is the top button, the &amp;quot;Explorer&amp;quot;. Think of this as your file navigation - it's effectively the same as navigating the Windows File Explorer, but it has some extra goodies that will be nice for us.&lt;br /&gt;
[[File:First script 3.png|left|thumb|578x578px]]&lt;br /&gt;
At the top of the Explorer, we have &amp;quot;Open Editors&amp;quot;. This will show us all of our actively opened files - we'll see this shortly!&lt;br /&gt;
&lt;br /&gt;
Below that, we have a tab for the currently opened folder. My folder is named babys_first_script, so that's what shows as the name here. Inside are all of the folders AND files that exist within my folder on my PC. We can open, create, rename, and delete any file within to our heart's content, and edit as long as Visual Studio Code can edit it. VSCode can edit essentially any text file, which is what all code files are, effectively. Based on the type of text file, VSCode will handle it differently - it knows the difference between a .lua and a .json file, and will react accordingly to the specifications of either language.&lt;br /&gt;
&lt;br /&gt;
Below that, we had &amp;quot;TODOs: Tree&amp;quot;, which is an extension preloaded with our Profile. This is one of my favorite tabs, because I can leave notes for myself to do stuff later and they will be displayed in this window.&lt;br /&gt;
&lt;br /&gt;
Below that are Outline and Timeline, which I rarely use but can sometimes be nice. Outline will show us the layout of our code, and Timeline will show us previous local history for saving/editing these files, and more details if we're using GitHub or another version control software.&lt;br /&gt;
&lt;br /&gt;
The Search button is also incredibly useful, for reasons that may be obvious.&lt;br /&gt;
&lt;br /&gt;
=== Menu Bar ===&lt;br /&gt;
On the very top, we have our conveniently named Top Bar, or Menu Bar. You've seen these a billion times before. There's a LOT of stuff up here, but in my five years of using this program for TW Lua I've only really cared about a couple buttons within.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;File&amp;quot; is going to be our best friend, for opening new windows, saving, and creating new files. Edit/Selection/View have a load of commands in them, and they may be good to reference often early on to see shortcuts for saving and other helpful code shortcuts, like duplicating text or renaming stuff.&lt;br /&gt;
&lt;br /&gt;
For now, what we should do is click View -&amp;gt; Problems, which will open up a new bottom bar for us. We only care about the &amp;quot;Problems&amp;quot; tab that shows up.&lt;br /&gt;
&lt;br /&gt;
=== Customizabilitization ===&lt;br /&gt;
Let's introduce the idea here that VSCode is '''super duper''' flexible with its layout. Anything on your screen right now can be put somewhere else, including individual tabs, buttons, anything. We can move Problems as a button to the Primary Bar, the Explorer as a tab on the bottom, and TODOs on the right all alone.&lt;br /&gt;
[[File:First script 4.png|thumb|824x824px]]&lt;br /&gt;
It's a bit clunky and not exactly what I need, but it's as good time as any to show you how flexible it can get.&lt;br /&gt;
&lt;br /&gt;
For now, I'm going to plop Search and TODOs on my new right sidebar stacked on one another, I'm going to right click one of the tabs at the bottom and deselect &amp;quot;Terminal&amp;quot;, &amp;quot;Output&amp;quot;, and &amp;quot;Debug Console&amp;quot;, and keep my left Primary Bar as is otherwise and open back up the Explorer.&lt;br /&gt;
&lt;br /&gt;
== Script Creation ==&lt;br /&gt;
Okay, enough preamble. Let's get it started.&lt;br /&gt;
&lt;br /&gt;
=== The Plan ===&lt;br /&gt;
Our standard first step for creating a new script is the first step we should do whenever making a new mod or system: having a plan, something we want. For this one, our goal is going to be simple. I want the following:&lt;br /&gt;
&lt;br /&gt;
* When the game starts, I want to output a message to a text file that tells me the game started, and tells me where my starting faction leader and capital region are.&lt;br /&gt;
* On every turn after that, I want to give my faction some extra gold.&lt;br /&gt;
* If I'm playing as Karl Franz, I want to give my faction another two armies.&lt;br /&gt;
* I swear it's balanced.&lt;br /&gt;
&lt;br /&gt;
=== Make It ===&lt;br /&gt;
[[File:First script 5.png|left|thumb|Second button from the left!]]&lt;br /&gt;
In VSC, go to the Explorer, and hover over the currently-opened-folder tab. You can either right click within the white space and press &amp;quot;New Folder&amp;quot;, or press the New Folder button on the tab for the currently opened folder.&lt;br /&gt;
&lt;br /&gt;
Name the empty folder that's created `script`. All scripts we write will be in this main folder. With this folder selected, create a new folder again, and call this one &amp;quot;campaign&amp;quot;. Do it again, calling the third &amp;quot;mod&amp;quot;, making our full path script/campaign/mod.&amp;lt;blockquote&amp;gt;'''NOTE:''' This folder path is one of several that is specified by Creative Assembly in more recent games, for modders to add scripts to which get automatically loaded. This behavior exists in Warhammer II, Warhammer III, Three Kingdoms, and Troy. It may continue for future games, but any game before Warhammer II needs a different way to load scripts.&lt;br /&gt;
&lt;br /&gt;
For more information, check out [[Lua/Loading Scripts]].&amp;lt;/blockquote&amp;gt;Within script/campaign/mod, now either right click the folder and press &amp;quot;New Text File&amp;quot;, or use the first button on the tab to create a new file. I'm going to name mine &amp;quot;totally_not_cheats.lua&amp;quot;. '''The .lua extension is required, don't skip it!'''&lt;br /&gt;
&lt;br /&gt;
=== Start It ===&lt;br /&gt;
With our newly created file, our VSC layout will change ever so slightly. In &amp;quot;Open Editors&amp;quot;, we'll see our fresh new baby script created; and in the central window, we'll see a new tab that's named the same as our new file, and an empty text file in the center with just the number &amp;quot;1&amp;quot; in it.&lt;br /&gt;
[[File:First script 6.png|none|thumb|1141x1141px|Notice the lil' moon symbol next to our file? That's because Lua is Portuguese for moon!]]&lt;br /&gt;
We'll kick off our script with the first piece of the puzzle, outputting some text to a file so we can read and interface with our scripts.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_6.png&amp;diff=674</id>
		<title>File:First script 6.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_6.png&amp;diff=674"/>
		<updated>2023-06-10T16:28:54Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;first script who dis&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_5.png&amp;diff=668</id>
		<title>File:First script 5.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_5.png&amp;diff=668"/>
		<updated>2023-06-10T16:19:34Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;New folder in Explorer.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_4.png&amp;diff=665</id>
		<title>File:First script 4.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_4.png&amp;diff=665"/>
		<updated>2023-06-10T15:41:51Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A reworked main window of Visual Studio Code.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_3.png&amp;diff=664</id>
		<title>File:First script 3.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_3.png&amp;diff=664"/>
		<updated>2023-06-10T15:29:10Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Close-up look at the Explorer menu.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_script_2.png&amp;diff=663</id>
		<title>File:First script 2.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_script_2.png&amp;diff=663"/>
		<updated>2023-06-10T15:21:13Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Default opening view of Visual Studio Code.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=File:First_Script_01.png&amp;diff=662</id>
		<title>File:First Script 01.png</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=File:First_Script_01.png&amp;diff=662"/>
		<updated>2023-06-10T15:06:15Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MyMod popup for the first script mod.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=661</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=661"/>
		<updated>2023-06-10T14:49:43Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** https://chadvandy.github.io/tw_modding_resources/index.html|Creative Assembly Scripting Documentation&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua&amp;diff=660</id>
		<title>Lua</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua&amp;diff=660"/>
		<updated>2023-06-08T01:32:20Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the landing page of all things Lua - at least, in the context of the Total War series. Enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
== What It Is ==&lt;br /&gt;
'''Lua''' is a ''scripting language'' - which is a type of programming language that is not precompiled. That's fancy jargon for &amp;quot;it isn't translated into computer-speak until we run it&amp;quot;. It's a super flexible language with a lot of quirks, designed to be an easy-to-approach language for people who aren't programmers but want to do some programming. Therefore it consists of very few forced assumptions or designs, most of its syntax is plain-English, and for the most part it doesn't have a ''lot'' going on within.&lt;br /&gt;
&lt;br /&gt;
Why do we care? Lua is the embedded scripting language within most Total War games, and it's a super flexible toolkit that allows us to interact with the game in dynamic and complex ways.&lt;br /&gt;
&lt;br /&gt;
Some highlighted features of things that are ''scripted'':&lt;br /&gt;
&lt;br /&gt;
* Every Quest Battle (the actions and responses taken by the AI armies, the objectives and how they react to the flow of battle)&lt;br /&gt;
* Varied start positions (ie. a faction owning one or another region based on the player's starting faction)&lt;br /&gt;
* LOADS of in-game mechanics:&lt;br /&gt;
* Rites/Rituals&lt;br /&gt;
* Many Missions&lt;br /&gt;
* Dynamic encounters&lt;br /&gt;
* Story-driven experiences (Attila: The Last Roman, Warhammer III: Prologue, Troy)&lt;br /&gt;
&lt;br /&gt;
Scripting is a design tool that is used whenever you want to have the following system:&amp;lt;blockquote&amp;gt;When [something happens], do [something else].&amp;lt;/blockquote&amp;gt;Lua is run by the game through individual text files, with the *.lua extension. Each of these files is called a &amp;quot;script&amp;quot;. And we'll call writing up these files, you guessed it, scripting!&lt;br /&gt;
&lt;br /&gt;
== How To Use It ==&lt;br /&gt;
As we can see, Lua is a useful tool! It can provide a lot of power in the hands of a modder with some big dreams and some time to kill, and maybe some tears here and there.&lt;br /&gt;
&lt;br /&gt;
But the good news is that Lua is also a great and powerful language, with MANY tools available to easily debug and resolve issues you might have with your scripts, and the TW Lua environment is rife with example scripts, from Creative Assembly and many modders throughout the game series.&lt;br /&gt;
&lt;br /&gt;
In pages to follow, we'll go over writing our first script, some details of how the Lua language works, how to debug, how to dream big and small, but before we go anywhere else we have to start at the beginning:&lt;br /&gt;
&lt;br /&gt;
[[Lua/Setup|Let's get set up!]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua]]&lt;br /&gt;
[[Category:Tutorial]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Main_Page&amp;diff=659</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Main_Page&amp;diff=659"/>
		<updated>2023-06-08T01:06:34Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== NEW WEBSITE ==&lt;br /&gt;
Yes, yes, we're on our sixth or seventh or eight iteration of this website!&lt;br /&gt;
&lt;br /&gt;
This newest version is built upon MediaWiki (same thing Wikipedia uses), and is very much a work in progress, but it's hopefully a much better time all around.&lt;br /&gt;
== Hello ==&lt;br /&gt;
Welcome to the very in-progress Total War: Modding Wiki! Maintained by Vandy, filled in by anyone!&lt;br /&gt;
&lt;br /&gt;
This Wiki is intended to be as good of a one-stop-shop as possible for modding the Total War series, when it comes to walkthroughs for early set-up and understanding, or tutorials to do specific tasks, or general wiki pages as an overview for various modding and game concepts. It should contain all the resources and tutorials really needed to go forward in modding - when all is said and done.&lt;br /&gt;
&lt;br /&gt;
This project is born out of the members of the [https://discord.gg/dd4TUDm Modding Den Discord channel], which is focused on the Total War: Warhammer side of the franchise due to its original founding by two popular Warhammer modders - but other Total Wars are more than welcome here!&lt;br /&gt;
&lt;br /&gt;
The [https://www.totalwar.com/ Total War] Franchise is a product of [https://www.creative-assembly.com/home Creative Assembly], they own it and other important legal business here.&lt;br /&gt;
&lt;br /&gt;
== Navigation ==&lt;br /&gt;
&lt;br /&gt;
=== All available [[Tutorial:Main Page|Tutorials]]: ===&lt;br /&gt;
{{Special:Prefixindex/Tutorial:}}&lt;br /&gt;
&lt;br /&gt;
[[:Category:Tools &amp;amp; Resources|Tools &amp;amp; Resources]]&lt;br /&gt;
===Tutorial Series===&lt;br /&gt;
&lt;br /&gt;
==== Lua Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/Lua:}}&lt;br /&gt;
&lt;br /&gt;
==== UI Tutorial Series, by Vandy: ====&lt;br /&gt;
{{Special:Prefixindex/UI:}}&lt;br /&gt;
&lt;br /&gt;
==== Battle Map Tutorial Series, by Frodo: ====&lt;br /&gt;
{{Special:Prefixindex/Battle Maps:}}&lt;br /&gt;
=== All Pages ===&lt;br /&gt;
{{Special:AllPages}}&lt;br /&gt;
&lt;br /&gt;
=== External Tutorials ===&lt;br /&gt;
&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1698960734 Abilities]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761202425 Ancillaries (Items, Mounts, etc)]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1696051257 Character Skills]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1694945483 Creating Custom Units]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=1761177338 Effects]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2180764161 Modding 101/FAQs]&lt;br /&gt;
* [https://steamcommunity.com/sharedfiles/filedetails/?id=2233644229 Modding Etiquette and Guidelines]&lt;br /&gt;
&lt;br /&gt;
== Help Out ==&lt;br /&gt;
There's a lot to do to help out! Most importantly, '''share what knowledge you have.''' If you are very knowledgeable about some subject, write a few new pages about it. Make edits to existing pages. Add new categories, fill out details. This is a communal effort, and while I'll be trying to shepherd it along and keep everything relatively organized, this is very intentionally a group effort!&lt;br /&gt;
&lt;br /&gt;
''Note: Only verified accounts can make edits. Just register a new account with your username and log in, and you can make edits. They will currently enter approval queue to prevent spam.''&lt;br /&gt;
&lt;br /&gt;
'''To make a new page:''' You just have to search for a page in the search bar. The website will ask &amp;quot;Do you want to create a page with name X?&amp;quot; or something similar - click the red link, and start creating a new page from there!&lt;br /&gt;
&lt;br /&gt;
- [[Tutorial:Main Page|Tutorials]] should be named &amp;quot;Tutorial:Tutorial Name Here&amp;quot;&lt;br /&gt;
&lt;br /&gt;
- Any other page can be named anything else, it doesn't matter. Please mind that only one page can exist with that name, of course, so be proper with your names.&lt;br /&gt;
&lt;br /&gt;
==Helpful Links For Now==&lt;br /&gt;
*[[mediawikiwiki:Help:Editing_pages|Best practices for editing pages]]&lt;br /&gt;
*[[mediawikiwiki:Help:Formatting|A How-To on using the MediaWiki Formatting]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Configuration_settings|Configuration settings list]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:FAQ|MediaWiki FAQ]]&lt;br /&gt;
*[https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Localisation#Translation_resources|Localise MediaWiki for your language]]&lt;br /&gt;
*[[mediawikiwiki:Special:MyLanguage/Manual:Combating_spam|Learn how to combat spam on your wiki]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua&amp;diff=657</id>
		<title>Lua</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua&amp;diff=657"/>
		<updated>2023-06-08T00:51:25Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Welcome to the landing page of all things Lua - at least, in the context of the Total War series. Enjoy your stay!&lt;br /&gt;
&lt;br /&gt;
{{Special:PrefixIndex/Lua/}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua]]&lt;br /&gt;
[[Category:Tutorial]]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=656</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=656"/>
		<updated>2023-06-08T00:47:36Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=655</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=MediaWiki:Sidebar&amp;diff=655"/>
		<updated>2023-06-08T00:46:46Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
* TW Links&lt;br /&gt;
** https://discord.gg/dd4TUDm|Modding Den Discord&lt;br /&gt;
** https://www.totalwar.com/|Official TW Site&lt;br /&gt;
** Special:IframePage/Den|Testing iFrame&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=654</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=654"/>
		<updated>2023-06-08T00:15:14Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* Wiki */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
* &amp;lt;s&amp;gt;Look into WYSIWYG editor for the wiki. Previously used version was buggy, but it might be better on the latest update of MediaWiki.&amp;lt;/s&amp;gt;&lt;br /&gt;
** Works perfectly on the new version!&lt;br /&gt;
* Search for better moderation tools, more all-in-one packages.&lt;br /&gt;
* Setup a more robust sidebar, include links to the Modding Den and such.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Move&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;br /&gt;
* Pages for each tool - RPFM, Assembly Kit, mod manager[s], etc. Sections for installation, usage, glossary, and helpful tips (ie. MyMod in RPFM)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=653</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=653"/>
		<updated>2023-06-08T00:14:49Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* Wiki */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
* &amp;lt;s&amp;gt;Look into WYSIWYG editor for the wiki. Previously used version was buggy, but it might be better on the latest update of MediaWiki.&amp;lt;/s&amp;gt;&lt;br /&gt;
** Works perfectly on the new version!&lt;br /&gt;
* Search for better moderation tools, and more all-in-one packages.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Move&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;br /&gt;
* Pages for each tool - RPFM, Assembly Kit, mod manager[s], etc. Sections for installation, usage, glossary, and helpful tips (ie. MyMod in RPFM)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/Setup&amp;diff=652</id>
		<title>Lua/Setup</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/Setup&amp;diff=652"/>
		<updated>2023-06-06T23:46:39Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;So you're ready to start programming in Lua - you've got [[RPFM]] set up, you're ready to go. Let's just crack open the text editor in RPFM and get going! Right?&lt;br /&gt;
&lt;br /&gt;
NO. DAMN IT, ABSOLUTELY NOT.&lt;br /&gt;
&lt;br /&gt;
== Why ==&lt;br /&gt;
This setup is, to put it lightly, ''extremely'' beneficial for long-term enjoyment and efficiency in programming Lua in Total War. &lt;br /&gt;
&lt;br /&gt;
There are features we'll get access to that will make life much simpler, including:&lt;br /&gt;
* A prettier color scheme that feels good to look at!&lt;br /&gt;
* Access to many life-preserving shortcuts.&lt;br /&gt;
* Easy ways to reference other parts of other scripts that you have opened.&lt;br /&gt;
* And best of all, ''a system that will yell at you whenever you fuck up!''&lt;br /&gt;
&lt;br /&gt;
This setup I've found is absolutely crucial to writing code. '''Even if you're a beginner, do not skip this step.''' You will regret it later, for sure.&lt;br /&gt;
&lt;br /&gt;
TODO add in some example images here of things VSC can do for us.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
First off, if you don't already have it, actually go get [[RPFM]] and set it up. Go ahead, I'll wait until you come back.&lt;br /&gt;
* You'll want to make sure RPFM's preferences for &amp;quot;MyMod&amp;quot; and &amp;quot;Game Paths&amp;quot; are all setup, before we go too far forward!&lt;br /&gt;
&lt;br /&gt;
Next, you'll want to install [https://code.visualstudio.com/ Visual Studio Code]. Grab the version that's right for you - 99.999% of the time you can just use the default build for Windows - and install it.&lt;br /&gt;
* Make sure you flag all the options in the install parameter as yes; &amp;quot;Open with Code&amp;quot; action, &amp;quot;Register Code&amp;quot;, and &amp;quot;Add to PATH&amp;quot; are all helpful options here.&lt;br /&gt;
* Install it wherever you'd like; it shouldn't matter too much where it is.&lt;br /&gt;
&lt;br /&gt;
We will be using Visual Studio Code to write our scripts. The main purpose of RPFM is to create and edit our .pack files, but Visual Studio Code is a much more robust ecosystem for editing code files, and to top it all off there's a plugin and some resources that we can use to put a load of tools and automation in our arsenal.&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Setup ==&lt;br /&gt;
Grab RPFM and open it up. Frodo has built-in, thankfully, a command to download a file that basically contains all of a game's Lua definitions - this is necessary for the debugger we're setting up to know what can and can't be used. If that doesn't make sense, don't worry - it will soon!&lt;br /&gt;
* Plop open RPFM.&lt;br /&gt;
* Go to About -&amp;gt; Check TW Autogen Updates.&lt;br /&gt;
* If it says there's something available, press download!&lt;br /&gt;
* Use &amp;quot;Game Selected -&amp;gt; Open RPFM's Config Folder&amp;quot;, and just have that open in the background.&lt;br /&gt;
&lt;br /&gt;
Now, open up Visual Studio Code. You should be able to just search its name in your Windows search bar to open up the program. I find it incredibly convenient to have it pinned to my taskbar, but I use it nearly every time I turn on my PC - YMMV.&lt;br /&gt;
&lt;br /&gt;
You'll probably be honestly pretty overwhelmed. There's a lot going on! Good news, there's an easy set up that you have to do. I have made a file that's a &amp;quot;profile&amp;quot; of my most-recommended settings for Visual Studio Code with TW Lua. You'll import this profile, it'll install a few plugins within VSCode, it'll apply a few settings, and you can go off to the races!&lt;br /&gt;
&lt;br /&gt;
* Download [[:File:TW_Lua.zip|this file]]&lt;br /&gt;
* Select that file using File Explorer, press the file in your Downloads folder, press the &amp;quot;Extract - Compressed Folder Tools&amp;quot; on the top bar, and use &amp;quot;Extract All&amp;quot;.&lt;br /&gt;
* In VSCode, use the &amp;quot;Manage&amp;quot; cog button on the bottom left.&lt;br /&gt;
* Hover on &amp;quot;Profiles (Default)&amp;quot;, and use &amp;quot;Import Profiles.&amp;quot;&lt;br /&gt;
* Press &amp;quot;Create from profile template file&amp;quot;, which will prompt you to select a file on your computer; navigate to the TW_Lua.code-profile file that's within the .zip above.&lt;br /&gt;
* Make decisions if you want to keep or remove some of the things in my profile; I have a few optional extensions that I put into the code-profile. '''''Do NOT remove the Lua extension.'''''&lt;br /&gt;
* Press &amp;quot;Create Profile&amp;quot; on the next prompt, and Visual Studio Code will then handle installing the extensions and setting up your different settings in the background.&lt;br /&gt;
&lt;br /&gt;
One beautiful thing with Profiles is that they are just that - a profile! If you happen to program multiple TW games, or you end up using VSCode for other languages, or already use VSCode and don't want to clog up your existing beautiful systems, you can make a new profile and keep everything nice and contextualized.&lt;br /&gt;
&lt;br /&gt;
And that's almost it! We just have one more step to take.&lt;br /&gt;
* Go to the &amp;quot;Manage&amp;quot; button on the bottom left again, and go to &amp;quot;Settings&amp;quot; within.&lt;br /&gt;
* On the topbar that says &amp;quot;Search settings&amp;quot;, type in &amp;quot;Lua.workspace.library&amp;quot;. This is a setting that tells the debugger extension we'll be using where to look for our definition files.&lt;br /&gt;
* In RPFM, use: Game Selected -&amp;gt; Open RPFM's Config Folder&lt;br /&gt;
* In the folder that opens up, navigate to tw_autogen -&amp;gt; output -&amp;gt; find the game that you're interested in.&lt;br /&gt;
* Open up the game folder, and press into the folder path in File Explorer to get the full path to the files.[[File:VSC2.png|thumb|none|693x693px]]&lt;br /&gt;
*Return to VSCode, and in the &amp;quot;Lua.workspace.library&amp;quot; setting, press the edit button and fill in the path to the game in question, and press 'OK'. &lt;br /&gt;
[[File:VSC3.png|thumb|none|731x731px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And there we are. All the tools and settings you need for starting up on TW Lua scripting!&lt;br /&gt;
&lt;br /&gt;
== Working With Visual Studio Code ==&lt;br /&gt;
[TODO]&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=User:Vandy&amp;diff=651</id>
		<title>User:Vandy</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=User:Vandy&amp;diff=651"/>
		<updated>2023-06-06T23:41:00Z</updated>

		<summary type="html">&lt;p&gt;Vandy: Created page with &amp;quot;hi&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;hi&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=650</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=650"/>
		<updated>2023-06-06T23:38:37Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
* Look into WYSIWYG editor for the wiki. Previously used version was buggy, but it might be better on the latest update of MediaWiki.&lt;br /&gt;
* Search for better moderation tools, and more all-in-one packages.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Move&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;br /&gt;
* Pages for each tool - RPFM, Assembly Kit, mod manager[s], etc. Sections for installation, usage, glossary, and helpful tips (ie. MyMod in RPFM)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=649</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=649"/>
		<updated>2023-06-06T23:30:24Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
* Look into WYSIWYG editor for the wiki. Previously used version was buggy, but it might be better on the latest update of MediaWiki.&lt;br /&gt;
* Search for better moderation tools, and more all-in-one packages.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Rename&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;br /&gt;
* Pages for each tool - RPFM, Assembly Kit, mod manager[s], etc. Sections for installation, usage, glossary, and helpful tips (ie. MyMod in RPFM)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=648</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=648"/>
		<updated>2023-06-06T23:25:12Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Rename&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;br /&gt;
* Pages for each tool - RPFM, Assembly Kit, mod manager[s], etc. Sections for installation, usage, glossary, and helpful tips (ie. MyMod in RPFM)&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=647</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=647"/>
		<updated>2023-06-06T23:23:51Z</updated>

		<summary type="html">&lt;p&gt;Vandy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
** Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Rename&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
** Groove Wizard will take point here&lt;br /&gt;
** Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
** Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Meta&amp;diff=646</id>
		<title>Meta</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Meta&amp;diff=646"/>
		<updated>2023-06-06T23:23:08Z</updated>

		<summary type="html">&lt;p&gt;Vandy: Created page with &amp;quot;This is a meta-page about things involving the website itself. Pretty meta, huh?  == To Do == Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.  === Wiki === * Set up the scripting documentation and other external documentation into this website's...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is a meta-page about things involving the website itself. Pretty meta, huh?&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
Ongoing list of things that need doing with the website. '''If you're able to help with something listed below''', simply edit this page and make a note there that says &amp;quot;[username] will help with this!&amp;quot; If you need any guidance, please feel free to reach out to Groove Wizard.&lt;br /&gt;
&lt;br /&gt;
=== Wiki ===&lt;br /&gt;
* Set up the scripting documentation and other external documentation into this website's hierarchy, instead of relying on hosting it separately. Will probably be as simple as hosting on the web server I have and having a link on the sidebar to documentation, though maybe there's an internal MediaWiki system for working with documentation&lt;br /&gt;
  * Groove Wizard will do this&lt;br /&gt;
* Find someone way more experienced in web dev that can give Groove Wizard some insight into various trouble spots.&lt;br /&gt;
* Go through https://www.mediawiki.org/wiki/Category:Stable_skins and find any that are specifically appealing and might work well for the wiki.&lt;br /&gt;
&lt;br /&gt;
=== Organization ===&lt;br /&gt;
* Go through existing categories, and create any more that are necessary. Make new categories for &amp;quot;spheres&amp;quot; of modding (modeling, map making, scripts, db, planning, etc.)&lt;br /&gt;
* Move old Tutorials out of their current location, which is &amp;quot;Tutorial:Tutorial Name&amp;quot;, and move them to a new page using &amp;quot;Edit -&amp;gt; More -&amp;gt; Rename&amp;quot;. Then properly categorize the tutorials, including marking them as &amp;quot;outdated&amp;quot;, &amp;quot;needs review&amp;quot;, the game it works for, and whatever else.&lt;br /&gt;
&lt;br /&gt;
=== Topics ===&lt;br /&gt;
* Go through the Lua tutorial series and clean it up.&lt;br /&gt;
  * Groove Wizard will take point here&lt;br /&gt;
  * Could use a couple of hands with review, editing, grabbing pictures, writing sections, etc.&lt;br /&gt;
* Deep dive on TWUI XML stuff&lt;br /&gt;
  * Groove Wizard again, probably much later.&lt;br /&gt;
* Overview of missions / dilemmas / events / incidents / messages / payloads / options / cdir at large.&lt;br /&gt;
* Dark secrets of animation unveiled.&lt;br /&gt;
* Lua - Overwriting / intercompatibility w/ vanilla and other scripts, etc.&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
	<entry>
		<id>https://tw-modding.com/index.php?title=Lua/Setup&amp;diff=645</id>
		<title>Lua/Setup</title>
		<link rel="alternate" type="text/html" href="https://tw-modding.com/index.php?title=Lua/Setup&amp;diff=645"/>
		<updated>2023-06-06T23:09:41Z</updated>

		<summary type="html">&lt;p&gt;Vandy: /* Why */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;So you're ready to start programming in Lua - you've got [[RPFM]] set up, you're ready to go. Let's just crack open the text editor in RPFM and get going! Right?&lt;br /&gt;
&lt;br /&gt;
NO. DAMN IT, ABSOLUTELY NOT.&lt;br /&gt;
&lt;br /&gt;
== Why ==&lt;br /&gt;
This setup is, to put it lightly, ''extremely'' beneficial for long-term enjoyment and efficiency in programming Lua in Total War. &lt;br /&gt;
&lt;br /&gt;
There are features we'll get access to that will make life much simpler, including:&lt;br /&gt;
* A prettier color scheme that feels good to look at!&lt;br /&gt;
* Access to many life-preserving shortcuts.&lt;br /&gt;
* Easy ways to reference other parts of other scripts that you have opened.&lt;br /&gt;
* And best of all, ''a system that will yell at you whenever you fuck up!''&lt;br /&gt;
&lt;br /&gt;
This setup I've found is absolutely crucial to writing code. '''Even if you're a beginner, do not skip this step.''' You will regret it later, for sure.&lt;br /&gt;
&lt;br /&gt;
TODO add in some example images here of things VSC can do for us.&lt;br /&gt;
&lt;br /&gt;
== What You Need ==&lt;br /&gt;
First off, if you don't already have it, actually go get [[RPFM]] and set it up. Go ahead, I'll wait until you come back.&lt;br /&gt;
* You'll want to make sure RPFM's preferences for &amp;quot;MyMod&amp;quot; and &amp;quot;Game Paths&amp;quot; are all setup, before we go too far forward!&lt;br /&gt;
&lt;br /&gt;
Next, you'll want to install [https://code.visualstudio.com/ Visual Studio Code]. Grab the version that's right for you - 99.999% of the time you can just use the default build for Windows - and install it.&lt;br /&gt;
* Make sure you flag all the options in the install parameter as yes; &amp;quot;Open with Code&amp;quot; action, &amp;quot;Register Code&amp;quot;, and &amp;quot;Add to PATH&amp;quot; are all helpful options here.&lt;br /&gt;
* Install it wherever you'd like; it shouldn't matter too much where it is.&lt;br /&gt;
&lt;br /&gt;
We will be using Visual Studio Code to write our scripts. The main purpose of RPFM is to create and edit our .pack files, but Visual Studio Code is a much more robust ecosystem for editing code files, and to top it all off there's a plugin and some resources that we can use to put a load of tools and automation in our arsenal.&lt;br /&gt;
&lt;br /&gt;
== Visual Studio Code Setup ==&lt;br /&gt;
Grab RPFM and open it up. Frodo has built-in, thankfully, a command to download a file that basically contains all of a game's Lua definitions - this is necessary for the debugger we're setting up to know what can and can't be used. If that doesn't make sense, don't worry - it will soon!&lt;br /&gt;
* Plop open RPFM.&lt;br /&gt;
* Go to About -&amp;gt; Check TW Autogen Updates.&lt;br /&gt;
* If it says there's something available, press download!&lt;br /&gt;
* Use &amp;quot;Game Selected -&amp;gt; Open RPFM's Config Folder&amp;quot;, and just have that open in the background.&lt;br /&gt;
&lt;br /&gt;
Now, open up Visual Studio Code. You should be able to just search its name in your Windows search bar to open up the program. I find it incredibly convenient to have it pinned to my taskbar, but I use it nearly every time I turn on my PC - YMMV.&lt;br /&gt;
&lt;br /&gt;
You'll probably be honestly pretty overwhelmed. There's a lot going on! Good news, there's an easy set up that you have to do. I have made a file that's a &amp;quot;profile&amp;quot; of my most-recommended settings for Visual Studio Code with TW Lua. You'll import this profile, it'll install a few plugins within VSCode, it'll apply a few settings, and you can go off to the races!&lt;br /&gt;
&lt;br /&gt;
* Download [[:File:TW_Lua.zip|this file]]&lt;br /&gt;
* Select that file using File Explorer, press the file in your Downloads folder, press the &amp;quot;Extract - Compressed Folder Tools&amp;quot; on the top bar, and use &amp;quot;Extract All&amp;quot;.&lt;br /&gt;
* In VSCode, use the &amp;quot;Manage&amp;quot; cog button on the bottom left.&lt;br /&gt;
* Hover on &amp;quot;Profiles (Default)&amp;quot;, and use &amp;quot;Import Profiles.&amp;quot;&lt;br /&gt;
* Press &amp;quot;Create from profile template file&amp;quot;, which will prompt you to select a file on your computer; navigate to the TW_Lua.code-profile file that's within the .zip above.&lt;br /&gt;
* Make decisions if you want to keep or remove some of the things in my profile; I have a few optional extensions that I put into the code-profile. '''''Do NOT remove the Lua extension.'''''&lt;br /&gt;
* Press &amp;quot;Create Profile&amp;quot; on the next prompt, and Visual Studio Code will then handle installing the extensions and setting up your different settings in the background.&lt;br /&gt;
&lt;br /&gt;
One beautiful thing with Profiles is that they are just that - a profile! If you happen to program multiple TW games, or you end up using VSCode for other languages, or already use VSCode and don't want to clog up your existing beautiful systems, you can make a new profile and keep everything nice and contextualized.&lt;br /&gt;
&lt;br /&gt;
And that's almost it! We just have one more step to take.&lt;br /&gt;
* Go to the &amp;quot;Manage&amp;quot; button on the bottom left again, and go to &amp;quot;Settings&amp;quot; within.&lt;br /&gt;
* On the topbar that says &amp;quot;Search settings&amp;quot;, type in &amp;quot;Lua.workspace.library&amp;quot;. This is a setting that tells the debugger extension we'll be using where to look for our definition files.&lt;br /&gt;
* In RPFM, use: Game Selected -&amp;gt; Open RPFM's Config Folder&lt;br /&gt;
* In the folder that opens up, navigate to tw_autogen -&amp;gt; output -&amp;gt; find the game that you're interested in.&lt;br /&gt;
* Open up the game folder, and press into the folder path in File Explorer to get the full path to the files. &lt;br /&gt;
[[File:VSC2.png|thumb|left]]&lt;br /&gt;
* Return to VSCode, and in the &amp;quot;Lua.workspace.library&amp;quot; setting, press the edit button and fill in the path to the game in question, and press 'OK'.&lt;br /&gt;
[[File:VSC3.png|thumb|left]]&lt;br /&gt;
&lt;br /&gt;
And there we are. All the tools and settings you need for starting up on TW Lua scripting!&lt;/div&gt;</summary>
		<author><name>Vandy</name></author>
	</entry>
</feed>