<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://www.datoolset.net/mw/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gaxkang55</id>
		<title>Dragon Age Toolset Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://www.datoolset.net/mw/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Gaxkang55"/>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/wiki/Special:Contributions/Gaxkang55"/>
		<updated>2026-06-17T22:08:48Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.25.6</generator>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15509</id>
		<title>Talk:Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15509"/>
				<updated>2011-01-10T08:26:18Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource scope edit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What if my mod extends both Single Player and Awakening? ==&lt;br /&gt;
&lt;br /&gt;
I moved this section here because it's under discussion. [[User:Proleric1|Proleric1]] 08:27, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
-------------&lt;br /&gt;
NOTE:&lt;br /&gt;
&lt;br /&gt;
There is an easier way than creating two scripts. Just put the information for both in the manifest.xml file. For one of my mods, the manifest file looked like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Manifest Type=&amp;quot;AddIn&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;AddInsList&amp;gt;&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Description DefaultText=&amp;quot;ELF the pet cat adds a 'Cat Toy' to the players inventory (rest of text deleted for brevity)&lt;br /&gt;
&lt;br /&gt;
((This package will work in both DAO and Awakening!))&amp;quot;&amp;gt;&amp;lt;/Description&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;packages/&amp;quot; Type=&amp;quot;package&amp;quot;/&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;/AddInsList&amp;gt;&lt;br /&gt;
&amp;lt;/Manifest&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
doing this allowed users to install one package (using DAModder) which worked for both awakening and DAO.&lt;br /&gt;
&lt;br /&gt;
============== ++ Angel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@monkeysnest - good to have the update concerning the manifest. A few queries:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the article would be clearer if you explained which line has to change, rather than reproduce the entire manifest here?&lt;br /&gt;
&lt;br /&gt;
* Would DAUpdater work? I don't see DAModder listed as a project download on the Bioware social site.&lt;br /&gt;
&lt;br /&gt;
* We don't normally leave our signatures on the content pages of a wiki.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
[[User:Proleric1|Proleric1]] 05:47, 8 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think the &amp;quot;dual entry, single manifest&amp;quot; approach should be followed or encouraged.  Creating two separate .dazip installations as mentioned in [[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | Compatibility: What if my mod extends both Single Player and Awakening?]] is IMHO the preferred approach.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nukenin|Nukenin]] 00:24, 24 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I'll have to agree with Nukenin here, especially since using the &amp;quot;dual entry, single manifest&amp;quot; approach will cause DAUpdater to crash and would unnecessarily force players to use third-party apps. Moreover, it's perfectly possible to include several addons (each one with its own manifest entry) in a single dazip package :&lt;br /&gt;
* Package root&lt;br /&gt;
** Manifest including several AddInItem elements&lt;br /&gt;
** Contents&lt;br /&gt;
*** addins&lt;br /&gt;
**** addin_uid1&lt;br /&gt;
**** addin_uid2&lt;br /&gt;
**** addin_uid3&lt;br /&gt;
**** etc&lt;br /&gt;
*** packages&lt;br /&gt;
&lt;br /&gt;
--[[User:Phaenan|Phaenan]] 06:45, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I find myself agreeing with Phaenan and Nukenin on this; end users should only use community created tools if they want a specific function that's only available to them that way (like the ability to uninstall a dazip). &lt;br /&gt;
[[User:Ladydesire|Ladydesire]] 18:40, 25 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Override Events while minimizing compat issues.. ==&lt;br /&gt;
&lt;br /&gt;
I believe this may be useful to others - through trial and error, and with some help, I have figured out a way to override events only when my module is running - I had to add a variable to var_module.xls/gda (which is probably where the only potential compatibility issue will arise via string ID, though I am not sure what would happen if someone tried to override the same events - depends on which engineevents get's loaded last I suppose...).&lt;br /&gt;
&lt;br /&gt;
The variable is defaulted to a 0....in my modules properties, I set the variable to a 1. My event overrides check for this variable to be == 1, if not, send it off the proper handler. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See the following post where I came to this 'workaround'...would love to know if there is a better way:&lt;br /&gt;
&lt;br /&gt;
http://social.bioware.com/forum/1/topic/8/index/2371093/1#2531362&lt;br /&gt;
&lt;br /&gt;
== Resource scope edit ==&lt;br /&gt;
&lt;br /&gt;
I have removed the reference to tint maps following the discussion at http://social.bioware.com/group/2937/discussion/12738/ .&lt;br /&gt;
&lt;br /&gt;
Also beefed up the recommendations about not putting files into packages --[[User:Gaxkang55|Gaxkang55]] 12:43, 30 December 2010 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Good update! I'm very much on the same wavelength. I have one question, though, concerning the Talk Table. Normally, the best way to change a core string is to make a new one, then point the appropriate 2DA at it. However, there are cases where no such mechanism exists. For example, if you want to make a module that isn't set in the Ferelden gameworld, you need to change the gender descriptions, replace all instances of &amp;quot;marabi&amp;quot; with &amp;quot;dog&amp;quot; and so on. To the best of my knowledge, this can't be done without an override - see [[String_editor]]. If there's a better solution, I'd be keen to hear it. [[User:Proleric1|Proleric1]] 08:50, 31 December 2010 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
As it happens, I had to do exactly that for the campaign I have in development, where I wanted to override the gender description. Create the string but make the Owner Module your module. This will be exported to the talktable placed in your core, and will overwrite the core string as long as your module is enabled. Also tested the head morph stuff, and that doesn't need to be in packages either, so will make a further update. --[[User:Gaxkang55|Gaxkang55]] 04:28, 3 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Have you tried to reproduce this [[Bug:_Talk_table_exported_to_packages_override | bug]] for the specific string mentioned there? I double-checked that the Owner Module is set correctly. It isn't exported to the talk table in core (which seems to be empty), nor does it work if the talk table in packages override is moved to any of the add-in folders.&lt;br /&gt;
&lt;br /&gt;
A couple of other issues:&lt;br /&gt;
&lt;br /&gt;
You recommend moving content from the override folders before B2P packaging. Is there any technical reason for that? I haven't heard this from Bioware. &amp;quot;If it ain't bust, don't fix it&amp;quot; might apply here? &lt;br /&gt;
&lt;br /&gt;
You've added some strong words about mods that use packages override. My heart is with you, but my head says the tone could be counter-productive. We seem to be making some progress with persuading the community that compatibility is important, but the &amp;quot;package overriders&amp;quot; are still in the majority. IMO we need to convince them to change their approach voluntarily, not antagonise them. After all, none of us has the power to deprecate anything (nor would we wish to have it). What do you think? [[User:Proleric1|Proleric1]] 08:27, 3 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Moving the compiled scripts and exported plots out of the toolsetexport folder '''into''' the override folder is a good idea, since when doing an &amp;quot;empty export directories&amp;quot;, you could accidently delete files needed for the builder to player package. I'm not sure why it would be necessary to move files out of the override folder.&lt;br /&gt;
&lt;br /&gt;
As far as the &amp;quot;package overriders&amp;quot; go, some may never change, no matter what we do; I have even seen people that were doing it basically the right way change because they weren't wanting to build multiple packages for their mods. [[User:Ladydesire|Ladydesire]] 00:03, 4 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
1. I have deleted the sentence about DAZIPs. On re-reading it actually compresses together two different ideas, and in any case doesn't really belong there. I will have a rethink about this when I have a bit more time on the weekend :-)&lt;br /&gt;
&lt;br /&gt;
2. Proleric, the string I override is the gender description string 377283. I export the talktable (which creates the three files) and delete the one in packages, ''core_en-us.tlk'', together with everything else there). Start my game and the string in overwritten correctly by the ''&amp;lt;uid&amp;gt;_c_en-us.tlk'' table.&lt;br /&gt;
&lt;br /&gt;
3. On the issue of packages override, the issue is whether or not this wiki contains correct information and procedures. If someone disagrees that this is the correct procedure (particularly in terms of mod inter-compatibility), I am more than happy to have the discussion. I suspect real change is only going to happen if the end-users start complaining in the comments sections of the download pages, but that's another story. In the meantime, the wiki should stick to the straight and narrow of providing the best information we can assemble --[[User:Gaxkang55|Gaxkang55]] 04:37, 4 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
1. Thanks.&lt;br /&gt;
&lt;br /&gt;
2. Issue closed. EDIT [[User:Proleric1|Proleric1]] 17:16, 4 January 2011 (UTC) It is not necessary to put a talk table in packages override. Instead of changing core strings, it's better to refer to new strings in the 2DA files (even though finding them is a lot of work when making a global change, such as &amp;quot;Marabi&amp;quot; to &amp;quot;Dog&amp;quot;. The gender description string does have to be overridden, but since it's only used in character generation, it's not affected by the save-load bug. &lt;br /&gt;
&lt;br /&gt;
3. Agreed. However, the wiki is about practical advice. The section in question talks about deprecating other people's stuff, which is beyond the reader's control! Instead, I suggest a two-pronged approach. Firstly, we already have the Disclaimer section of this article. Secondly, contribute to the [http://social.bioware.com/project/3966/ project] which is developing an FAQ for players. Just my 2 cents. [[User:Proleric1|Proleric1]] 08:33, 4 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
&lt;br /&gt;
On 3, since most players assume that the modder knows best, or are from a game where adding mods can only be done in a specific directory (TES III and TES IV, Fallot 3 and Fallout: New Vegas, just for a few examples), they won't be the ones to complain about having to do that. We should be suggesting the use of modules/Single Player/override for Origins content, addins/&amp;lt;uid&amp;gt;/module/override for things for DLCs (where uid is the folder name of the specific DLC (I listed several of them in the Module Priority tutorial) instead of packages/core/override if a mod '''must''' use the override. The only mods that need to be done this way are compatibility files for various mods that might be editing the same files, at least as far as I'm concerned; everything else should be done as dazips. [[User:Ladydesire|Ladydesire]] 23:26, 6 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Just on the term &amp;quot;deprecated&amp;quot;, this is really a technical term in software development and deployment, and does not carry a value judgement. It simply means a superseded method that should no longer be used. This is a developer not a player wiki, and the use of the term is entirely appropriate, imho --[[User:Gaxkang55|Gaxkang55]] 07:56, 8 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
OK I had a go at rewording, to emphasise that it is the technique which is deprecated, not the mods. Only players have the power to deprecate (i.e. cease using and/or archive) mods, which I've reiterated in the form of a link to the Disclaimer section. What do you think? &lt;br /&gt;
&lt;br /&gt;
@ladydesire : you might want to do an edit to capture your thoughts above. I don't disagree, but you know a lot more than I about how to mod the OC.&lt;br /&gt;
[[User:Proleric1|Proleric1]] 11:43, 8 January 2011 (UTC)&lt;br /&gt;
--------------&lt;br /&gt;
That edit looks fine to me. &lt;br /&gt;
&lt;br /&gt;
On the separate issue of what should be in the core and what in the module folders of you &amp;lt;uid&amp;gt; folder, I am actually scheduled to do some testing on this very question for my own campaign (in dev), and will return to this issue for this page in a week or two --[[User:Gaxkang55|Gaxkang55]] 08:26, 10 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Follower_tutorial&amp;diff=15508</id>
		<title>Talk:Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Follower_tutorial&amp;diff=15508"/>
				<updated>2011-01-10T08:19:53Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Handling followers more robustly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Handling followers more robustly ==&lt;br /&gt;
&lt;br /&gt;
Just a few things&lt;br /&gt;
* I don't think the described behaviour is a bug in [[UT_HireFollower]](). It's documented that &amp;quot;This function will do nothing for plot followers&amp;quot;. It was never intended for use with normal followers, and the code even checks the object tag against the single player campaign's companions. It'll fail to check against your own module's custom followers, though, so it'll do something, but that something isn't always what you want either.&lt;br /&gt;
&lt;br /&gt;
* Plot script gen00pt_party.nss and party_h have some plot-companion handling functions. I wouldn't really give it a short treatment at the bottom under &amp;quot;Advanced Follower Creation&amp;quot; if it's a solid approach. See things like Party_GetFollowerByTag in party_h with an interesting function and comment:&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
object Party_GetFollowerByTag(string sTag)&lt;br /&gt;
{&lt;br /&gt;
    // We have to retrieve the follower like this. Trying to do it with&lt;br /&gt;
    // GetObjectByTag proved to mess up lots of stuff. -- yaron.&lt;br /&gt;
    object [] arParty = GetPartyPoolList();&lt;br /&gt;
    int i;&lt;br /&gt;
    int nSize = GetArraySize(arParty);&lt;br /&gt;
    object oCurrent;&lt;br /&gt;
    for(i = 0; i &amp;lt; nSize; i++)&lt;br /&gt;
    {&lt;br /&gt;
        oCurrent = arParty[i];&lt;br /&gt;
        if(GetTag(oCurrent) == sTag)&lt;br /&gt;
            return oCurrent;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return UT_GetNearestObjectByTag(GetMainControlled(), sTag, TRUE);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* It's probably worth going through those scripts and adapting them for general tutorial use. That way we can benefit from whatever gotchas have already been solved.&lt;br /&gt;
&lt;br /&gt;
--[[User:FollowTheGourd|FollowTheGourd]] 17:52, 1 January 2011 (UTC)&lt;br /&gt;
-------------------&lt;br /&gt;
As the author of the &amp;quot;alternative approach&amp;quot; section, my own view is that this should effectively replace that whole section with the monstrous hire script, which really belongs in a how-I-did-it page rather than in a tutorial. However, I am currently up to my armpits in work on my own mod and just don't  currently have the bandwidth to undertake the redraft. --[[User:Gaxkang55|Gaxkang55]] 04:10, 8 January 2011 (UTC)&lt;br /&gt;
-------------------&lt;br /&gt;
I have some sympathy with that. Indeed, I suspect that most of the additions could be integrated into one &amp;quot;best practice&amp;quot; approach. However, I hesitate to carve this up without some informed debate. I'll volunteer to redraft if a few people are willing to join a group discussion first. [[User:Proleric1|Proleric1]] 12:06, 8 January 2011 (UTC)&lt;br /&gt;
-------------------&lt;br /&gt;
Would be happy to be part of the discussion. Perhaps FollowTheGourd might join the party as well :-) --[[User:Gaxkang55|Gaxkang55]] 08:19, 10 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
== ==&lt;br /&gt;
&lt;br /&gt;
great tutorial. my only problem is: my companion, Erik has different skills and doesn't seem to follow his autolevel template. --[[User:Mono0x32440|Mono0x32440]] 17:46, 25 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Follower's Portrait ==&lt;br /&gt;
&lt;br /&gt;
I cannot figure out how to change the default grey backgrounded portrait for the new followers. It would be nice to have pose and background options.&lt;br /&gt;
&lt;br /&gt;
== Dog equipment slots ==&lt;br /&gt;
&lt;br /&gt;
Mention should be made of the fact that a dog follower needs to have the appropriate equipment slot mask. I will make the addition to the text if no-one has any objections/suggestions in a couple of days. --[[User:Gaxkang55|Gaxkang55]] 09:38, 21 October 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think that happened, so I've done it now. [[User:Proleric1|Proleric1]] 10:12, 2 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15452</id>
		<title>Talk:Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15452"/>
				<updated>2011-01-08T07:56:13Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource scope edit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What if my mod extends both Single Player and Awakening? ==&lt;br /&gt;
&lt;br /&gt;
I moved this section here because it's under discussion. [[User:Proleric1|Proleric1]] 08:27, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
-------------&lt;br /&gt;
NOTE:&lt;br /&gt;
&lt;br /&gt;
There is an easier way than creating two scripts. Just put the information for both in the manifest.xml file. For one of my mods, the manifest file looked like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Manifest Type=&amp;quot;AddIn&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;AddInsList&amp;gt;&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Description DefaultText=&amp;quot;ELF the pet cat adds a 'Cat Toy' to the players inventory (rest of text deleted for brevity)&lt;br /&gt;
&lt;br /&gt;
((This package will work in both DAO and Awakening!))&amp;quot;&amp;gt;&amp;lt;/Description&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;packages/&amp;quot; Type=&amp;quot;package&amp;quot;/&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;/AddInsList&amp;gt;&lt;br /&gt;
&amp;lt;/Manifest&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
doing this allowed users to install one package (using DAModder) which worked for both awakening and DAO.&lt;br /&gt;
&lt;br /&gt;
============== ++ Angel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@monkeysnest - good to have the update concerning the manifest. A few queries:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the article would be clearer if you explained which line has to change, rather than reproduce the entire manifest here?&lt;br /&gt;
&lt;br /&gt;
* Would DAUpdater work? I don't see DAModder listed as a project download on the Bioware social site.&lt;br /&gt;
&lt;br /&gt;
* We don't normally leave our signatures on the content pages of a wiki.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
[[User:Proleric1|Proleric1]] 05:47, 8 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think the &amp;quot;dual entry, single manifest&amp;quot; approach should be followed or encouraged.  Creating two separate .dazip installations as mentioned in [[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | Compatibility: What if my mod extends both Single Player and Awakening?]] is IMHO the preferred approach.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nukenin|Nukenin]] 00:24, 24 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I'll have to agree with Nukenin here, especially since using the &amp;quot;dual entry, single manifest&amp;quot; approach will cause DAUpdater to crash and would unnecessarily force players to use third-party apps. Moreover, it's perfectly possible to include several addons (each one with its own manifest entry) in a single dazip package :&lt;br /&gt;
* Package root&lt;br /&gt;
** Manifest including several AddInItem elements&lt;br /&gt;
** Contents&lt;br /&gt;
*** addins&lt;br /&gt;
**** addin_uid1&lt;br /&gt;
**** addin_uid2&lt;br /&gt;
**** addin_uid3&lt;br /&gt;
**** etc&lt;br /&gt;
*** packages&lt;br /&gt;
&lt;br /&gt;
--[[User:Phaenan|Phaenan]] 06:45, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I find myself agreeing with Phaenan and Nukenin on this; end users should only use community created tools if they want a specific function that's only available to them that way (like the ability to uninstall a dazip). &lt;br /&gt;
[[User:Ladydesire|Ladydesire]] 18:40, 25 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Override Events while minimizing compat issues.. ==&lt;br /&gt;
&lt;br /&gt;
I believe this may be useful to others - through trial and error, and with some help, I have figured out a way to override events only when my module is running - I had to add a variable to var_module.xls/gda (which is probably where the only potential compatibility issue will arise via string ID, though I am not sure what would happen if someone tried to override the same events - depends on which engineevents get's loaded last I suppose...).&lt;br /&gt;
&lt;br /&gt;
The variable is defaulted to a 0....in my modules properties, I set the variable to a 1. My event overrides check for this variable to be == 1, if not, send it off the proper handler. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See the following post where I came to this 'workaround'...would love to know if there is a better way:&lt;br /&gt;
&lt;br /&gt;
http://social.bioware.com/forum/1/topic/8/index/2371093/1#2531362&lt;br /&gt;
&lt;br /&gt;
== Resource scope edit ==&lt;br /&gt;
&lt;br /&gt;
I have removed the reference to tint maps following the discussion at http://social.bioware.com/group/2937/discussion/12738/ .&lt;br /&gt;
&lt;br /&gt;
Also beefed up the recommendations about not putting files into packages --[[User:Gaxkang55|Gaxkang55]] 12:43, 30 December 2010 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Good update! I'm very much on the same wavelength. I have one question, though, concerning the Talk Table. Normally, the best way to change a core string is to make a new one, then point the appropriate 2DA at it. However, there are cases where no such mechanism exists. For example, if you want to make a module that isn't set in the Ferelden gameworld, you need to change the gender descriptions, replace all instances of &amp;quot;marabi&amp;quot; with &amp;quot;dog&amp;quot; and so on. To the best of my knowledge, this can't be done without an override - see [[String_editor]]. If there's a better solution, I'd be keen to hear it. [[User:Proleric1|Proleric1]] 08:50, 31 December 2010 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
As it happens, I had to do exactly that for the campaign I have in development, where I wanted to override the gender description. Create the string but make the Owner Module your module. This will be exported to the talktable placed in your core, and will overwrite the core string as long as your module is enabled. Also tested the head morph stuff, and that doesn't need to be in packages either, so will make a further update. --[[User:Gaxkang55|Gaxkang55]] 04:28, 3 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Have you tried to reproduce this [[Bug:_Talk_table_exported_to_packages_override | bug]] for the specific string mentioned there? I double-checked that the Owner Module is set correctly. It isn't exported to the talk table in core (which seems to be empty), nor does it work if the talk table in packages override is moved to any of the add-in folders.&lt;br /&gt;
&lt;br /&gt;
A couple of other issues:&lt;br /&gt;
&lt;br /&gt;
You recommend moving content from the override folders before B2P packaging. Is there any technical reason for that? I haven't heard this from Bioware. &amp;quot;If it ain't bust, don't fix it&amp;quot; might apply here? &lt;br /&gt;
&lt;br /&gt;
You've added some strong words about mods that use packages override. My heart is with you, but my head says the tone could be counter-productive. We seem to be making some progress with persuading the community that compatibility is important, but the &amp;quot;package overriders&amp;quot; are still in the majority. IMO we need to convince them to change their approach voluntarily, not antagonise them. After all, none of us has the power to deprecate anything (nor would we wish to have it). What do you think? [[User:Proleric1|Proleric1]] 08:27, 3 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Moving the compiled scripts and exported plots out of the toolsetexport folder '''into''' the override folder is a good idea, since when doing an &amp;quot;empty export directories&amp;quot;, you could accidently delete files needed for the builder to player package. I'm not sure why it would be necessary to move files out of the override folder.&lt;br /&gt;
&lt;br /&gt;
As far as the &amp;quot;package overriders&amp;quot; go, some may never change, no matter what we do; I have even seen people that were doing it basically the right way change because they weren't wanting to build multiple packages for their mods. [[User:Ladydesire|Ladydesire]] 00:03, 4 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
1. I have deleted the sentence about DAZIPs. On re-reading it actually compresses together two different ideas, and in any case doesn't really belong there. I will have a rethink about this when I have a bit more time on the weekend :-)&lt;br /&gt;
&lt;br /&gt;
2. Proleric, the string I override is the gender description string 377283. I export the talktable (which creates the three files) and delete the one in packages, ''core_en-us.tlk'', together with everything else there). Start my game and the string in overwritten correctly by the ''&amp;lt;uid&amp;gt;_c_en-us.tlk'' table.&lt;br /&gt;
&lt;br /&gt;
3. On the issue of packages override, the issue is whether or not this wiki contains correct information and procedures. If someone disagrees that this is the correct procedure (particularly in terms of mod inter-compatibility), I am more than happy to have the discussion. I suspect real change is only going to happen if the end-users start complaining in the comments sections of the download pages, but that's another story. In the meantime, the wiki should stick to the straight and narrow of providing the best information we can assemble --[[User:Gaxkang55|Gaxkang55]] 04:37, 4 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
1. Thanks.&lt;br /&gt;
&lt;br /&gt;
2. Issue closed. EDIT [[User:Proleric1|Proleric1]] 17:16, 4 January 2011 (UTC) It is not necessary to put a talk table in packages override. Instead of changing core strings, it's better to refer to new strings in the 2DA files (even though finding them is a lot of work when making a global change, such as &amp;quot;Marabi&amp;quot; to &amp;quot;Dog&amp;quot;. The gender description string does have to be overridden, but since it's only used in character generation, it's not affected by the save-load bug. &lt;br /&gt;
&lt;br /&gt;
3. Agreed. However, the wiki is about practical advice. The section in question talks about deprecating other people's stuff, which is beyond the reader's control! Instead, I suggest a two-pronged approach. Firstly, we already have the Disclaimer section of this article. Secondly, contribute to the [http://social.bioware.com/project/3966/ project] which is developing an FAQ for players. Just my 2 cents. [[User:Proleric1|Proleric1]] 08:33, 4 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
&lt;br /&gt;
On 3, since most players assume that the modder knows best, or are from a game where adding mods can only be done in a specific directory (TES III and TES IV, Fallot 3 and Fallout: New Vegas, just for a few examples), they won't be the ones to complain about having to do that. We should be suggesting the use of modules/Single Player/override for Origins content, addins/&amp;lt;uid&amp;gt;/module/override for things for DLCs (where uid is the folder name of the specific DLC (I listed several of them in the Module Priority tutorial) instead of packages/core/override if a mod '''must''' use the override. The only mods that need to be done this way are compatibility files for various mods that might be editing the same files, at least as far as I'm concerned; everything else should be done as dazips. [[User:Ladydesire|Ladydesire]] 23:26, 6 January 2011 (UTC)&lt;br /&gt;
-------------&lt;br /&gt;
Just on the term &amp;quot;deprecated&amp;quot;, this is really a technical term in software development and deployment, and does not carry a value judgement. It simply means a superseded method that should no longer be used. This is a developer not a player wiki, and the use of the term is entirely appropriate, imho --[[User:Gaxkang55|Gaxkang55]] 07:56, 8 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Follower_tutorial&amp;diff=15451</id>
		<title>Talk:Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Follower_tutorial&amp;diff=15451"/>
				<updated>2011-01-08T04:10:02Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Handling followers more robustly */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Handling followers more robustly ==&lt;br /&gt;
&lt;br /&gt;
Just a few things&lt;br /&gt;
* I don't think the described behaviour is a bug in [[UT_HireFollower]](). It's documented that &amp;quot;This function will do nothing for plot followers&amp;quot;. It was never intended for use with normal followers, and the code even checks the object tag against the single player campaign's companions. It'll fail to check against your own module's custom followers, though, so it'll do something, but that something isn't always what you want either.&lt;br /&gt;
&lt;br /&gt;
* Plot script gen00pt_party.nss and party_h have some plot-companion handling functions. I wouldn't really give it a short treatment at the bottom under &amp;quot;Advanced Follower Creation&amp;quot; if it's a solid approach. See things like Party_GetFollowerByTag in party_h with an interesting function and comment:&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
object Party_GetFollowerByTag(string sTag)&lt;br /&gt;
{&lt;br /&gt;
    // We have to retrieve the follower like this. Trying to do it with&lt;br /&gt;
    // GetObjectByTag proved to mess up lots of stuff. -- yaron.&lt;br /&gt;
    object [] arParty = GetPartyPoolList();&lt;br /&gt;
    int i;&lt;br /&gt;
    int nSize = GetArraySize(arParty);&lt;br /&gt;
    object oCurrent;&lt;br /&gt;
    for(i = 0; i &amp;lt; nSize; i++)&lt;br /&gt;
    {&lt;br /&gt;
        oCurrent = arParty[i];&lt;br /&gt;
        if(GetTag(oCurrent) == sTag)&lt;br /&gt;
            return oCurrent;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return UT_GetNearestObjectByTag(GetMainControlled(), sTag, TRUE);&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* It's probably worth going through those scripts and adapting them for general tutorial use. That way we can benefit from whatever gotchas have already been solved.&lt;br /&gt;
&lt;br /&gt;
--[[User:FollowTheGourd|FollowTheGourd]] 17:52, 1 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
As the author of the &amp;quot;alternative approach&amp;quot; section, my own view is that this should effectively replace that whole section with the monstrous hire script, which really belongs in a how-I-did-it page rather than in a tutorial. However, I am currently up to my armpits in work on my own mod and just don't  currently have the bandwidth to undertake the redraft. --[[User:Gaxkang55|Gaxkang55]] 04:10, 8 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
== ==&lt;br /&gt;
&lt;br /&gt;
great tutorial. my only problem is: my companion, Erik has different skills and doesn't seem to follow his autolevel template. --[[User:Mono0x32440|Mono0x32440]] 17:46, 25 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Follower's Portrait ==&lt;br /&gt;
&lt;br /&gt;
I cannot figure out how to change the default grey backgrounded portrait for the new followers. It would be nice to have pose and background options.&lt;br /&gt;
&lt;br /&gt;
== Dog equipment slots ==&lt;br /&gt;
&lt;br /&gt;
Mention should be made of the fact that a dog follower needs to have the appropriate equipment slot mask. I will make the addition to the text if no-one has any objections/suggestions in a couple of days. --[[User:Gaxkang55|Gaxkang55]] 09:38, 21 October 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think that happened, so I've done it now. [[User:Proleric1|Proleric1]] 10:12, 2 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15399</id>
		<title>Talk:Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15399"/>
				<updated>2011-01-04T04:37:52Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource scope edit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What if my mod extends both Single Player and Awakening? ==&lt;br /&gt;
&lt;br /&gt;
I moved this section here because it's under discussion. [[User:Proleric1|Proleric1]] 08:27, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
=============== &lt;br /&gt;
NOTE:&lt;br /&gt;
&lt;br /&gt;
There is an easier way than creating two scripts. Just put the information for both in the manifest.xml file. For one of my mods, the manifest file looked like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Manifest Type=&amp;quot;AddIn&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;AddInsList&amp;gt;&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Description DefaultText=&amp;quot;ELF the pet cat adds a 'Cat Toy' to the players inventory (rest of text deleted for brevity)&lt;br /&gt;
&lt;br /&gt;
((This package will work in both DAO and Awakening!))&amp;quot;&amp;gt;&amp;lt;/Description&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;packages/&amp;quot; Type=&amp;quot;package&amp;quot;/&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;/AddInsList&amp;gt;&lt;br /&gt;
&amp;lt;/Manifest&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
doing this allowed users to install one package (using DAModder) which worked for both awakening and DAO.&lt;br /&gt;
&lt;br /&gt;
============== ++ Angel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@monkeysnest - good to have the update concerning the manifest. A few queries:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the article would be clearer if you explained which line has to change, rather than reproduce the entire manifest here?&lt;br /&gt;
&lt;br /&gt;
* Would DAUpdater work? I don't see DAModder listed as a project download on the Bioware social site.&lt;br /&gt;
&lt;br /&gt;
* We don't normally leave our signatures on the content pages of a wiki.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
[[User:Proleric1|Proleric1]] 05:47, 8 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think the &amp;quot;dual entry, single manifest&amp;quot; approach should be followed or encouraged.  Creating two separate .dazip installations as mentioned in [[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | Compatibility: What if my mod extends both Single Player and Awakening?]] is IMHO the preferred approach.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nukenin|Nukenin]] 00:24, 24 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I'll have to agree with Nukenin here, especially since using the &amp;quot;dual entry, single manifest&amp;quot; approach will cause DAUpdater to crash and would unnecessarily force players to use third-party apps. Moreover, it's perfectly possible to include several addons (each one with its own manifest entry) in a single dazip package :&lt;br /&gt;
* Package root&lt;br /&gt;
** Manifest including several AddInItem elements&lt;br /&gt;
** Contents&lt;br /&gt;
*** addins&lt;br /&gt;
**** addin_uid1&lt;br /&gt;
**** addin_uid2&lt;br /&gt;
**** addin_uid3&lt;br /&gt;
**** etc&lt;br /&gt;
*** packages&lt;br /&gt;
&lt;br /&gt;
--[[User:Phaenan|Phaenan]] 06:45, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I find myself agreeing with Phaenan and Nukenin on this; end users should only use community created tools if they want a specific function that's only available to them that way (like the ability to uninstall a dazip). &lt;br /&gt;
[[User:Ladydesire|Ladydesire]] 18:40, 25 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Override Events while minimizing compat issues.. ==&lt;br /&gt;
&lt;br /&gt;
I believe this may be useful to others - through trial and error, and with some help, I have figured out a way to override events only when my module is running - I had to add a variable to var_module.xls/gda (which is probably where the only potential compatibility issue will arise via string ID, though I am not sure what would happen if someone tried to override the same events - depends on which engineevents get's loaded last I suppose...).&lt;br /&gt;
&lt;br /&gt;
The variable is defaulted to a 0....in my modules properties, I set the variable to a 1. My event overrides check for this variable to be == 1, if not, send it off the proper handler. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See the following post where I came to this 'workaround'...would love to know if there is a better way:&lt;br /&gt;
&lt;br /&gt;
http://social.bioware.com/forum/1/topic/8/index/2371093/1#2531362&lt;br /&gt;
&lt;br /&gt;
== Resource scope edit ==&lt;br /&gt;
&lt;br /&gt;
I have removed the reference to tint maps following the discussion at http://social.bioware.com/group/2937/discussion/12738/ .&lt;br /&gt;
&lt;br /&gt;
Also beefed up the recommendations about not putting files into packages --[[User:Gaxkang55|Gaxkang55]] 12:43, 30 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
Good update! I'm very much on the same wavelength. I have one question, though, concerning the Talk Table. Normally, the best way to change a core string is to make a new one, then point the appropriate 2DA at it. However, there are cases where no such mechanism exists. For example, if you want to make a module that isn't set in the Ferelden gameworld, you need to change the gender descriptions, replace all instances of &amp;quot;marabi&amp;quot; with &amp;quot;dog&amp;quot; and so on. To the best of my knowledge, this can't be done without an override - see [[String_editor]]. If there's a better solution, I'd be keen to hear it. [[User:Proleric1|Proleric1]] 08:50, 31 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
As it happens, I had to do exactly that for the campaign I have in development, where I wanted to override the gender description. Create the string but make the Owner Module your module. This will be exported to the talktable placed in your core, and will overwrite the core string as long as your module is enabled. Also tested the head morph stuff, and that doesn't need to be in packages either, so will make a further update. --[[User:Gaxkang55|Gaxkang55]] 04:28, 3 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
Have you tried to reproduce this [[Bug:_Talk_table_exported_to_packages_override | bug]] for the specific string mentioned there? I double-checked that the Owner Module is set correctly. It isn't exported to the talk table in core (which seems to be empty), nor does it work if the talk table in packages override is moved to any of the add-in folders.&lt;br /&gt;
&lt;br /&gt;
A couple of other issues:&lt;br /&gt;
&lt;br /&gt;
You recommend moving content from the override folders before B2P packaging. Is there any technical reason for that? I haven't heard this from Bioware. &amp;quot;If it ain't bust, don't fix it&amp;quot; might apply here? &lt;br /&gt;
&lt;br /&gt;
You've added some strong words about mods that use packages override. My heart is with you, but my head says the tone could be counter-productive. We seem to be making some progress with persuading the community that compatibility is important, but the &amp;quot;package overriders&amp;quot; are still in the majority. IMO we need to convince them to change their approach voluntarily, not antagonise them. After all, none of us has the power to deprecate anything (nor would we wish to have it). What do you think? [[User:Proleric1|Proleric1]] 08:27, 3 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
Moving the compiled scripts and exported plots out of the toolsetexport folder '''into''' the override folder is a good idea, since when doing an &amp;quot;empty export directories&amp;quot;, you could accidently delete files needed for the builder to player package. I'm not sure why it would be necessary to move files out of the override folder.&lt;br /&gt;
&lt;br /&gt;
As far as the &amp;quot;package overriders&amp;quot; go, some may never change, no matter what we do; I have even seen people that were doing it basically the right way change because they weren't wanting to build multiple packages for their mods. [[User:Ladydesire|Ladydesire]] 00:03, 4 January 2011 (UTC)&lt;br /&gt;
&lt;br /&gt;
1. I have deleted the sentence about DAZIPs. On re-reading it actually compresses together two different ideas, and in any case doesn't really belong there. I will have a rethink about this when I have a bit more time on the weekend :-)&lt;br /&gt;
&lt;br /&gt;
2. Proleric, the string I override is the gender description string 377283. I export the talktable (which creates the three files) and delete the one in packages, ''core_en-us.tlk'', together with everything else there). Start my game and the string in overwritten correctly by the ''&amp;lt;uid&amp;gt;_c_en-us.tlk'' table.&lt;br /&gt;
&lt;br /&gt;
3. On the issue of packages override, the issue is whether or not this wiki contains correct information and procedures. If someone disagrees that this is the correct procedure (particularly in terms of mod inter-compatibility), I am more than happy to have the discussion. I suspect real change is only going to happen if the end-users start complaining in the comments sections of the download pages, but that's another story. In the meantime, the wiki should stick to the straight and narrow of providing the best information we can assemble --[[User:Gaxkang55|Gaxkang55]] 04:37, 4 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15398</id>
		<title>Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15398"/>
				<updated>2011-01-04T04:08:32Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource Scope */ deleted sentence pending further discussion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DAO has an active modding community. Over time, players will accumulate many new campaigns and game mods. So, as a courtesy to players and other builders, it's helpful to try to make our mods mutually compatible. &lt;br /&gt;
&lt;br /&gt;
From time to time, Bioware may well issue new releases, so it's good to reduce the risk of conflict in that respect, too. &lt;br /&gt;
&lt;br /&gt;
Since we can't be sure that all authors will respect compatibility considerations, the emphasis here is on techniques that reduce the risk of conflict, regardless of what other people do (though not all are foolproof).&lt;br /&gt;
&lt;br /&gt;
Obviously, there are some conflicts with no win-win (hurlocks can't be both green and purple at the same time), but that doesn't stop us trying to avoid unnecessary win-lose or corruption.&lt;br /&gt;
&lt;br /&gt;
We begin with a concrete example - a tutorial on script conflict in OC mods, which is one of the most common problems to avoid. The remainder of the page is a more systematic discussion, which applies to both OC mods and custom campaigns.    &lt;br /&gt;
&lt;br /&gt;
== Tutorial to ensure your Awakening mod will not break Origins and vice versa!!! (includes screenshots and script code) ==&lt;br /&gt;
&lt;br /&gt;
I'm hoping to save my modding friends some time. (Tutorial by Immortality)&lt;br /&gt;
&lt;br /&gt;
'''Remember: IT'S YOUR RESPONSIBILITY TO ENSURE YOUR MOD DOES NOT BREAK THE GAME, THE EXPANSION, DLCS, OR OTHER MODS!!'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The problem:'''''&lt;br /&gt;
&lt;br /&gt;
- While working in my Origins mod, and then on my Awakening mod, I realized that my Origins mod was breaking Awakening (scripts were not triggering, and even objects were moving around!).&lt;br /&gt;
&lt;br /&gt;
- In the same way, my mod for Awakening was interfeering in Origins, breaking it (wrong scripts triggering, destroying the party recruiting).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The objective:'''''&lt;br /&gt;
&lt;br /&gt;
- Prevent the Origins mod to interfere with Awakening. If your mod is for Origins, it should only work in Origins.&lt;br /&gt;
&lt;br /&gt;
- Prevent the Awakening mod to interfere with Origins. If your mod is for Awakening, it should only work in Awakening.&lt;br /&gt;
&lt;br /&gt;
- If you have one mod for both, to ensure that the Origins part triggers in Origins and Awakening part in Awakening.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Procedure:'''''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''1- Ensure your Origins mod is for Origins only!'''&lt;br /&gt;
&lt;br /&gt;
NEVER EVER EVER set your core scripts or handling scripts as Core Game Resources. NEVER!&lt;br /&gt;
&lt;br /&gt;
There's absolutely no need for your scripts (especially your module core) to be a core game resource.&lt;br /&gt;
&lt;br /&gt;
This means that whenever you create a mod for origins you should always set the properties of your major handling scripts as &amp;quot;Module: your module&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. NEVER as a core game resource. Otherwise they will interfere with awakening and will break it (make no mistake, they will).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
This is how you set your Origins module: [[image:Originshierarchy.jpg]]&lt;br /&gt;
&lt;br /&gt;
This is how you set all your script's properties: [[image:Originsproperties.jpg]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2- Ensure your Awakening mod is for Awakening only!'''&lt;br /&gt;
&lt;br /&gt;
Things are different for Awakening because you DO have to set all your materials' properties as &amp;quot;Module: Core Game Resources&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. (read the tutorial if you need to know more: http://social.bioware.com/53295/blog/10858/ )&lt;br /&gt;
&lt;br /&gt;
This means that your Awakening mod will interfere with Origins and will break the game.&lt;br /&gt;
&lt;br /&gt;
Use IsUsingEP1Resources() [returns TRUE or FALSE] as the preferred method of ensuring your scripts apply to the correct campaign. Origins code itself has a lot of code that was written for Awakening and in all cases, Bioware uses this function to check if Awakening is being used or not.&lt;br /&gt;
&lt;br /&gt;
'''Addendum:''' If you have copy-pasted scripts, for example your follower join script, it can still mess your Origins mod, even with the checks implemented!!!&lt;br /&gt;
&lt;br /&gt;
In order to avoid this, you can rename your functions.&lt;br /&gt;
For example, if your Origins script has the function &amp;quot;SetFollowerInParty&amp;quot;, then rename the function in your Awakening script to &amp;quot;SetFollowerInParty_awakening&amp;quot;, and etc.&lt;br /&gt;
&lt;br /&gt;
== Disable Add-Ins : Suggested Disclaimer ==&lt;br /&gt;
&lt;br /&gt;
If the player disables all other add-ins on the in game DLC screen, no conflict should occur between them. Tedious, but effective.&lt;br /&gt;
&lt;br /&gt;
This should rarely be necessary if the compatibility guidelines listed here are observed.&lt;br /&gt;
&lt;br /&gt;
Exception : there is a [[Bug:_export_creates_unnecessary_core_override | toolset bug]] which produces content that persists in game, even when the add-in is disabled, unless the builder cleans it out before making the Builder-to-Player file. The same problem can occur if a builder has intentionally placed content in the packages\override folder (which should normally be avoided, as it is very rarely necessary).&lt;br /&gt;
&lt;br /&gt;
Mod authors can work together to set player expectations in this respect. For example, the installation instructions might say &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;Reasonable steps have been taken to make this mod compatible. &lt;br /&gt;
Obviously, the author has no control over the quality of other mods you may have installed. &lt;br /&gt;
So, to reduce the risk of conflict, you are are strongly advised to move all files out of your &lt;br /&gt;
packages\override folders, and consider disabling unnecessary community mods on your in-game &lt;br /&gt;
DLC screen, before playing.&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Module Scope ==&lt;br /&gt;
&lt;br /&gt;
Setting the Extended Module in Module properties to &amp;quot;Core Game Resources&amp;quot; means that the add-in will change every campaign in game. If that's not intended, select the campaign you're trying to extend e.g. Single Player for the official campaign, (None) for a new standalone campaign.&lt;br /&gt;
&lt;br /&gt;
[[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | What if my mod extends both Single Player and Awakening?]]&lt;br /&gt;
&lt;br /&gt;
== Resource Scope ==&lt;br /&gt;
&lt;br /&gt;
By default, the toolset exports design resources to your addin's module override folder. That's a good thing, because it ensures that the scope of the resources is confined to your addin (and any that extend it). There's less risk of corrupting other people's work that way.&lt;br /&gt;
&lt;br /&gt;
Never put resources in the packages folder, because that impacts every campaign. Also, once a player has installed resources there, they persist, even when your add-in is disabled. There are currently no resources known which need to be in the packages folder in order to work.&lt;br /&gt;
&lt;br /&gt;
Normally, it's not a good idea to make new core resources. It's easy to make a new core resource accidentally when duplicating an official core resource, because the Owner Module defaults to core. This isn't obvious, but the resource will export to your addin's core override folder. Exception : items cannot be imported to a new campaign with the player character unless the template is included in both campaigns. One way of doing that is to make it a core resource.   &lt;br /&gt;
&lt;br /&gt;
Art resources posted to local are always sent to the module's core override folder. Fortunately, the core override folder only affects the campaign extended (if any), the addin and any that extend it. Most of those resources can, and should be, moved to the module folder and still work. The only exceptions are resources intended to overwrite a core game resouce.&lt;br /&gt;
&lt;br /&gt;
There are a large number of mods available that use the packages folder, creating headaches for other modders and often users since such overwrites cannot be turned off in the game GUI. Users should be told to avoid mods whose method of installation is &amp;quot;place this folder in packages\override&amp;quot; and to delete any content that is currently in that folder. Mods not properly organised into dazips and installed with the Bioware supplied daupdater should also be deprecated, unless a good reason is given why they are being distributed that way.&lt;br /&gt;
&lt;br /&gt;
== Resource Conflict ==&lt;br /&gt;
&lt;br /&gt;
Resource names need to be unique within type. For example, genpt_party.plt and genpt_party.nss are different resources, becasue the type is different. However, if two modules both have resources called genpt_party.plt, only one will load in game, following the [[Source directory priorities]]. &lt;br /&gt;
&lt;br /&gt;
Within the toolset database, duplicate resource names are forbidden, but there's nothing to stop different builders making resources which accidentally conflict, so it's wise to choose a unique range of names. Each builder can register the prefix they require. See [[Naming_conventions#Resource_Naming_Convention | Resource Naming Convention]] and especially [[Prefixes in use]].&lt;br /&gt;
&lt;br /&gt;
It is possible to override a core resource intentionally, by editing a copy, exporting it, and renaming it in the export folder to the same name as the original. However, almost invariably there is a cleaner way of doing this - for example, by changing the 2DA which identifies which resource to use.&lt;br /&gt;
 &lt;br /&gt;
== Existing Content Modification ==&lt;br /&gt;
&lt;br /&gt;
When adding new content or content hooks to existing areas, do not modify the area directly and deploy the modified area as an override with your mod. This is incompatible with other mods trying to edit the same area since only one modified version of the area will &amp;quot;win&amp;quot;, and changes made by other mods to that area will not be available. Instead, use the [[PRCSCR]] system to add new content to existing areas.&lt;br /&gt;
&lt;br /&gt;
== 2DA Conflict ==&lt;br /&gt;
&lt;br /&gt;
Conflict between 2DA mods can be reduced using the [[2DA#Extending_the_game_via_M2DAs | M2DA]] mechanism and [[2DA#Reserved_ID_Ranges_and_overriding_existing_rows | reserving ID ranges]].&lt;br /&gt;
&lt;br /&gt;
2DA mods should normally be placed in the add-in's module folder. Exception : if they are meant to be universally applied to all campaigns, they should be in the addin/core/override folder. The packages override folder should normally be avoided (because that removes control from the player, by forcing the 2DA to load even if the player has disabled the add-in).&lt;br /&gt;
&lt;br /&gt;
== String Conflict ==&lt;br /&gt;
&lt;br /&gt;
When a new module is created, its properties include a [[String ID]] range which starts at a very large random number. This makes it very unlikely that text created by one add-in will override another.&lt;br /&gt;
&lt;br /&gt;
See [[String ID]] main article for a discussion of how this impacts sharing between Builders.&lt;br /&gt;
&lt;br /&gt;
The [[String editor]] article discusses techniques for editing strings which are outside of the module's normal range. It is not normally necessary to customise core strings directly, but if there is no alternative, change the Owner Module to the current module, and the Table to the current module's talk table. Otherwise, the custom string will override all campaigns.&lt;br /&gt;
&lt;br /&gt;
== Event Handling Conflict ==&lt;br /&gt;
&lt;br /&gt;
Bear in mind that an add-in which impacts all campaigns could have undesirable consequences if it changes scripts or event-handling, given that custom campaigns may well have made changes of their own. If in doubt, consider modding the Single Player campaign only.&lt;br /&gt;
&lt;br /&gt;
See [[Event_override | event override]] for recommended methods of intercepting events.&lt;br /&gt;
&lt;br /&gt;
Note that script resources are never overwritten in these methods. Conceptually, the event is intercepted by a custom script, then passed on (unless the event has been handled successfully and further processing would be harmful). In this way, mods try not to interfere unnecessarily with other scripts.&lt;br /&gt;
&lt;br /&gt;
Given the variety of actions that can be taken in a script, and that fact that one mod can't know what other mods are trying to do, we can't guarantee that this approach will be entirely free of logical problems, but the Perfect is the enemy of the Good. &lt;br /&gt;
&lt;br /&gt;
The simplest and safest method is to assign a custom event script to a resource. This is likely to be used by custom campaigns, and also by Single Player mods to specific resources, as it is the approach that Bioware devs have often recommended.  &lt;br /&gt;
&lt;br /&gt;
Mods which aim to impact all campaigns globally are better advised to use the second method, i.e. overriding [[Event_(dascript_type) | event]] handling using an Events M2DA. As illustrated in the example script, if possible the event should be passed on to the default handler of the event's target object (which might be a custom event script). In this way, a global mod can be compatible with custom campaigns and specific resource mods. &lt;br /&gt;
&lt;br /&gt;
Unfortunately, if two mods simply try to override the same event with an M2DA, they will be incompatible.&lt;br /&gt;
&lt;br /&gt;
The best solution to override, partially override, or just listen for events via M2DA at this point would be to use a system such as [http://social.bioware.com/project/1907/#details Event Manager], though to ensure compatibility all modules overriding or listening for events should also be using the same system.&lt;br /&gt;
&lt;br /&gt;
In the case of modules trying to totally override an event, only one module that does so will ultimately &amp;quot;win&amp;quot; (no such modules can ever truly be compatible with one another short of merging their functionality into one unified module as possible), but utilizing a system such as Event Manager will allow modules to partially override an event (i.e. only handle the event in certain situations), and will allow any module to listen for an event (without handling it) before or after the event is handled.&lt;br /&gt;
&lt;br /&gt;
== Plot Property ==&lt;br /&gt;
&lt;br /&gt;
Scripts that impact all campaigns should respect the plot property on resources. For example, if a campaign author has flagged an NPC as plot, it might not be helpful to change the creature AI.&lt;br /&gt;
&lt;br /&gt;
== Open Source ==&lt;br /&gt;
&lt;br /&gt;
If mod authors choose to publish their source code, with no restrictions on re-deployment, other builders can work around any residual incompatibilities (either by understanding the conflict more clearly, or by integrating the mod into their own work).&lt;br /&gt;
&lt;br /&gt;
This technical wiki is not the place to discuss any legal or ethical considerations.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== What if my mod extends both Single Player and Awakening? ===&lt;br /&gt;
&lt;br /&gt;
Just create two dazips for your module. Name one yourprefix_yourmodule_version and the other yourprefix_yourmodule_EP1_version.&lt;br /&gt;
&lt;br /&gt;
Edit the Manifest.xml file inside  yourprefix_yourmodule_EP_1_version.dazip.&lt;br /&gt;
Change the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt; to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule_EP_1&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;200&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Talk:Compatibility | Discussion]]&lt;br /&gt;
&lt;br /&gt;
=== How can I import an item with my existing character to a new campaign? ===&lt;br /&gt;
&lt;br /&gt;
The Awakening expansion allows an existing character to be imported from one campaign to another.&lt;br /&gt;
&lt;br /&gt;
There are two methods of ensuring that an item in the player's inventory is imported successfully:&lt;br /&gt;
&lt;br /&gt;
* Make the item a core resource&lt;br /&gt;
* Include the item template in separate add-ins to both campaigns (see Awakening example above)&lt;br /&gt;
&lt;br /&gt;
=== How can I stop items being imported into my campaign? ===&lt;br /&gt;
&lt;br /&gt;
Assuming your campaign allows existing characters to be imported during Character Generation, you might want to clear the player's inventory before adding your starting equipment. Imported equipment might upset the balance of your campaign.&lt;br /&gt;
&lt;br /&gt;
If you decide to do this, it's a good idea to warn players, so that they understand what's happening.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15385</id>
		<title>Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15385"/>
				<updated>2011-01-03T04:40:51Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource Scope */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DAO has an active modding community. Over time, players will accumulate many new campaigns and game mods. So, as a courtesy to players and other builders, it's helpful to try to make our mods mutually compatible. &lt;br /&gt;
&lt;br /&gt;
From time to time, Bioware may well issue new releases, so it's good to reduce the risk of conflict in that respect, too. &lt;br /&gt;
&lt;br /&gt;
Since we can't be sure that all authors will respect compatibility considerations, the emphasis here is on techniques that reduce the risk of conflict, regardless of what other people do (though not all are foolproof).&lt;br /&gt;
&lt;br /&gt;
Obviously, there are some conflicts with no win-win (hurlocks can't be both green and purple at the same time), but that doesn't stop us trying to avoid unnecessary win-lose or corruption.&lt;br /&gt;
&lt;br /&gt;
We begin with a concrete example - a tutorial on script conflict in OC mods, which is one of the most common problems to avoid. The remainder of the page is a more systematic discussion, which applies to both OC mods and custom campaigns.    &lt;br /&gt;
&lt;br /&gt;
== Tutorial to ensure your Awakening mod will not break Origins and vice versa!!! (includes screenshots and script code) ==&lt;br /&gt;
&lt;br /&gt;
I'm hoping to save my modding friends some time. (Tutorial by Immortality)&lt;br /&gt;
&lt;br /&gt;
'''Remember: IT'S YOUR RESPONSIBILITY TO ENSURE YOUR MOD DOES NOT BREAK THE GAME, THE EXPANSION, DLCS, OR OTHER MODS!!'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The problem:'''''&lt;br /&gt;
&lt;br /&gt;
- While working in my Origins mod, and then on my Awakening mod, I realized that my Origins mod was breaking Awakening (scripts were not triggering, and even objects were moving around!).&lt;br /&gt;
&lt;br /&gt;
- In the same way, my mod for Awakening was interfeering in Origins, breaking it (wrong scripts triggering, destroying the party recruiting).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The objective:'''''&lt;br /&gt;
&lt;br /&gt;
- Prevent the Origins mod to interfere with Awakening. If your mod is for Origins, it should only work in Origins.&lt;br /&gt;
&lt;br /&gt;
- Prevent the Awakening mod to interfere with Origins. If your mod is for Awakening, it should only work in Awakening.&lt;br /&gt;
&lt;br /&gt;
- If you have one mod for both, to ensure that the Origins part triggers in Origins and Awakening part in Awakening.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Procedure:'''''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''1- Ensure your Origins mod is for Origins only!'''&lt;br /&gt;
&lt;br /&gt;
NEVER EVER EVER set your core scripts or handling scripts as Core Game Resources. NEVER!&lt;br /&gt;
&lt;br /&gt;
There's absolutely no need for your scripts (especially your module core) to be a core game resource.&lt;br /&gt;
&lt;br /&gt;
This means that whenever you create a mod for origins you should always set the properties of your major handling scripts as &amp;quot;Module: your module&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. NEVER as a core game resource. Otherwise they will interfere with awakening and will break it (make no mistake, they will).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
This is how you set your Origins module: [[image:Originshierarchy.jpg]]&lt;br /&gt;
&lt;br /&gt;
This is how you set all your script's properties: [[image:Originsproperties.jpg]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2- Ensure your Awakening mod is for Awakening only!'''&lt;br /&gt;
&lt;br /&gt;
Things are different for Awakening because you DO have to set all your materials' properties as &amp;quot;Module: Core Game Resources&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. (read the tutorial if you need to know more: http://social.bioware.com/53295/blog/10858/ )&lt;br /&gt;
&lt;br /&gt;
This means that your Awakening mod will interfere with Origins and will break the game.&lt;br /&gt;
&lt;br /&gt;
Use IsUsingEP1Resources() [returns TRUE or FALSE] as the preferred method of ensuring your scripts apply to the correct campaign. Origins code itself has a lot of code that was written for Awakening and in all cases, Bioware uses this function to check if Awakening is being used or not.&lt;br /&gt;
&lt;br /&gt;
'''Addendum:''' If you have copy-pasted scripts, for example your follower join script, it can still mess your Origins mod, even with the checks implemented!!!&lt;br /&gt;
&lt;br /&gt;
In order to avoid this, you can rename your functions.&lt;br /&gt;
For example, if your Origins script has the function &amp;quot;SetFollowerInParty&amp;quot;, then rename the function in your Awakening script to &amp;quot;SetFollowerInParty_awakening&amp;quot;, and etc.&lt;br /&gt;
&lt;br /&gt;
== Disable Add-Ins : Suggested Disclaimer ==&lt;br /&gt;
&lt;br /&gt;
If the player disables all other add-ins on the in game DLC screen, no conflict should occur between them. Tedious, but effective.&lt;br /&gt;
&lt;br /&gt;
This should rarely be necessary if the compatibility guidelines listed here are observed.&lt;br /&gt;
&lt;br /&gt;
Exception : there is a [[Bug:_export_creates_unnecessary_core_override | toolset bug]] which produces content that persists in game, even when the add-in is disabled, unless the builder cleans it out before making the Builder-to-Player file. The same problem can occur if a builder has intentionally placed content in the packages\override folder (which should normally be avoided, as it is very rarely necessary).&lt;br /&gt;
&lt;br /&gt;
Mod authors can work together to set player expectations in this respect. For example, the installation instructions might say &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;Reasonable steps have been taken to make this mod compatible. &lt;br /&gt;
Obviously, the author has no control over the quality of other mods you may have installed. &lt;br /&gt;
So, to reduce the risk of conflict, you are are strongly advised to move all files out of your &lt;br /&gt;
packages\override folders, and consider disabling unnecessary community mods on your in-game &lt;br /&gt;
DLC screen, before playing.&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Module Scope ==&lt;br /&gt;
&lt;br /&gt;
Setting the Extended Module in Module properties to &amp;quot;Core Game Resources&amp;quot; means that the add-in will change every campaign in game. If that's not intended, select the campaign you're trying to extend e.g. Single Player for the official campaign, (None) for a new standalone campaign.&lt;br /&gt;
&lt;br /&gt;
[[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | What if my mod extends both Single Player and Awakening?]]&lt;br /&gt;
&lt;br /&gt;
== Resource Scope ==&lt;br /&gt;
&lt;br /&gt;
By default, the toolset exports design resources to your addin's module override folder. That's a good thing, because it ensures that the scope of the resources is confined to your addin (and any that extend it). There's less risk of corrupting other people's work that way.&lt;br /&gt;
&lt;br /&gt;
When creating the player DAZIP, these resources should be taken out of override and put in the appropriate subfolders in your module folder. The module's override folders should only be used for changes and bug fixes, ie for overriding your own module after it has been distributed and installed.&lt;br /&gt;
&lt;br /&gt;
Never put resources in the packages folder, because that impacts every campaign. Also, once a player has installed resources there, they persist, even when your add-in is disabled. There are currently no resources known which need to be in the packages folder in order to work.&lt;br /&gt;
&lt;br /&gt;
Normally, it's not a good idea to make new core resources. It's easy to make a new core resource accidentally when duplicating an official core resource, because the Owner Module defaults to core. This isn't obvious, but the resource will export to your addin's core override folder. Exception : items cannot be imported to a new campaign with the player character unless the template is included in both campaigns. One way of doing that is to make it a core resource.   &lt;br /&gt;
&lt;br /&gt;
Art resources posted to local are always sent to the module's core override folder. Fortunately, the core override folder only affects the campaign extended (if any), the addin and any that extend it. Most of those resources can, and should be, moved to the module folder and still work. The only exceptions are resources intended to overwrite a core game resouce.&lt;br /&gt;
&lt;br /&gt;
There are a large number of mods available that use the packages folder, creating headaches for other modders and often users since such overwrites cannot be turned off in the game GUI. Users should be told to avoid mods whose method of installation is &amp;quot;place this folder in packages\override&amp;quot; and to delete any content that is currently in that folder. Mods not properly organised into dazips and installed with the Bioware supplied daupdater should also be deprecated, unless a good reason is given why they are being distributed that way.&lt;br /&gt;
&lt;br /&gt;
== Resource Conflict ==&lt;br /&gt;
&lt;br /&gt;
Resource names need to be unique within type. For example, genpt_party.plt and genpt_party.nss are different resources, becasue the type is different. However, if two modules both have resources called genpt_party.plt, only one will load in game, following the [[Source directory priorities]]. &lt;br /&gt;
&lt;br /&gt;
Within the toolset database, duplicate resource names are forbidden, but there's nothing to stop different builders making resources which accidentally conflict, so it's wise to choose a unique range of names. Each builder can register the prefix they require. See [[Naming_conventions#Resource_Naming_Convention | Resource Naming Convention]] and especially [[Prefixes in use]].&lt;br /&gt;
&lt;br /&gt;
It is possible to override a core resource intentionally, by editing a copy, exporting it, and renaming it in the export folder to the same name as the original. However, almost invariably there is a cleaner way of doing this - for example, by changing the 2DA which identifies which resource to use.&lt;br /&gt;
 &lt;br /&gt;
== Existing Content Modification ==&lt;br /&gt;
&lt;br /&gt;
When adding new content or content hooks to existing areas, do not modify the area directly and deploy the modified area as an override with your mod. This is incompatible with other mods trying to edit the same area since only one modified version of the area will &amp;quot;win&amp;quot;, and changes made by other mods to that area will not be available. Instead, use the [[PRCSCR]] system to add new content to existing areas.&lt;br /&gt;
&lt;br /&gt;
== 2DA Conflict ==&lt;br /&gt;
&lt;br /&gt;
Conflict between 2DA mods can be reduced using the [[2DA#Extending_the_game_via_M2DAs | M2DA]] mechanism and [[2DA#Reserved_ID_Ranges_and_overriding_existing_rows | reserving ID ranges]].&lt;br /&gt;
&lt;br /&gt;
2DA mods should normally be placed in the add-in's module folder. Exception : if they are meant to be universally applied to all campaigns, they should be in the addin/core/override folder. The packages override folder should normally be avoided (because that removes control from the player, by forcing the 2DA to load even if the player has disabled the add-in).&lt;br /&gt;
&lt;br /&gt;
== String Conflict ==&lt;br /&gt;
&lt;br /&gt;
When a new module is created, its properties include a [[String ID]] range which starts at a very large random number. This makes it very unlikely that text created by one add-in will override another.&lt;br /&gt;
&lt;br /&gt;
See [[String ID]] main article for a discussion of how this impacts sharing between Builders.&lt;br /&gt;
&lt;br /&gt;
The [[String editor]] article discusses techniques for editing strings which are outside of the module's normal range. It is not normally necessary to customise core strings directly, but if there is no alternative, change the Owner Module to the current module, and the Table to the current module's talk table. Otherwise, the custom string will override all campaigns.&lt;br /&gt;
&lt;br /&gt;
== Event Handling Conflict ==&lt;br /&gt;
&lt;br /&gt;
Bear in mind that an add-in which impacts all campaigns could have undesirable consequences if it changes scripts or event-handling, given that custom campaigns may well have made changes of their own. If in doubt, consider modding the Single Player campaign only.&lt;br /&gt;
&lt;br /&gt;
See [[Event_override | event override]] for recommended methods of intercepting events.&lt;br /&gt;
&lt;br /&gt;
Note that script resources are never overwritten in these methods. Conceptually, the event is intercepted by a custom script, then passed on (unless the event has been handled successfully and further processing would be harmful). In this way, mods try not to interfere unnecessarily with other scripts.&lt;br /&gt;
&lt;br /&gt;
Given the variety of actions that can be taken in a script, and that fact that one mod can't know what other mods are trying to do, we can't guarantee that this approach will be entirely free of logical problems, but the Perfect is the enemy of the Good. &lt;br /&gt;
&lt;br /&gt;
The simplest and safest method is to assign a custom event script to a resource. This is likely to be used by custom campaigns, and also by Single Player mods to specific resources, as it is the approach that Bioware devs have often recommended.  &lt;br /&gt;
&lt;br /&gt;
Mods which aim to impact all campaigns globally are better advised to use the second method, i.e. overriding [[Event_(dascript_type) | event]] handling using an Events M2DA. As illustrated in the example script, if possible the event should be passed on to the default handler of the event's target object (which might be a custom event script). In this way, a global mod can be compatible with custom campaigns and specific resource mods. &lt;br /&gt;
&lt;br /&gt;
Unfortunately, if two mods simply try to override the same event with an M2DA, they will be incompatible.&lt;br /&gt;
&lt;br /&gt;
The best solution to override, partially override, or just listen for events via M2DA at this point would be to use a system such as [http://social.bioware.com/project/1907/#details Event Manager], though to ensure compatibility all modules overriding or listening for events should also be using the same system.&lt;br /&gt;
&lt;br /&gt;
In the case of modules trying to totally override an event, only one module that does so will ultimately &amp;quot;win&amp;quot; (no such modules can ever truly be compatible with one another short of merging their functionality into one unified module as possible), but utilizing a system such as Event Manager will allow modules to partially override an event (i.e. only handle the event in certain situations), and will allow any module to listen for an event (without handling it) before or after the event is handled.&lt;br /&gt;
&lt;br /&gt;
== Plot Property ==&lt;br /&gt;
&lt;br /&gt;
Scripts that impact all campaigns should respect the plot property on resources. For example, if a campaign author has flagged an NPC as plot, it might not be helpful to change the creature AI.&lt;br /&gt;
&lt;br /&gt;
== Open Source ==&lt;br /&gt;
&lt;br /&gt;
If mod authors choose to publish their source code, with no restrictions on re-deployment, other builders can work around any residual incompatibilities (either by understanding the conflict more clearly, or by integrating the mod into their own work).&lt;br /&gt;
&lt;br /&gt;
This technical wiki is not the place to discuss any legal or ethical considerations.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== What if my mod extends both Single Player and Awakening? ===&lt;br /&gt;
&lt;br /&gt;
Just create two dazips for your module. Name one yourprefix_yourmodule_version and the other yourprefix_yourmodule_EP1_version.&lt;br /&gt;
&lt;br /&gt;
Edit the Manifest.xml file inside  yourprefix_yourmodule_EP_1_version.dazip.&lt;br /&gt;
Change the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt; to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule_EP_1&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;200&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Talk:Compatibility | Discussion]]&lt;br /&gt;
&lt;br /&gt;
=== How can I import an item with my existing character to a new campaign? ===&lt;br /&gt;
&lt;br /&gt;
The Awakening expansion allows an existing character to be imported from one campaign to another.&lt;br /&gt;
&lt;br /&gt;
There are two methods of ensuring that an item in the player's inventory is imported successfully:&lt;br /&gt;
&lt;br /&gt;
* Make the item a core resource&lt;br /&gt;
* Include the item template in separate add-ins to both campaigns (see Awakening example above)&lt;br /&gt;
&lt;br /&gt;
=== How can I stop items being imported into my campaign? ===&lt;br /&gt;
&lt;br /&gt;
Assuming your campaign allows existing characters to be imported during Character Generation, you might want to clear the player's inventory before adding your starting equipment. Imported equipment might upset the balance of your campaign.&lt;br /&gt;
&lt;br /&gt;
If you decide to do this, it's a good idea to warn players, so that they understand what's happening.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15384</id>
		<title>Talk:Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15384"/>
				<updated>2011-01-03T04:28:16Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource scope edit */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What if my mod extends both Single Player and Awakening? ==&lt;br /&gt;
&lt;br /&gt;
I moved this section here because it's under discussion. [[User:Proleric1|Proleric1]] 08:27, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
=============== &lt;br /&gt;
NOTE:&lt;br /&gt;
&lt;br /&gt;
There is an easier way than creating two scripts. Just put the information for both in the manifest.xml file. For one of my mods, the manifest file looked like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Manifest Type=&amp;quot;AddIn&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;AddInsList&amp;gt;&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Description DefaultText=&amp;quot;ELF the pet cat adds a 'Cat Toy' to the players inventory (rest of text deleted for brevity)&lt;br /&gt;
&lt;br /&gt;
((This package will work in both DAO and Awakening!))&amp;quot;&amp;gt;&amp;lt;/Description&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;packages/&amp;quot; Type=&amp;quot;package&amp;quot;/&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;/AddInsList&amp;gt;&lt;br /&gt;
&amp;lt;/Manifest&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
doing this allowed users to install one package (using DAModder) which worked for both awakening and DAO.&lt;br /&gt;
&lt;br /&gt;
============== ++ Angel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@monkeysnest - good to have the update concerning the manifest. A few queries:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the article would be clearer if you explained which line has to change, rather than reproduce the entire manifest here?&lt;br /&gt;
&lt;br /&gt;
* Would DAUpdater work? I don't see DAModder listed as a project download on the Bioware social site.&lt;br /&gt;
&lt;br /&gt;
* We don't normally leave our signatures on the content pages of a wiki.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
[[User:Proleric1|Proleric1]] 05:47, 8 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think the &amp;quot;dual entry, single manifest&amp;quot; approach should be followed or encouraged.  Creating two separate .dazip installations as mentioned in [[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | Compatibility: What if my mod extends both Single Player and Awakening?]] is IMHO the preferred approach.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nukenin|Nukenin]] 00:24, 24 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I'll have to agree with Nukenin here, especially since using the &amp;quot;dual entry, single manifest&amp;quot; approach will cause DAUpdater to crash and would unnecessarily force players to use third-party apps. Moreover, it's perfectly possible to include several addons (each one with its own manifest entry) in a single dazip package :&lt;br /&gt;
* Package root&lt;br /&gt;
** Manifest including several AddInItem elements&lt;br /&gt;
** Contents&lt;br /&gt;
*** addins&lt;br /&gt;
**** addin_uid1&lt;br /&gt;
**** addin_uid2&lt;br /&gt;
**** addin_uid3&lt;br /&gt;
**** etc&lt;br /&gt;
*** packages&lt;br /&gt;
&lt;br /&gt;
--[[User:Phaenan|Phaenan]] 06:45, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I find myself agreeing with Phaenan and Nukenin on this; end users should only use community created tools if they want a specific function that's only available to them that way (like the ability to uninstall a dazip). &lt;br /&gt;
[[User:Ladydesire|Ladydesire]] 18:40, 25 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Override Events while minimizing compat issues.. ==&lt;br /&gt;
&lt;br /&gt;
I believe this may be useful to others - through trial and error, and with some help, I have figured out a way to override events only when my module is running - I had to add a variable to var_module.xls/gda (which is probably where the only potential compatibility issue will arise via string ID, though I am not sure what would happen if someone tried to override the same events - depends on which engineevents get's loaded last I suppose...).&lt;br /&gt;
&lt;br /&gt;
The variable is defaulted to a 0....in my modules properties, I set the variable to a 1. My event overrides check for this variable to be == 1, if not, send it off the proper handler. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See the following post where I came to this 'workaround'...would love to know if there is a better way:&lt;br /&gt;
&lt;br /&gt;
http://social.bioware.com/forum/1/topic/8/index/2371093/1#2531362&lt;br /&gt;
&lt;br /&gt;
== Resource scope edit ==&lt;br /&gt;
&lt;br /&gt;
I have removed the reference to tint maps following the discussion at http://social.bioware.com/group/2937/discussion/12738/ .&lt;br /&gt;
&lt;br /&gt;
Also beefed up the recommendations about not putting files into packages --[[User:Gaxkang55|Gaxkang55]] 12:43, 30 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
Good update! I'm very much on the same wavelength. I have one question, though, concerning the Talk Table. Normally, the best way to change a core string is to make a new one, then point the appropriate 2DA at it. However, there are cases where no such mechanism exists. For example, if you want to make a module that isn't set in the Ferelden gameworld, you need to change the gender descriptions, replace all instances of &amp;quot;marabi&amp;quot; with &amp;quot;dog&amp;quot; and so on. To the best of my knowledge, this can't be done without an override - see [[String_editor]]. If there's a better solution, I'd be keen to hear it. [[User:Proleric1|Proleric1]] 08:50, 31 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
As it happens, I had to do exactly that for the campaign I have in development, where I wanted to override the gender description. Create the string but make the Owner Module your module. This will be exported to the talktable placed in your core, and will overwrite the core string as long as your module is enabled. Also tested the head morph stuff, and that doesn't need to be in packages either, so will make a further update. --[[User:Gaxkang55|Gaxkang55]] 04:28, 3 January 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Bug:_Toolset_loses_M2DA_dropdown_selection,_resets_to_default&amp;diff=15324</id>
		<title>Bug: Toolset loses M2DA dropdown selection, resets to default</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Bug:_Toolset_loses_M2DA_dropdown_selection,_resets_to_default&amp;diff=15324"/>
				<updated>2010-12-30T17:31:16Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*'''Version found:''' 1.0.1008.0&amp;lt;!-- put the version number of your toolset here --&amp;gt;&lt;br /&gt;
*'''Status:''' Open&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&amp;lt;!-- Describe the bug here including as many details as possible. What situations trigger it and what effects it causes are the most important. --&amp;gt;The toolset will from time to time report it can no longer find name of ... , referring to a selection defined in a M2DA and previously selected, saved and exported. On the next export in which the affected object is also exported as a dependent resource, it will have reverted to whatever the default is in the main 2DA. This has affected new placeables, appearances, tints and tint overrides, and alternative variable tables that I have noticed so far, but the spread indicates any M2DA can be effected. The bug is particularly toxic because several hundred exports may occur when, for instance, an area is exported and the warning is then very easy to miss. Needless to say, the effects can be quite drastic ingame, with placeables disappearing, tints non-existent, scripts unable to get variables, etc, and of course it is not always clear what the source of perceived problem is, since the damage may have been done many days before ingame testing discovers there is a problem. The phenomenon is random, and varies in frequency to several times an hour for a particular table to no problems for days on end for the same table.&lt;br /&gt;
&lt;br /&gt;
== Workarounds ==&lt;br /&gt;
&amp;lt;!-- if you know of any ways to work around the bug describe them here. --&amp;gt;Once discovered, closing and reopening the toolset will set the correct option without further intervention, and the object can be re-exported successfully. In general, keeping a weather eye on the log is a good idea, since the toolset will repeatedly complain whenever anything affecting the damaged resource is worked on, eg when scripts are compiled that reference the resource. If you see such a warning, call up the object and verify it has reverted to default for relevant field. Close the toolset immediately, and on reopening export the resource.&lt;br /&gt;
&lt;br /&gt;
[[Category:Toolset bugs]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Bug:_Toolset_loses_M2DA_dropdown_selection,_resets_to_default&amp;diff=15323</id>
		<title>Bug: Toolset loses M2DA dropdown selection, resets to default</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Bug:_Toolset_loses_M2DA_dropdown_selection,_resets_to_default&amp;diff=15323"/>
				<updated>2010-12-30T17:29:37Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: Created page with '*'''Version found:''' 1.0.1008.0&amp;lt;!-- put the version number of your toolset here --&amp;gt; *'''Status:''' Open  == Description == &amp;lt;!-- Describe the bug here including as many details a...'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*'''Version found:''' 1.0.1008.0&amp;lt;!-- put the version number of your toolset here --&amp;gt;&lt;br /&gt;
*'''Status:''' Open&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
&amp;lt;!-- Describe the bug here including as many details as possible. What situations trigger it and what effects it causes are the most important. --&amp;gt;The toolset will from time to time report it can no longer find name of ... , referring to a selection defined in a M2DA and previously selected, saved and exported. On the next export in which the affected object is also exported as a dependent resource, it will have reverted to whatever the default is in the main 2DA. This has affected new placeables, appearances, tints and tint overrides, and alternative variable tables that I have noticed so far, but the spread indicates any M2DA can be effected. The bug is particularly toxic because several hundred exports may occur when, for instance, and area is exported and the warning is then very easy to miss. Needless to say, the effects can be quite drastic ingame, with placeable disappearing, tints non-existent, scripts unable to get variables, etc, and of course it is not always clear what the source of perceived problem is, since the damage may have been done many days before ingame testing discovers there is a problem. The phenomenon is random, and varies in frequency to several times an hour for a particular table to no problems for days on end for the same table.&lt;br /&gt;
&lt;br /&gt;
== Workarounds ==&lt;br /&gt;
&amp;lt;!-- if you know of any ways to work around the bug describe them here. --&amp;gt;Once discovered, closing and reopening the toolset will set the correct option without further intervention, and the object can be re-exported successfully. In general, keeping a weather eye on the log is a good idea, since the toolset will repeatedly complain whenever anything affecting the damaged resource is worked on, eg when scripts are compiled that reference the resource. If you see such a warning, call up the object and verify it has reverted to default for relevant field. Close the toolset immediately, and on reopening export the resource.&lt;br /&gt;
&lt;br /&gt;
[[Category:Toolset bugs]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15322</id>
		<title>Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15322"/>
				<updated>2010-12-30T12:57:14Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Tutorial to ensure your Awakening mod will not break Origins and vice versa!!! (includes screenshots and script code) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DAO has an active modding community. Over time, players will accumulate many new campaigns and game mods. So, as a courtesy to players and other builders, it's helpful to try to make our mods mutually compatible. &lt;br /&gt;
&lt;br /&gt;
From time to time, Bioware may well issue new releases, so it's good to reduce the risk of conflict in that respect, too. &lt;br /&gt;
&lt;br /&gt;
Since we can't be sure that all authors will respect compatibility considerations, the emphasis here is on techniques that reduce the risk of conflict, regardless of what other people do (though not all are foolproof).&lt;br /&gt;
&lt;br /&gt;
Obviously, there are some conflicts with no win-win (hurlocks can't be both green and purple at the same time), but that doesn't stop us trying to avoid unnecessary win-lose or corruption.&lt;br /&gt;
&lt;br /&gt;
We begin with a concrete example - a tutorial on script conflict in OC mods, which is one of the most common problems to avoid. The remainder of the page is a more systematic discussion, which applies to both OC mods and custom campaigns.    &lt;br /&gt;
&lt;br /&gt;
== Tutorial to ensure your Awakening mod will not break Origins and vice versa!!! (includes screenshots and script code) ==&lt;br /&gt;
&lt;br /&gt;
I'm hoping to save my modding friends some time. (Tutorial by Immortality)&lt;br /&gt;
&lt;br /&gt;
'''Remember: IT'S YOUR RESPONSIBILITY TO ENSURE YOUR MOD DOES NOT BREAK THE GAME, THE EXPANSION, DLCS, OR OTHER MODS!!'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The problem:'''''&lt;br /&gt;
&lt;br /&gt;
- While working in my Origins mod, and then on my Awakening mod, I realized that my Origins mod was breaking Awakening (scripts were not triggering, and even objects were moving around!).&lt;br /&gt;
&lt;br /&gt;
- In the same way, my mod for Awakening was interfeering in Origins, breaking it (wrong scripts triggering, destroying the party recruiting).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The objective:'''''&lt;br /&gt;
&lt;br /&gt;
- Prevent the Origins mod to interfere with Awakening. If your mod is for Origins, it should only work in Origins.&lt;br /&gt;
&lt;br /&gt;
- Prevent the Awakening mod to interfere with Origins. If your mod is for Awakening, it should only work in Awakening.&lt;br /&gt;
&lt;br /&gt;
- If you have one mod for both, to ensure that the Origins part triggers in Origins and Awakening part in Awakening.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Procedure:'''''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''1- Ensure your Origins mod is for Origins only!'''&lt;br /&gt;
&lt;br /&gt;
NEVER EVER EVER set your core scripts or handling scripts as Core Game Resources. NEVER!&lt;br /&gt;
&lt;br /&gt;
There's absolutely no need for your scripts (especially your module core) to be a core game resource.&lt;br /&gt;
&lt;br /&gt;
This means that whenever you create a mod for origins you should always set the properties of your major handling scripts as &amp;quot;Module: your module&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. NEVER as a core game resource. Otherwise they will interfere with awakening and will break it (make no mistake, they will).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
This is how you set your Origins module: [[image:Originshierarchy.jpg]]&lt;br /&gt;
&lt;br /&gt;
This is how you set all your script's properties: [[image:Originsproperties.jpg]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2- Ensure your Awakening mod is for Awakening only!'''&lt;br /&gt;
&lt;br /&gt;
Things are different for Awakening because you DO have to set all your materials' properties as &amp;quot;Module: Core Game Resources&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. (read the tutorial if you need to know more: http://social.bioware.com/53295/blog/10858/ )&lt;br /&gt;
&lt;br /&gt;
This means that your Awakening mod will interfere with Origins and will break the game.&lt;br /&gt;
&lt;br /&gt;
Use IsUsingEP1Resources() [returns TRUE or FALSE] as the preferred method of ensuring your scripts apply to the correct campaign. Origins code itself has a lot of code that was written for Awakening and in all cases, Bioware uses this function to check if Awakening is being used or not.&lt;br /&gt;
&lt;br /&gt;
'''Addendum:''' If you have copy-pasted scripts, for example your follower join script, it can still mess your Origins mod, even with the checks implemented!!!&lt;br /&gt;
&lt;br /&gt;
In order to avoid this, you can rename your functions.&lt;br /&gt;
For example, if your Origins script has the function &amp;quot;SetFollowerInParty&amp;quot;, then rename the function in your Awakening script to &amp;quot;SetFollowerInParty_awakening&amp;quot;, and etc.&lt;br /&gt;
&lt;br /&gt;
== Disable Add-Ins : Suggested Disclaimer ==&lt;br /&gt;
&lt;br /&gt;
If the player disables all other add-ins on the in game DLC screen, no conflict should occur between them. Tedious, but effective.&lt;br /&gt;
&lt;br /&gt;
This should rarely be necessary if the compatibility guidelines listed here are observed.&lt;br /&gt;
&lt;br /&gt;
Exception : there is a [[Bug:_export_creates_unnecessary_core_override | toolset bug]] which produces content that persists in game, even when the add-in is disabled, unless the builder cleans it out before making the Builder-to-Player file. The same problem can occur if a builder has intentionally placed content in the packages\override folder (which should normally be avoided, as it is very rarely necessary).&lt;br /&gt;
&lt;br /&gt;
Mod authors can work together to set player expectations in this respect. For example, the installation instructions might say &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;Reasonable steps have been taken to make this mod compatible. &lt;br /&gt;
Obviously, the author has no control over the quality of other mods you may have installed. &lt;br /&gt;
So, to reduce the risk of conflict, you are are strongly advised to move all files out of your &lt;br /&gt;
packages\override folders, and consider disabling unnecessary community mods on your in-game &lt;br /&gt;
DLC screen, before playing.&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Module Scope ==&lt;br /&gt;
&lt;br /&gt;
Setting the Extended Module in Module properties to &amp;quot;Core Game Resources&amp;quot; means that the add-in will change every campaign in game. If that's not intended, select the campaign you're trying to extend e.g. Single Player for the official campaign, (None) for a new standalone campaign.&lt;br /&gt;
&lt;br /&gt;
[[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | What if my mod extends both Single Player and Awakening?]]&lt;br /&gt;
&lt;br /&gt;
== Resource Scope ==&lt;br /&gt;
&lt;br /&gt;
By default, the toolset exports design resources to your addin's module override folder. That's a good thing, because it ensures that the scope of the resources is confined to your addin (and any that extend it). There's less risk of corrupting other people's work that way.&lt;br /&gt;
&lt;br /&gt;
Never put resources in the packages folder, because that impacts every campaign. Also, once a player has installed resources there, they persist, even when your add-in is disabled. &lt;br /&gt;
&lt;br /&gt;
It appears the packages folder has to be used for resources that won't load from the addins folder, namely &lt;br /&gt;
&lt;br /&gt;
* The Talk Table (see [[Bug:_Talk_table_exported_to_packages_override | bug]]) that overrides existing game strings. Best practice is to avoid doing this in the first place.&lt;br /&gt;
* The chargenmorphcfg.xml file, which can be used to add new morph presets for character generation.&lt;br /&gt;
&lt;br /&gt;
It was reported that tint maps needed to be in packages, but this was based on a misunderstanding. &lt;br /&gt;
&lt;br /&gt;
Normally, it's not a good idea to make new core resources. It's easy to make a new core resource accidentally when duplicating an official core resource, because the Owner Module defaults to core. This isn't obvious, but the resource will export to your addin's core override folder.      &lt;br /&gt;
&lt;br /&gt;
Exception : items cannot be imported to a new campaign with the player character unless the template is included in both campaigns. One way of doing that is to make it a core resource.   &lt;br /&gt;
&lt;br /&gt;
Art resources posted to local are always sent to the module's core override folder. Fortunately, the core override folder only affects the campaign extended (if any), the addin and any that extend it. Many of those resources can in any case be moved to the module folder and still work.&lt;br /&gt;
&lt;br /&gt;
There are a large number of mods available that use the packages folder, creating headaches for other modders and often users since such overwrites cannot be turned off in the game GUI. Users should be told to avoid mods whose method of installation is &amp;quot;place this folder in packages\override&amp;quot; and to delete any content that is currently in that folder. Mods not properly organised into dazips and installed with the Bioware supplied daupdater should also be deprecated, unless a good reason is given why they are being distributed that way.&lt;br /&gt;
&lt;br /&gt;
== Resource Conflict ==&lt;br /&gt;
&lt;br /&gt;
Resource names need to be unique within type. For example, genpt_party.plt and genpt_party.nss are different resources, becasue the type is different. However, if two modules both have resources called genpt_party.plt, only one will load in game, following the [[Source directory priorities]]. &lt;br /&gt;
&lt;br /&gt;
Within the toolset database, duplicate resource names are forbidden, but there's nothing to stop different builders making resources which accidentally conflict, so it's wise to choose a unique range of names. Each builder can register the prefix they require. See [[Naming_conventions#Resource_Naming_Convention | Resource Naming Convention]] and especially [[Prefixes in use]].&lt;br /&gt;
&lt;br /&gt;
It is possible to override a core resource intentionally, by editing a copy, exporting it, and renaming it in the export folder to the same name as the original. However, almost invariably there is a cleaner way of doing this - for example, by changing the 2DA which identifies which resource to use.&lt;br /&gt;
 &lt;br /&gt;
== Existing Content Modification ==&lt;br /&gt;
&lt;br /&gt;
When adding new content or content hooks to existing areas, do not modify the area directly and deploy the modified area as an override with your mod. This is incompatible with other mods trying to edit the same area since only one modified version of the area will &amp;quot;win&amp;quot;, and changes made by other mods to that area will not be available. Instead, use the [[PRCSCR]] system to add new content to existing areas.&lt;br /&gt;
&lt;br /&gt;
== 2DA Conflict ==&lt;br /&gt;
&lt;br /&gt;
Conflict between 2DA mods can be reduced using the [[2DA#Extending_the_game_via_M2DAs | M2DA]] mechanism and [[2DA#Reserved_ID_Ranges_and_overriding_existing_rows | reserving ID ranges]].&lt;br /&gt;
&lt;br /&gt;
2DA mods should normally be placed in the add-in's module folder. Exception : if they are meant to be universally applied to all campaigns, they should be in the addin/core/override folder. The packages override folder should normally be avoided (because that removes control from the player, by forcing the 2DA to load even if the player has disabled the add-in).&lt;br /&gt;
&lt;br /&gt;
== String Conflict ==&lt;br /&gt;
&lt;br /&gt;
When a new module is created, its properties include a [[String ID]] range which starts at a very large random number. This makes it very unlikely that text created by one add-in will override another.&lt;br /&gt;
&lt;br /&gt;
See [[String ID]] main article for a discussion of how this impacts sharing between Builders.&lt;br /&gt;
&lt;br /&gt;
The [[String editor]] article discusses techniques for editing strings which are outside of the module's normal range. It is not normally necessary to customise core strings directly, but if there is no alternative, change the Owner Module to the current module, and the Table to the current module's talk table. Otherwise, the custom string will override all campaigns.&lt;br /&gt;
&lt;br /&gt;
== Event Handling Conflict ==&lt;br /&gt;
&lt;br /&gt;
Bear in mind that an add-in which impacts all campaigns could have undesirable consequences if it changes scripts or event-handling, given that custom campaigns may well have made changes of their own. If in doubt, consider modding the Single Player campaign only.&lt;br /&gt;
&lt;br /&gt;
See [[Event_override | event override]] for recommended methods of intercepting events.&lt;br /&gt;
&lt;br /&gt;
Note that script resources are never overwritten in these methods. Conceptually, the event is intercepted by a custom script, then passed on (unless the event has been handled successfully and further processing would be harmful). In this way, mods try not to interfere unnecessarily with other scripts.&lt;br /&gt;
&lt;br /&gt;
Given the variety of actions that can be taken in a script, and that fact that one mod can't know what other mods are trying to do, we can't guarantee that this approach will be entirely free of logical problems, but the Perfect is the enemy of the Good. &lt;br /&gt;
&lt;br /&gt;
The simplest and safest method is to assign a custom event script to a resource. This is likely to be used by custom campaigns, and also by Single Player mods to specific resources, as it is the approach that Bioware devs have often recommended.  &lt;br /&gt;
&lt;br /&gt;
Mods which aim to impact all campaigns globally are better advised to use the second method, i.e. overriding [[Event_(dascript_type) | event]] handling using an Events M2DA. As illustrated in the example script, if possible the event should be passed on to the default handler of the event's target object (which might be a custom event script). In this way, a global mod can be compatible with custom campaigns and specific resource mods. &lt;br /&gt;
&lt;br /&gt;
Unfortunately, if two mods simply try to override the same event with an M2DA, they will be incompatible.&lt;br /&gt;
&lt;br /&gt;
The best solution to override, partially override, or just listen for events via M2DA at this point would be to use a system such as [http://social.bioware.com/project/1907/#details Event Manager], though to ensure compatibility all modules overriding or listening for events should also be using the same system.&lt;br /&gt;
&lt;br /&gt;
In the case of modules trying to totally override an event, only one module that does so will ultimately &amp;quot;win&amp;quot; (no such modules can ever truly be compatible with one another short of merging their functionality into one unified module as possible), but utilizing a system such as Event Manager will allow modules to partially override an event (i.e. only handle the event in certain situations), and will allow any module to listen for an event (without handling it) before or after the event is handled.&lt;br /&gt;
&lt;br /&gt;
== Plot Property ==&lt;br /&gt;
&lt;br /&gt;
Scripts that impact all campaigns should respect the plot property on resources. For example, if a campaign author has flagged an NPC as plot, it might not be helpful to change the creature AI.&lt;br /&gt;
&lt;br /&gt;
== Open Source ==&lt;br /&gt;
&lt;br /&gt;
If mod authors choose to publish their source code, with no restrictions on re-deployment, other builders can work around any residual incompatibilities (either by understanding the conflict more clearly, or by integrating the mod into their own work).&lt;br /&gt;
&lt;br /&gt;
This technical wiki is not the place to discuss any legal or ethical considerations.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== What if my mod extends both Single Player and Awakening? ===&lt;br /&gt;
&lt;br /&gt;
Just create two dazips for your module. Name one yourprefix_yourmodule_version and the other yourprefix_yourmodule_EP1_version.&lt;br /&gt;
&lt;br /&gt;
Edit the Manifest.xml file inside  yourprefix_yourmodule_EP_1_version.dazip.&lt;br /&gt;
Change the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt; to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule_EP_1&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;200&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Talk:Compatibility | Discussion]]&lt;br /&gt;
&lt;br /&gt;
=== How can I import an item with my existing character to a new campaign? ===&lt;br /&gt;
&lt;br /&gt;
The Awakening expansion allows an existing character to be imported from one campaign to another.&lt;br /&gt;
&lt;br /&gt;
There are two methods of ensuring that an item in the player's inventory is imported successfully:&lt;br /&gt;
&lt;br /&gt;
* Make the item a core resource&lt;br /&gt;
* Include the item template in separate add-ins to both campaigns (see Awakening example above)&lt;br /&gt;
&lt;br /&gt;
=== How can I stop items being imported into my campaign? ===&lt;br /&gt;
&lt;br /&gt;
Assuming your campaign allows existing characters to be imported during Character Generation, you might want to clear the player's inventory before adding your starting equipment. Imported equipment might upset the balance of your campaign.&lt;br /&gt;
&lt;br /&gt;
If you decide to do this, it's a good idea to warn players, so that they understand what's happening.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15321</id>
		<title>Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15321"/>
				<updated>2010-12-30T12:53:50Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: cleaned up text. this is not a discussion page, we should just provide the best advice available not have a debate.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DAO has an active modding community. Over time, players will accumulate many new campaigns and game mods. So, as a courtesy to players and other builders, it's helpful to try to make our mods mutually compatible. &lt;br /&gt;
&lt;br /&gt;
From time to time, Bioware may well issue new releases, so it's good to reduce the risk of conflict in that respect, too. &lt;br /&gt;
&lt;br /&gt;
Since we can't be sure that all authors will respect compatibility considerations, the emphasis here is on techniques that reduce the risk of conflict, regardless of what other people do (though not all are foolproof).&lt;br /&gt;
&lt;br /&gt;
Obviously, there are some conflicts with no win-win (hurlocks can't be both green and purple at the same time), but that doesn't stop us trying to avoid unnecessary win-lose or corruption.&lt;br /&gt;
&lt;br /&gt;
We begin with a concrete example - a tutorial on script conflict in OC mods, which is one of the most common problems to avoid. The remainder of the page is a more systematic discussion, which applies to both OC mods and custom campaigns.    &lt;br /&gt;
&lt;br /&gt;
== Tutorial to ensure your Awakening mod will not break Origins and vice versa!!! (includes screenshots and script code) ==&lt;br /&gt;
&lt;br /&gt;
I'm hoping to save my modding friends some time. (Tutorial by Immortality)&lt;br /&gt;
&lt;br /&gt;
'''Remember: IT'S YOUR RESPONSIBILITY TO ENSURE YOUR MOD DOES NOT BREAK THE GAME, THE EXPANSION, DLCS, OR OTHER MODS!!'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The problem:'''''&lt;br /&gt;
&lt;br /&gt;
- While working in my Origins mod, and then on my Awakening mod, I realized that my Origins mod was breaking Awakening (scripts were not triggering, and even objects were moving around!).&lt;br /&gt;
&lt;br /&gt;
- In the same way, my mod for Awakening was interfeering in Origins, breaking it (wrong scripts triggering, destroying the party recruiting).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The objective:'''''&lt;br /&gt;
&lt;br /&gt;
- Prevent the Origins mod to interfere with Awakening. If your mod is for Origins, it should only work in Origins.&lt;br /&gt;
&lt;br /&gt;
- Prevent the Awakening mod to interfere with Origins. If your mod is for Awakening, it should only work in Awakening.&lt;br /&gt;
&lt;br /&gt;
- If you have one mod for both, to ensure that the Origins part triggers in Origins and Awakening part in Awakening.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Procedure:'''''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''1- Ensure your Origins mod is for Origins only!'''&lt;br /&gt;
&lt;br /&gt;
NEVER EVER EVER set your core scripts or handling scripts as Core Game Resources. NEVER!&lt;br /&gt;
&lt;br /&gt;
There's absolutely no need for your scripts (especially your module core) to be a core game resource.&lt;br /&gt;
&lt;br /&gt;
This means that whenever you create a mod for origins you should always set the properties of your major handling scripts as &amp;quot;Module: your module&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. NEVER as a core game resource. Otherwise they will interfere with awakening and will break it (make no mistake, they will).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
This is how you set your Origins module: [[image:Originshierarchy.jpg]]&lt;br /&gt;
&lt;br /&gt;
This is how you set all your script's properties: [[image:Originsproperties.jpg]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2- Ensure your Awakening mod is for Awakening only!'''&lt;br /&gt;
&lt;br /&gt;
Things are different for Awakening because you DO have to set all your materials' properties as &amp;quot;Module: Core Game Resources&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. (read the tutorial if you need to know more: http://social.bioware.com/53295/blog/10858/ )&lt;br /&gt;
&lt;br /&gt;
This means that your Awakening mod will interfere with Origins and will break the game.&lt;br /&gt;
&lt;br /&gt;
Use IsUsingEP1Resources() [returns TRUE or FALSE] as the preferred of ensuring your scripts apply to the correct campaign. Origins code itself has a lot of code that was written for Awakening and in all cases, Bioware uses this function to check if Awakening is being used or not.&lt;br /&gt;
&lt;br /&gt;
'''Addendum:''' If you have copy-pasted scripts, for example your follower join script, it can still mess your Origins mod, even with the checks implemented!!!&lt;br /&gt;
&lt;br /&gt;
In order to avoid this, you can rename your functions.&lt;br /&gt;
For example, if your Origins script has the function &amp;quot;SetFollowerInParty&amp;quot;, then rename the function in your Awakening script to &amp;quot;SetFollowerInParty_awakening&amp;quot;, and etc.&lt;br /&gt;
&lt;br /&gt;
== Disable Add-Ins : Suggested Disclaimer ==&lt;br /&gt;
&lt;br /&gt;
If the player disables all other add-ins on the in game DLC screen, no conflict should occur between them. Tedious, but effective.&lt;br /&gt;
&lt;br /&gt;
This should rarely be necessary if the compatibility guidelines listed here are observed.&lt;br /&gt;
&lt;br /&gt;
Exception : there is a [[Bug:_export_creates_unnecessary_core_override | toolset bug]] which produces content that persists in game, even when the add-in is disabled, unless the builder cleans it out before making the Builder-to-Player file. The same problem can occur if a builder has intentionally placed content in the packages\override folder (which should normally be avoided, as it is very rarely necessary).&lt;br /&gt;
&lt;br /&gt;
Mod authors can work together to set player expectations in this respect. For example, the installation instructions might say &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;Reasonable steps have been taken to make this mod compatible. &lt;br /&gt;
Obviously, the author has no control over the quality of other mods you may have installed. &lt;br /&gt;
So, to reduce the risk of conflict, you are are strongly advised to move all files out of your &lt;br /&gt;
packages\override folders, and consider disabling unnecessary community mods on your in-game &lt;br /&gt;
DLC screen, before playing.&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Module Scope ==&lt;br /&gt;
&lt;br /&gt;
Setting the Extended Module in Module properties to &amp;quot;Core Game Resources&amp;quot; means that the add-in will change every campaign in game. If that's not intended, select the campaign you're trying to extend e.g. Single Player for the official campaign, (None) for a new standalone campaign.&lt;br /&gt;
&lt;br /&gt;
[[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | What if my mod extends both Single Player and Awakening?]]&lt;br /&gt;
&lt;br /&gt;
== Resource Scope ==&lt;br /&gt;
&lt;br /&gt;
By default, the toolset exports design resources to your addin's module override folder. That's a good thing, because it ensures that the scope of the resources is confined to your addin (and any that extend it). There's less risk of corrupting other people's work that way.&lt;br /&gt;
&lt;br /&gt;
Never put resources in the packages folder, because that impacts every campaign. Also, once a player has installed resources there, they persist, even when your add-in is disabled. &lt;br /&gt;
&lt;br /&gt;
It appears the packages folder has to be used for resources that won't load from the addins folder, namely &lt;br /&gt;
&lt;br /&gt;
* The Talk Table (see [[Bug:_Talk_table_exported_to_packages_override | bug]]) that overrides existing game strings. Best practice is to avoid doing this in the first place.&lt;br /&gt;
* The chargenmorphcfg.xml file, which can be used to add new morph presets for character generation.&lt;br /&gt;
&lt;br /&gt;
It was reported that tint maps needed to be in packages, but this was based on a misunderstanding. &lt;br /&gt;
&lt;br /&gt;
Normally, it's not a good idea to make new core resources. It's easy to make a new core resource accidentally when duplicating an official core resource, because the Owner Module defaults to core. This isn't obvious, but the resource will export to your addin's core override folder.      &lt;br /&gt;
&lt;br /&gt;
Exception : items cannot be imported to a new campaign with the player character unless the template is included in both campaigns. One way of doing that is to make it a core resource.   &lt;br /&gt;
&lt;br /&gt;
Art resources posted to local are always sent to the module's core override folder. Fortunately, the core override folder only affects the campaign extended (if any), the addin and any that extend it. Many of those resources can in any case be moved to the module folder and still work.&lt;br /&gt;
&lt;br /&gt;
There are a large number of mods available that use the packages folder, creating headaches for other modders and often users since such overwrites cannot be turned off in the game GUI. Users should be told to avoid mods whose method of installation is &amp;quot;place this folder in packages\override&amp;quot; and to delete any content that is currently in that folder. Mods not properly organised into dazips and installed with the Bioware supplied daupdater should also be deprecated, unless a good reason is given why they are being distributed that way.&lt;br /&gt;
&lt;br /&gt;
== Resource Conflict ==&lt;br /&gt;
&lt;br /&gt;
Resource names need to be unique within type. For example, genpt_party.plt and genpt_party.nss are different resources, becasue the type is different. However, if two modules both have resources called genpt_party.plt, only one will load in game, following the [[Source directory priorities]]. &lt;br /&gt;
&lt;br /&gt;
Within the toolset database, duplicate resource names are forbidden, but there's nothing to stop different builders making resources which accidentally conflict, so it's wise to choose a unique range of names. Each builder can register the prefix they require. See [[Naming_conventions#Resource_Naming_Convention | Resource Naming Convention]] and especially [[Prefixes in use]].&lt;br /&gt;
&lt;br /&gt;
It is possible to override a core resource intentionally, by editing a copy, exporting it, and renaming it in the export folder to the same name as the original. However, almost invariably there is a cleaner way of doing this - for example, by changing the 2DA which identifies which resource to use.&lt;br /&gt;
 &lt;br /&gt;
== Existing Content Modification ==&lt;br /&gt;
&lt;br /&gt;
When adding new content or content hooks to existing areas, do not modify the area directly and deploy the modified area as an override with your mod. This is incompatible with other mods trying to edit the same area since only one modified version of the area will &amp;quot;win&amp;quot;, and changes made by other mods to that area will not be available. Instead, use the [[PRCSCR]] system to add new content to existing areas.&lt;br /&gt;
&lt;br /&gt;
== 2DA Conflict ==&lt;br /&gt;
&lt;br /&gt;
Conflict between 2DA mods can be reduced using the [[2DA#Extending_the_game_via_M2DAs | M2DA]] mechanism and [[2DA#Reserved_ID_Ranges_and_overriding_existing_rows | reserving ID ranges]].&lt;br /&gt;
&lt;br /&gt;
2DA mods should normally be placed in the add-in's module folder. Exception : if they are meant to be universally applied to all campaigns, they should be in the addin/core/override folder. The packages override folder should normally be avoided (because that removes control from the player, by forcing the 2DA to load even if the player has disabled the add-in).&lt;br /&gt;
&lt;br /&gt;
== String Conflict ==&lt;br /&gt;
&lt;br /&gt;
When a new module is created, its properties include a [[String ID]] range which starts at a very large random number. This makes it very unlikely that text created by one add-in will override another.&lt;br /&gt;
&lt;br /&gt;
See [[String ID]] main article for a discussion of how this impacts sharing between Builders.&lt;br /&gt;
&lt;br /&gt;
The [[String editor]] article discusses techniques for editing strings which are outside of the module's normal range. It is not normally necessary to customise core strings directly, but if there is no alternative, change the Owner Module to the current module, and the Table to the current module's talk table. Otherwise, the custom string will override all campaigns.&lt;br /&gt;
&lt;br /&gt;
== Event Handling Conflict ==&lt;br /&gt;
&lt;br /&gt;
Bear in mind that an add-in which impacts all campaigns could have undesirable consequences if it changes scripts or event-handling, given that custom campaigns may well have made changes of their own. If in doubt, consider modding the Single Player campaign only.&lt;br /&gt;
&lt;br /&gt;
See [[Event_override | event override]] for recommended methods of intercepting events.&lt;br /&gt;
&lt;br /&gt;
Note that script resources are never overwritten in these methods. Conceptually, the event is intercepted by a custom script, then passed on (unless the event has been handled successfully and further processing would be harmful). In this way, mods try not to interfere unnecessarily with other scripts.&lt;br /&gt;
&lt;br /&gt;
Given the variety of actions that can be taken in a script, and that fact that one mod can't know what other mods are trying to do, we can't guarantee that this approach will be entirely free of logical problems, but the Perfect is the enemy of the Good. &lt;br /&gt;
&lt;br /&gt;
The simplest and safest method is to assign a custom event script to a resource. This is likely to be used by custom campaigns, and also by Single Player mods to specific resources, as it is the approach that Bioware devs have often recommended.  &lt;br /&gt;
&lt;br /&gt;
Mods which aim to impact all campaigns globally are better advised to use the second method, i.e. overriding [[Event_(dascript_type) | event]] handling using an Events M2DA. As illustrated in the example script, if possible the event should be passed on to the default handler of the event's target object (which might be a custom event script). In this way, a global mod can be compatible with custom campaigns and specific resource mods. &lt;br /&gt;
&lt;br /&gt;
Unfortunately, if two mods simply try to override the same event with an M2DA, they will be incompatible.&lt;br /&gt;
&lt;br /&gt;
The best solution to override, partially override, or just listen for events via M2DA at this point would be to use a system such as [http://social.bioware.com/project/1907/#details Event Manager], though to ensure compatibility all modules overriding or listening for events should also be using the same system.&lt;br /&gt;
&lt;br /&gt;
In the case of modules trying to totally override an event, only one module that does so will ultimately &amp;quot;win&amp;quot; (no such modules can ever truly be compatible with one another short of merging their functionality into one unified module as possible), but utilizing a system such as Event Manager will allow modules to partially override an event (i.e. only handle the event in certain situations), and will allow any module to listen for an event (without handling it) before or after the event is handled.&lt;br /&gt;
&lt;br /&gt;
== Plot Property ==&lt;br /&gt;
&lt;br /&gt;
Scripts that impact all campaigns should respect the plot property on resources. For example, if a campaign author has flagged an NPC as plot, it might not be helpful to change the creature AI.&lt;br /&gt;
&lt;br /&gt;
== Open Source ==&lt;br /&gt;
&lt;br /&gt;
If mod authors choose to publish their source code, with no restrictions on re-deployment, other builders can work around any residual incompatibilities (either by understanding the conflict more clearly, or by integrating the mod into their own work).&lt;br /&gt;
&lt;br /&gt;
This technical wiki is not the place to discuss any legal or ethical considerations.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== What if my mod extends both Single Player and Awakening? ===&lt;br /&gt;
&lt;br /&gt;
Just create two dazips for your module. Name one yourprefix_yourmodule_version and the other yourprefix_yourmodule_EP1_version.&lt;br /&gt;
&lt;br /&gt;
Edit the Manifest.xml file inside  yourprefix_yourmodule_EP_1_version.dazip.&lt;br /&gt;
Change the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt; to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule_EP_1&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;200&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Talk:Compatibility | Discussion]]&lt;br /&gt;
&lt;br /&gt;
=== How can I import an item with my existing character to a new campaign? ===&lt;br /&gt;
&lt;br /&gt;
The Awakening expansion allows an existing character to be imported from one campaign to another.&lt;br /&gt;
&lt;br /&gt;
There are two methods of ensuring that an item in the player's inventory is imported successfully:&lt;br /&gt;
&lt;br /&gt;
* Make the item a core resource&lt;br /&gt;
* Include the item template in separate add-ins to both campaigns (see Awakening example above)&lt;br /&gt;
&lt;br /&gt;
=== How can I stop items being imported into my campaign? ===&lt;br /&gt;
&lt;br /&gt;
Assuming your campaign allows existing characters to be imported during Character Generation, you might want to clear the player's inventory before adding your starting equipment. Imported equipment might upset the balance of your campaign.&lt;br /&gt;
&lt;br /&gt;
If you decide to do this, it's a good idea to warn players, so that they understand what's happening.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15320</id>
		<title>Talk:Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Compatibility&amp;diff=15320"/>
				<updated>2010-12-30T12:43:05Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource scope edit */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What if my mod extends both Single Player and Awakening? ==&lt;br /&gt;
&lt;br /&gt;
I moved this section here because it's under discussion. [[User:Proleric1|Proleric1]] 08:27, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
=============== &lt;br /&gt;
NOTE:&lt;br /&gt;
&lt;br /&gt;
There is an easier way than creating two scripts. Just put the information for both in the manifest.xml file. For one of my mods, the manifest file looked like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; standalone=&amp;quot;yes&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;Manifest Type=&amp;quot;AddIn&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;AddInsList&amp;gt;&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Description DefaultText=&amp;quot;ELF the pet cat adds a 'Cat Toy' to the players inventory (rest of text deleted for brevity)&lt;br /&gt;
&lt;br /&gt;
((This package will work in both DAO and Awakening!))&amp;quot;&amp;gt;&amp;lt;/Description&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;packages/&amp;quot; Type=&amp;quot;package&amp;quot;/&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;AddInItem UID=&amp;quot;elf_cat_pet&amp;quot; Name=&amp;quot;ELF the pet cat for DAO and Awakening&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;Title DefaultText=&amp;quot;ELF the pet cat&amp;quot;&amp;gt;&amp;lt;/Title&amp;gt;&lt;br /&gt;
			&amp;lt;Image&amp;gt;ico_elf_cat_sleep&amp;lt;/Image&amp;gt;&lt;br /&gt;
			&amp;lt;Rating DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/Rating&amp;gt;&lt;br /&gt;
			&amp;lt;RatingDescription DefaultText=&amp;quot;&amp;quot;&amp;gt;&amp;lt;/RatingDescription&amp;gt;&lt;br /&gt;
			&amp;lt;URL DefaultText=&amp;quot;www.ELFpath.com&amp;quot;&amp;gt;&amp;lt;/URL&amp;gt;&lt;br /&gt;
			&amp;lt;ReleaseDate&amp;gt;6 April 2010&amp;lt;/ReleaseDate&amp;gt;&lt;br /&gt;
			&amp;lt;Version&amp;gt;2.0&amp;lt;/Version&amp;gt;&lt;br /&gt;
			&amp;lt;GameVersion/&amp;gt;&lt;br /&gt;
			&amp;lt;Type&amp;gt;1&amp;lt;/Type&amp;gt;&lt;br /&gt;
			&amp;lt;Publisher DefaultText=&amp;quot;Angel == monkeysnest@yahoo.com&amp;quot;&amp;gt;&amp;lt;/Publisher&amp;gt;&lt;br /&gt;
			&amp;lt;PrereqList/&amp;gt;&lt;br /&gt;
			&amp;lt;FileList&amp;gt;&lt;br /&gt;
				&amp;lt;Folder src=&amp;quot;addins/&amp;quot; Type=&amp;quot;addin&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/FileList&amp;gt;&lt;br /&gt;
		&amp;lt;/AddInItem&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;/AddInsList&amp;gt;&lt;br /&gt;
&amp;lt;/Manifest&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
doing this allowed users to install one package (using DAModder) which worked for both awakening and DAO.&lt;br /&gt;
&lt;br /&gt;
============== ++ Angel&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@monkeysnest - good to have the update concerning the manifest. A few queries:&lt;br /&gt;
&lt;br /&gt;
* Perhaps the article would be clearer if you explained which line has to change, rather than reproduce the entire manifest here?&lt;br /&gt;
&lt;br /&gt;
* Would DAUpdater work? I don't see DAModder listed as a project download on the Bioware social site.&lt;br /&gt;
&lt;br /&gt;
* We don't normally leave our signatures on the content pages of a wiki.&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
[[User:Proleric1|Proleric1]] 05:47, 8 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I don't think the &amp;quot;dual entry, single manifest&amp;quot; approach should be followed or encouraged.  Creating two separate .dazip installations as mentioned in [[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | Compatibility: What if my mod extends both Single Player and Awakening?]] is IMHO the preferred approach.&lt;br /&gt;
&lt;br /&gt;
--[[User:Nukenin|Nukenin]] 00:24, 24 April 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I'll have to agree with Nukenin here, especially since using the &amp;quot;dual entry, single manifest&amp;quot; approach will cause DAUpdater to crash and would unnecessarily force players to use third-party apps. Moreover, it's perfectly possible to include several addons (each one with its own manifest entry) in a single dazip package :&lt;br /&gt;
* Package root&lt;br /&gt;
** Manifest including several AddInItem elements&lt;br /&gt;
** Contents&lt;br /&gt;
*** addins&lt;br /&gt;
**** addin_uid1&lt;br /&gt;
**** addin_uid2&lt;br /&gt;
**** addin_uid3&lt;br /&gt;
**** etc&lt;br /&gt;
*** packages&lt;br /&gt;
&lt;br /&gt;
--[[User:Phaenan|Phaenan]] 06:45, 21 July 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
I find myself agreeing with Phaenan and Nukenin on this; end users should only use community created tools if they want a specific function that's only available to them that way (like the ability to uninstall a dazip). &lt;br /&gt;
[[User:Ladydesire|Ladydesire]] 18:40, 25 December 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Override Events while minimizing compat issues.. ==&lt;br /&gt;
&lt;br /&gt;
I believe this may be useful to others - through trial and error, and with some help, I have figured out a way to override events only when my module is running - I had to add a variable to var_module.xls/gda (which is probably where the only potential compatibility issue will arise via string ID, though I am not sure what would happen if someone tried to override the same events - depends on which engineevents get's loaded last I suppose...).&lt;br /&gt;
&lt;br /&gt;
The variable is defaulted to a 0....in my modules properties, I set the variable to a 1. My event overrides check for this variable to be == 1, if not, send it off the proper handler. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See the following post where I came to this 'workaround'...would love to know if there is a better way:&lt;br /&gt;
&lt;br /&gt;
http://social.bioware.com/forum/1/topic/8/index/2371093/1#2531362&lt;br /&gt;
&lt;br /&gt;
== Resource scope edit ==&lt;br /&gt;
&lt;br /&gt;
I have removed the reference to tint maps following the discussion at http://social.bioware.com/group/2937/discussion/12738/ .&lt;br /&gt;
&lt;br /&gt;
Also beefed up the recommendations about not putting files into packages --[[User:Gaxkang55|Gaxkang55]] 12:43, 30 December 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15319</id>
		<title>Compatibility</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Compatibility&amp;diff=15319"/>
				<updated>2010-12-30T12:38:48Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Resource Scope */ See talk page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;DAO has an active modding community. Over time, players will accumulate many new campaigns and game mods. So, as a courtesy to players and other builders, it's helpful to try to make our mods mutually compatible. &lt;br /&gt;
&lt;br /&gt;
From time to time, Bioware may well issue new releases, so it's good to reduce the risk of conflict in that respect, too. &lt;br /&gt;
&lt;br /&gt;
Since we can't be sure that all authors will respect compatibility considerations, the emphasis here is on techniques that reduce the risk of conflict, regardless of what other people do (though not all are foolproof).&lt;br /&gt;
&lt;br /&gt;
Obviously, there are some conflicts with no win-win (hurlocks can't be both green and purple at the same time), but that doesn't stop us trying to avoid unnecessary win-lose or corruption.&lt;br /&gt;
&lt;br /&gt;
We begin with a concrete example - a tutorial on script conflict in OC mods, which is one of the most common problems to avoid. The remainder of the page is a more systematic discussion, which applies to both OC mods and custom campaigns.    &lt;br /&gt;
&lt;br /&gt;
== Tutorial to ensure your Awakening mod will not break Origins and vice versa!!! (includes screenshots and script code) ==&lt;br /&gt;
&lt;br /&gt;
I'm hoping to save my modding friends some time. (Tutorial by Immortality)&lt;br /&gt;
&lt;br /&gt;
'''Remember: IT'S YOUR RESPONSIBILITY TO ENSURE YOUR MOD DOES NOT BREAK THE GAME, THE EXPANSION, DLCS, OR OTHER MODS!!'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The problem:'''''&lt;br /&gt;
&lt;br /&gt;
- While working in my Origins mod, and then on my Awakening mod, I realized that my Origins mod was breaking Awakening (scripts were not triggering, and even objects were moving around!).&lt;br /&gt;
&lt;br /&gt;
- In the same way, my mod for Awakening was interfeering in Origins, breaking it (wrong scripts triggering, destroying the party recruiting).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''The objective:'''''&lt;br /&gt;
&lt;br /&gt;
- Prevent the Origins mod to interfere with Awakening. If your mod is for Origins, it should only work in Origins.&lt;br /&gt;
&lt;br /&gt;
- Prevent the Awakening mod to interfere with Origins. If your mod is for Awakening, it should only work in Awakening.&lt;br /&gt;
&lt;br /&gt;
- If you have one mod for both, to ensure that the Origins part triggers in Origins and Awakening part in Awakening.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Procedure:'''''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''1- Ensure your Origins mod is for Origins only!'''&lt;br /&gt;
&lt;br /&gt;
NEVER EVER EVER set your core scripts or handling scripts as Core Game Resources. NEVER!&lt;br /&gt;
&lt;br /&gt;
There's absolutely no need for your scripts (especially your module core) to be a core game resource.&lt;br /&gt;
&lt;br /&gt;
This means that whenever you create a mod for origins you should always set the properties of your major handling scripts as &amp;quot;Module: your module&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. NEVER as a core game resource. Otherwise they will interfere with awakening and will break it (make no mistake, they will).&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
This is how you set your Origins module: [[image:Originshierarchy.jpg]]&lt;br /&gt;
&lt;br /&gt;
This is how you set all your script's properties: [[image:Originsproperties.jpg]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''2- Ensure your Awakening mod is for Awakening only!'''&lt;br /&gt;
&lt;br /&gt;
Things are different for Awakening because you DO have to set all your materials' properties as &amp;quot;Module: Core Game Resources&amp;quot;, and &amp;quot;Owner Module: your module&amp;quot;. (read the tutorial if you need to know more: http://social.bioware.com/53295/blog/10858/ )&lt;br /&gt;
&lt;br /&gt;
This means that your Awakening mod will interfere with Origins and will break the game.&lt;br /&gt;
&lt;br /&gt;
We will use a plot flag check to ensure that your module core script and handling scripts only trigger in Awakening.&lt;br /&gt;
&lt;br /&gt;
You should insert this code in all your handling scripts:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 if(!WR_GetPlotFlag(&amp;quot;C0B7199C74CA4B67B143ACA8CDCFCF9D&amp;quot;,0, TRUE))&lt;br /&gt;
 return;&lt;br /&gt;
&lt;br /&gt;
Where &amp;quot;C0B7199C74CA4B67B143ACA8CDCFCF9D&amp;quot; is actually gxa000pt_awakening,plo, and &amp;quot;0&amp;quot;, is &amp;quot;GXA_AWAKENING_START&amp;quot;, but you can use any other Awakening plot that you may need.&lt;br /&gt;
&lt;br /&gt;
Please read this tutorial to learn how to mod using Awakening's plot flags: http://social.bioware.com/53295/blog/10881/&lt;br /&gt;
(For for people who don't know how to script, like me, this tells the game not to run the script unless GXA_AWAKENING_START is true.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Screenshots of my Awakening handling scripts with the code inserted: &lt;br /&gt;
[[image:Awakening1.jpg]] [[image:Awakening2.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''OR'''&lt;br /&gt;
&lt;br /&gt;
(From TimelordDC)&lt;br /&gt;
&lt;br /&gt;
Use IsUsingEP1Resources() [returns TRUE or FALSE] instead of that plot flag check.&lt;br /&gt;
&lt;br /&gt;
Origins code itself has a lot of code that was written for Awakening and in all cases, they use this function to check if Awakening is being used or not.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Immortality's editor note: Instead of my code, you can use '''IsUsingEP1Resources()''', which is probably safer. :-)&lt;br /&gt;
&lt;br /&gt;
And as always... BE CAREFUL! :-)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Addendum:''' If you have copy-pasted scripts, for example your follower join script, it can still mess your Origins mod, even with the checks implemented!!!&lt;br /&gt;
&lt;br /&gt;
In order to avoid this, you can rename your functions.&lt;br /&gt;
For example, if your Origins script has the function &amp;quot;SetFollowerInParty&amp;quot;, then rename the function in your Awakening script to &amp;quot;SetFollowerInParty_awakening&amp;quot;, and etc.&lt;br /&gt;
&lt;br /&gt;
== Disable Add-Ins : Suggested Disclaimer ==&lt;br /&gt;
&lt;br /&gt;
If the player disables all other add-ins on the in game DLC screen, no conflict should occur between them. Tedious, but effective.&lt;br /&gt;
&lt;br /&gt;
This should rarely be necessary if the compatibility guidelines listed here are observed.&lt;br /&gt;
&lt;br /&gt;
Exception : there is a [[Bug:_export_creates_unnecessary_core_override | toolset bug]] which produces content that persists in game, even when the add-in is disabled, unless the builder cleans it out before making the Builder-to-Player file. The same problem can occur if a builder has intentionally placed content in the packages\override folder (which should normally be avoided, as it is very rarely necessary).&lt;br /&gt;
&lt;br /&gt;
Mod authors can work together to set player expectations in this respect. For example, the installation instructions might say &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;Reasonable steps have been taken to make this mod compatible. &lt;br /&gt;
Obviously, the author has no control over the quality of other mods you may have installed. &lt;br /&gt;
So, to reduce the risk of conflict, you are are strongly advised to move all files out of your &lt;br /&gt;
packages\override folders, and consider disabling unnecessary community mods on your in-game &lt;br /&gt;
DLC screen, before playing.&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Module Scope ==&lt;br /&gt;
&lt;br /&gt;
Setting the Extended Module in Module properties to &amp;quot;Core Game Resources&amp;quot; means that the add-in will change every campaign in game. If that's not intended, select the campaign you're trying to extend e.g. Single Player for the official campaign, (None) for a new standalone campaign.&lt;br /&gt;
&lt;br /&gt;
[[Compatibility#What_if_my_mod_extends_both_Single_Player_and_Awakening.3F | What if my mod extends both Single Player and Awakening?]]&lt;br /&gt;
&lt;br /&gt;
== Resource Scope ==&lt;br /&gt;
&lt;br /&gt;
By default, the toolset exports design resources to your addin's module override folder. That's a good thing, because it ensures that the scope of the resources is confined to your addin (and any that extend it). There's less risk of corrupting other people's work that way.&lt;br /&gt;
&lt;br /&gt;
Never put resources in the packages folder, because that impacts every campaign. Also, once a player has installed resources there, they persist, even when your add-in is disabled. &lt;br /&gt;
&lt;br /&gt;
It appears the packages folder has to be used for resources that won't load from the addins folder, namely &lt;br /&gt;
&lt;br /&gt;
* The Talk Table (see [[Bug:_Talk_table_exported_to_packages_override | bug]]) that overrides existing game strings. Best practice is to avoid doing this in the first place.&lt;br /&gt;
* The chargenmorphcfg.xml file, which can be used to add new morph presets for character generation.&lt;br /&gt;
&lt;br /&gt;
It was reported that tint maps needed to be in packages, but this was based on a misunderstanding. &lt;br /&gt;
&lt;br /&gt;
Normally, it's not a good idea to make new core resources. It's easy to make a new core resource accidentally when duplicating an official core resource, because the Owner Module defaults to core. This isn't obvious, but the resource will export to your addin's core override folder.      &lt;br /&gt;
&lt;br /&gt;
Exception : items cannot be imported to a new campaign with the player character unless the template is included in both campaigns. One way of doing that is to make it a core resource.   &lt;br /&gt;
&lt;br /&gt;
Art resources posted to local are always sent to the module's core override folder. Fortunately, the core override folder only affects the campaign extended (if any), the addin and any that extend it. Many of those resources can in any case be moved to the module folder and still work.&lt;br /&gt;
&lt;br /&gt;
There are a large number of mods available that use the packages folder, creating headaches for other modders and often users since such overwrites cannot be turned off in the game GUI. Users should be told to avoid mods whose method of installation is &amp;quot;place this folder in packages\override&amp;quot; and to delete any content that is currently in that folder. Mods not properly organised into dazips and installed with the Bioware supplied daupdater should also be deprecated, unless a good reason is given why they are being distributed that way.&lt;br /&gt;
&lt;br /&gt;
== Resource Conflict ==&lt;br /&gt;
&lt;br /&gt;
Resource names need to be unique within type. For example, genpt_party.plt and genpt_party.nss are different resources, becasue the type is different. However, if two modules both have resources called genpt_party.plt, only one will load in game, following the [[Source directory priorities]]. &lt;br /&gt;
&lt;br /&gt;
Within the toolset database, duplicate resource names are forbidden, but there's nothing to stop different builders making resources which accidentally conflict, so it's wise to choose a unique range of names. Each builder can register the prefix they require. See [[Naming_conventions#Resource_Naming_Convention | Resource Naming Convention]] and especially [[Prefixes in use]].&lt;br /&gt;
&lt;br /&gt;
It is possible to override a core resource intentionally, by editing a copy, exporting it, and renaming it in the export folder to the same name as the original. However, almost invariably there is a cleaner way of doing this - for example, by changing the 2DA which identifies which resource to use.&lt;br /&gt;
 &lt;br /&gt;
== Existing Content Modification ==&lt;br /&gt;
&lt;br /&gt;
When adding new content or content hooks to existing areas, do not modify the area directly and deploy the modified area as an override with your mod. This is incompatible with other mods trying to edit the same area since only one modified version of the area will &amp;quot;win&amp;quot;, and changes made by other mods to that area will not be available. Instead, use the [[PRCSCR]] system to add new content to existing areas.&lt;br /&gt;
&lt;br /&gt;
== 2DA Conflict ==&lt;br /&gt;
&lt;br /&gt;
Conflict between 2DA mods can be reduced using the [[2DA#Extending_the_game_via_M2DAs | M2DA]] mechanism and [[2DA#Reserved_ID_Ranges_and_overriding_existing_rows | reserving ID ranges]].&lt;br /&gt;
&lt;br /&gt;
2DA mods should normally be placed in the add-in's module folder. Exception : if they are meant to be universally applied to all campaigns, they should be in the addin/core/override folder. The packages override folder should normally be avoided (because that removes control from the player, by forcing the 2DA to load even if the player has disabled the add-in).&lt;br /&gt;
&lt;br /&gt;
== String Conflict ==&lt;br /&gt;
&lt;br /&gt;
When a new module is created, its properties include a [[String ID]] range which starts at a very large random number. This makes it very unlikely that text created by one add-in will override another.&lt;br /&gt;
&lt;br /&gt;
See [[String ID]] main article for a discussion of how this impacts sharing between Builders.&lt;br /&gt;
&lt;br /&gt;
The [[String editor]] article discusses techniques for editing strings which are outside of the module's normal range. It is not normally necessary to customise core strings directly, but if there is no alternative, change the Owner Module to the current module, and the Table to the current module's talk table. Otherwise, the custom string will override all campaigns.&lt;br /&gt;
&lt;br /&gt;
== Event Handling Conflict ==&lt;br /&gt;
&lt;br /&gt;
Bear in mind that an add-in which impacts all campaigns could have undesirable consequences if it changes scripts or event-handling, given that custom campaigns may well have made changes of their own. If in doubt, consider modding the Single Player campaign only.&lt;br /&gt;
&lt;br /&gt;
See [[Event_override | event override]] for recommended methods of intercepting events.&lt;br /&gt;
&lt;br /&gt;
Note that script resources are never overwritten in these methods. Conceptually, the event is intercepted by a custom script, then passed on (unless the event has been handled successfully and further processing would be harmful). In this way, mods try not to interfere unnecessarily with other scripts.&lt;br /&gt;
&lt;br /&gt;
Given the variety of actions that can be taken in a script, and that fact that one mod can't know what other mods are trying to do, we can't guarantee that this approach will be entirely free of logical problems, but the Perfect is the enemy of the Good. &lt;br /&gt;
&lt;br /&gt;
The simplest and safest method is to assign a custom event script to a resource. This is likely to be used by custom campaigns, and also by Single Player mods to specific resources, as it is the approach that Bioware devs have often recommended.  &lt;br /&gt;
&lt;br /&gt;
Mods which aim to impact all campaigns globally are better advised to use the second method, i.e. overriding [[Event_(dascript_type) | event]] handling using an Events M2DA. As illustrated in the example script, if possible the event should be passed on to the default handler of the event's target object (which might be a custom event script). In this way, a global mod can be compatible with custom campaigns and specific resource mods. &lt;br /&gt;
&lt;br /&gt;
Unfortunately, if two mods simply try to override the same event with an M2DA, they will be incompatible.&lt;br /&gt;
&lt;br /&gt;
The best solution to override, partially override, or just listen for events via M2DA at this point would be to use a system such as [http://social.bioware.com/project/1907/#details Event Manager], though to ensure compatibility all modules overriding or listening for events should also be using the same system.&lt;br /&gt;
&lt;br /&gt;
In the case of modules trying to totally override an event, only one module that does so will ultimately &amp;quot;win&amp;quot; (no such modules can ever truly be compatible with one another short of merging their functionality into one unified module as possible), but utilizing a system such as Event Manager will allow modules to partially override an event (i.e. only handle the event in certain situations), and will allow any module to listen for an event (without handling it) before or after the event is handled.&lt;br /&gt;
&lt;br /&gt;
== Plot Property ==&lt;br /&gt;
&lt;br /&gt;
Scripts that impact all campaigns should respect the plot property on resources. For example, if a campaign author has flagged an NPC as plot, it might not be helpful to change the creature AI.&lt;br /&gt;
&lt;br /&gt;
== Open Source ==&lt;br /&gt;
&lt;br /&gt;
If mod authors choose to publish their source code, with no restrictions on re-deployment, other builders can work around any residual incompatibilities (either by understanding the conflict more clearly, or by integrating the mod into their own work).&lt;br /&gt;
&lt;br /&gt;
This technical wiki is not the place to discuss any legal or ethical considerations.&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
=== What if my mod extends both Single Player and Awakening? ===&lt;br /&gt;
&lt;br /&gt;
Just create two dazips for your module. Name one yourprefix_yourmodule_version and the other yourprefix_yourmodule_EP1_version.&lt;br /&gt;
&lt;br /&gt;
Edit the Manifest.xml file inside  yourprefix_yourmodule_EP_1_version.dazip.&lt;br /&gt;
Change the line&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;Single Player&amp;quot; Priority=&amp;quot;100&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt; to&lt;br /&gt;
&lt;br /&gt;
&amp;lt;AddInItem UID=&amp;quot;yourprefix_yourmodule_EP_1&amp;quot; Name=&amp;quot;Your Module Name&amp;quot; ExtendedModuleUID=&amp;quot;DAO_PRC_EP_1&amp;quot; Priority=&amp;quot;200&amp;quot; Enabled=&amp;quot;1&amp;quot; State=&amp;quot;2&amp;quot; Format=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See also [[Talk:Compatibility | Discussion]]&lt;br /&gt;
&lt;br /&gt;
=== How can I import an item with my existing character to a new campaign? ===&lt;br /&gt;
&lt;br /&gt;
The Awakening expansion allows an existing character to be imported from one campaign to another.&lt;br /&gt;
&lt;br /&gt;
There are two methods of ensuring that an item in the player's inventory is imported successfully:&lt;br /&gt;
&lt;br /&gt;
* Make the item a core resource&lt;br /&gt;
* Include the item template in separate add-ins to both campaigns (see Awakening example above)&lt;br /&gt;
&lt;br /&gt;
=== How can I stop items being imported into my campaign? ===&lt;br /&gt;
&lt;br /&gt;
Assuming your campaign allows existing characters to be imported during Character Generation, you might want to clear the player's inventory before adding your starting equipment. Imported equipment might upset the balance of your campaign.&lt;br /&gt;
&lt;br /&gt;
If you decide to do this, it's a good idea to warn players, so that they understand what's happening.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Overriding_and_creating_tints_tutorial&amp;diff=15299</id>
		<title>Talk:Overriding and creating tints tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Overriding_and_creating_tints_tutorial&amp;diff=15299"/>
				<updated>2010-12-25T20:33:32Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: Created page with 'This is terrible advice on several fronts. If core game resources are to overwritten  by a mod, then disabling the mod through the game GUI should turn off the overwrite. Nothing...'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is terrible advice on several fronts. If core game resources are to overwritten  by a mod, then disabling the mod through the game GUI should turn off the overwrite. Nothing should go into packages unless it absolutely has to, which is certainly not the case here. I may put a note on this after I finish an alternative tutorial on the tint system. Would welcome any discussion in the meantime since it goes to the broader question of good and bad modding practices. --[[User:Gaxkang55|Gaxkang55]] 20:33, 25 December 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15266</id>
		<title>Reskinning an item tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15266"/>
				<updated>2010-12-22T13:01:11Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* General considerations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
This tutorial describes how to reskin, or change the default texture, of items that already exist in-game. As an example, the default textures of the human female mage's apprentice robes will be changed.&lt;br /&gt;
&lt;br /&gt;
Tools needed are the Dragon Age Toolset, and a grafic editing Applications capable of Opening, Editing and Saving DDS Texture Files.&lt;br /&gt;
&lt;br /&gt;
==General considerations==&lt;br /&gt;
Most armor and weapons have a tint map, and if the aim is simply to recolor a model, then a custom tint should be used. In any case, recoloring a model which already has a tint applied will either not work or lead to unpredictable results. Additionally, a custom tint file has the advantage of working for both high and medium textures at all LOD. See below for further tutorials. However, there are situations where creating/modifying textures is appropriate, but in those situations it is preferable to create a new item variation and associated machinery to '''add''' the texture rather than overwriting an existing game resource.&lt;br /&gt;
&lt;br /&gt;
== Locating the Model Textures the Hard Way==&lt;br /&gt;
&lt;br /&gt;
At the beginning, you only know how the [[Model]] looks and what its called. A somewhat difficult task will be finding out which files are tied to the model so that you can edit them. &lt;br /&gt;
&lt;br /&gt;
First and foremost, you are looking for DDS Files. How DDS Files are referenced by an Item you see in Game is a long list of database references.&lt;br /&gt;
&lt;br /&gt;
A quick rundown on references we need to be aware of&lt;br /&gt;
&lt;br /&gt;
#A DDS File is referenced by the Material Properties of a [[Model]]&lt;br /&gt;
#A [[Model]] is then referenced by the &amp;quot;ItemVariation&amp;quot; type of files. In our example, the sub &amp;quot;clothing_variation.gda&amp;quot;&lt;br /&gt;
#The different Clothing Variations are then referenced by the Item Type made via the Toolset&lt;br /&gt;
#The Item Type is lastly referenced by the Game, when choosing which gender and race this item is worn. And then displays the final version in your game.&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To track back to the DDS File, you need to run up this list in reverse. Starting up our example, the mages apprentice robe, as it is worn by human females. &lt;br /&gt;
&lt;br /&gt;
#Open up the Toolset and in the Resource Palette on the upper right click on &amp;quot;Items&amp;quot; (appears as a sword icon). Now comes guessing where this piece is to be found there. These Items are pretty well sorted though, it is to be found under _global / Clothing / Mage Robes / Unique. In the following list you see the ResourceName followed by ItemName &amp;quot;gen_im_cth_mag_app (Apprentice Robes)&amp;quot;. Any Item can be found in the &amp;quot;Item&amp;quot; Category.  Doubleclick that entry to look inside.&lt;br /&gt;
#In the listing of information that appears to the left of the item, note that the &amp;quot;Base Item Type&amp;quot; is &amp;quot;Clothing&amp;quot;, which is branching off into the Item Variation. The robe has a &amp;quot;Item Variation&amp;quot; called &amp;quot;Robe, Apprentice&amp;quot;. Variation in mind, onto the next step.&lt;br /&gt;
#Open up the &amp;quot;ItemVariations.xls&amp;quot; File located under &amp;quot;(dragon age install directory)/tools/Source/2da/rules&amp;quot;. It has many pages, locate page &amp;quot;clothing_variation&amp;quot; since we know our &amp;quot;Base Item Type&amp;quot; is of &amp;quot;Clothing&amp;quot;. In there, locate the Row called whatever Item Variation your Item had. &amp;quot;Robe, Apprentice&amp;quot; has Namestrings followed by &amp;quot;rob&amp;quot; &amp;quot;app&amp;quot; &amp;quot;a&amp;quot;.&lt;br /&gt;
#With these 3 Strings, and Dragon Age's [[Naming conventions|Naming Scheme]] you can find the [[MMH]] Main Modelfile.&lt;br /&gt;
#At the end of MMH file (extract, open and Expand All with the toolset), is the reference to the material object filename (page up two or three times from the end of the file).&lt;br /&gt;
#And inside the [[MAO]] File (open with Notepad) are the references to the texture filenames.&lt;br /&gt;
&lt;br /&gt;
Spend a little time browsing through these files, and the naming convention will become clear. The armor prefixes are a compound of a &amp;quot;race&amp;quot; letter -- h, d, e, q, k (for children) and p (for person, or humanoid) -- and a gender letter -- m, f or n. For instance, a Chest mesh (the actual model or msh file) is by necessity both race and usually gender specific, several mmh files will usually reference one msh and are prefixed similarly, while textures will map to any model with the correct UV map, so usually begin with &amp;quot;p&amp;quot; and may or may not be gender specific. Once you understand the prefixes, the textures can usually be located quickly in the relevant erf, with the part code (where applicable) coming next, followed by the item variation code, followed by the texture code.&lt;br /&gt;
&lt;br /&gt;
(There are some anomalies: for instance Ancient Elven Armor is listed in the toolset as Medium Armor E, but is in fact heavy armor so has an item variation code of &amp;quot;hvye&amp;quot; (it also has no tint map, being a one-off piece), but such cases are not too hard to track down once you understand the overall schema.)&lt;br /&gt;
&lt;br /&gt;
== Extracting the Texture from the Package ==&lt;br /&gt;
&lt;br /&gt;
Model textures are located in two &amp;quot;texturepack.erf&amp;quot; [[ERF]] packages, corresponding to high resolution and medium resolution textures. These packages can be found in the (dragon age install directory)\packages\core\textures\ folder. For example, the packages might be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\textures\high\texturepack.erf&lt;br /&gt;
C:\Program Files\Dragon Age\packages\core\textures\medium\texturepack.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drag and drop these ERF Files onto the Toolset to browse and extract their content. If you have the Name, finding the Files will be easy. The Files will be in both &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot; and the quality setting in the game will decide which to choose. To make it compatible enough, taking them all may be neccessary.&lt;br /&gt;
&lt;br /&gt;
Incidentally, high and medium texture versions are only required for certain model types. For example, heraldry and props only have one texture, and these can be found in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\data\textures.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prepare for extracting the textures, we must create a directory mimicking the structure of the Dragon Age packages folder. To do this, create a new folder named &amp;quot;textures&amp;quot; in a convenient location (for example, on your desktop). Inside this folder, create two new folders, named &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot;. The &amp;quot;high&amp;quot; folder will be where the high-resolution textures are extracted to, and the &amp;quot;medium&amp;quot; folder will be where the medium-resolution textures are extracted to.&lt;br /&gt;
&lt;br /&gt;
For this tutorial, we are interested in the mage's robes. To locate the textures of the mage's robes, scroll down to &amp;quot;pf_rob_appa_0d.dds&amp;quot; in one of the two texturepack ERFs. In each texturepack.erf, select all of the image files prefixed with &amp;quot;pf_rob_appa&amp;quot; (from &amp;quot;pf_rob_appa_0d.dds&amp;quot; to &amp;quot;pf_rob_appa_0tl3.dds&amp;quot;). For the high-resolution texturepack.erf, extract these images to the &amp;quot;textures\high\&amp;quot; folder just created. Extract the medium-resolution textures to the &amp;quot;textures\medium\&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
The Suffixes for Texturefiles are describing their Formats, which is described under [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
To extract one of the textures, right-click on it and select &amp;quot;Extract Resource.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Editing the Textures ==&lt;br /&gt;
&lt;br /&gt;
At this stage, if we wanted to edit the existing robe textures, we could do so by changing these files. See [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
Once this has been done for all of the robe textures (in both the &amp;quot;High&amp;quot; and &amp;quot;Medium&amp;quot; folders), we'll be ready to override the default textures in Dragon Age.&lt;br /&gt;
&lt;br /&gt;
== Overriding the Existing Textures ==&lt;br /&gt;
[[Image:Demo-retexture.jpg|thumb|The end result: reskinned default mage robes.]]&lt;br /&gt;
&lt;br /&gt;
Comment : this section doesn't agree with the guidance on [[Compatibility]]. Surely textures should be placed in the module's texture folder?  &lt;br /&gt;
&lt;br /&gt;
To override the existing textures, copy the &amp;quot;textures&amp;quot; folder containing the modified textures, and paste this folder into the Dragon Age override folder. The override folder is found in:&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
for Windows Vista and 7, and in a similar location on Windows XP.&lt;br /&gt;
&lt;br /&gt;
So, after pasting in the modified textures, the structure of the override folder should look like this:&lt;br /&gt;
&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
**textures&lt;br /&gt;
***high&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
***medium&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
&lt;br /&gt;
== Further Tutorials ==&lt;br /&gt;
&lt;br /&gt;
[[Tutorial: Creating recolors of existing items]] - A way to change the tint of the new texture&lt;br /&gt;
&lt;br /&gt;
== Related Links ==&lt;br /&gt;
&lt;br /&gt;
[[Texture Formats]] - Texture formats in detail.&lt;br /&gt;
&lt;br /&gt;
[[Art Resources]] - Broad topic of Art Resources, which textures are a part of.&lt;br /&gt;
&lt;br /&gt;
[[category:tutorials]]&lt;br /&gt;
[[Category:Textures]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15265</id>
		<title>Reskinning an item tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15265"/>
				<updated>2010-12-22T12:52:25Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
This tutorial describes how to reskin, or change the default texture, of items that already exist in-game. As an example, the default textures of the human female mage's apprentice robes will be changed.&lt;br /&gt;
&lt;br /&gt;
Tools needed are the Dragon Age Toolset, and a grafic editing Applications capable of Opening, Editing and Saving DDS Texture Files.&lt;br /&gt;
&lt;br /&gt;
==General considerations==&lt;br /&gt;
Most armor and weapons have a tint map, and if the aim is simply to recolor a model, then a custom tint should be used. In any case, recoloring a model which has a tint applied will either not work or lead to unpredictable results. See below for further tutorials. However, there are situations where creating/modifying textures is appropriate, but in those situations it is preferable to create a new item variation and associated machinery to ''''add'''' the texture rather than overwriting an existing ingame resource.&lt;br /&gt;
&lt;br /&gt;
== Locating the Model Textures the Hard Way==&lt;br /&gt;
&lt;br /&gt;
At the beginning, you only know how the [[Model]] looks and what its called. A somewhat difficult task will be finding out which files are tied to the model so that you can edit them. &lt;br /&gt;
&lt;br /&gt;
First and foremost, you are looking for DDS Files. How DDS Files are referenced by an Item you see in Game is a long list of database references.&lt;br /&gt;
&lt;br /&gt;
A quick rundown on references we need to be aware of&lt;br /&gt;
&lt;br /&gt;
#A DDS File is referenced by the Material Properties of a [[Model]]&lt;br /&gt;
#A [[Model]] is then referenced by the &amp;quot;ItemVariation&amp;quot; type of files. In our example, the sub &amp;quot;clothing_variation.gda&amp;quot;&lt;br /&gt;
#The different Clothing Variations are then referenced by the Item Type made via the Toolset&lt;br /&gt;
#The Item Type is lastly referenced by the Game, when choosing which gender and race this item is worn. And then displays the final version in your game.&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To track back to the DDS File, you need to run up this list in reverse. Starting up our example, the mages apprentice robe, as it is worn by human females. &lt;br /&gt;
&lt;br /&gt;
#Open up the Toolset and in the Resource Palette on the upper right click on &amp;quot;Items&amp;quot; (appears as a sword icon). Now comes guessing where this piece is to be found there. These Items are pretty well sorted though, it is to be found under _global / Clothing / Mage Robes / Unique. In the following list you see the ResourceName followed by ItemName &amp;quot;gen_im_cth_mag_app (Apprentice Robes)&amp;quot;. Any Item can be found in the &amp;quot;Item&amp;quot; Category.  Doubleclick that entry to look inside.&lt;br /&gt;
#In the listing of information that appears to the left of the item, note that the &amp;quot;Base Item Type&amp;quot; is &amp;quot;Clothing&amp;quot;, which is branching off into the Item Variation. The robe has a &amp;quot;Item Variation&amp;quot; called &amp;quot;Robe, Apprentice&amp;quot;. Variation in mind, onto the next step.&lt;br /&gt;
#Open up the &amp;quot;ItemVariations.xls&amp;quot; File located under &amp;quot;(dragon age install directory)/tools/Source/2da/rules&amp;quot;. It has many pages, locate page &amp;quot;clothing_variation&amp;quot; since we know our &amp;quot;Base Item Type&amp;quot; is of &amp;quot;Clothing&amp;quot;. In there, locate the Row called whatever Item Variation your Item had. &amp;quot;Robe, Apprentice&amp;quot; has Namestrings followed by &amp;quot;rob&amp;quot; &amp;quot;app&amp;quot; &amp;quot;a&amp;quot;.&lt;br /&gt;
#With these 3 Strings, and Dragon Age's [[Naming conventions|Naming Scheme]] you can find the [[MMH]] Main Modelfile.&lt;br /&gt;
#At the end of MMH file (extract, open and Expand All with the toolset), is the reference to the material object filename (page up two or three times from the end of the file).&lt;br /&gt;
#And inside the [[MAO]] File (open with Notepad) are the references to the texture filenames.&lt;br /&gt;
&lt;br /&gt;
Spend a little time browsing through these files, and the naming convention will become clear. The armor prefixes are a compound of a &amp;quot;race&amp;quot; letter -- h, d, e, q, k (for children) and p (for person, or humanoid) -- and a gender letter -- m, f or n. For instance, a Chest mesh (the actual model or msh file) is by necessity both race and usually gender specific, several mmh files will usually reference one msh and are prefixed similarly, while textures will map to any model with the correct UV map, so usually begin with &amp;quot;p&amp;quot; and may or may not be gender specific. Once you understand the prefixes, the textures can usually be located quickly in the relevant erf, with the part code (where applicable) coming next, followed by the item variation code, followed by the texture code.&lt;br /&gt;
&lt;br /&gt;
(There are some anomalies: for instance Ancient Elven Armor is listed in the toolset as Medium Armor E, but is in fact heavy armor so has an item variation code of &amp;quot;hvye&amp;quot; (it also has no tint map, being a one-off piece), but such cases are not too hard to track down once you understand the overall schema.)&lt;br /&gt;
&lt;br /&gt;
== Extracting the Texture from the Package ==&lt;br /&gt;
&lt;br /&gt;
Model textures are located in two &amp;quot;texturepack.erf&amp;quot; [[ERF]] packages, corresponding to high resolution and medium resolution textures. These packages can be found in the (dragon age install directory)\packages\core\textures\ folder. For example, the packages might be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\textures\high\texturepack.erf&lt;br /&gt;
C:\Program Files\Dragon Age\packages\core\textures\medium\texturepack.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drag and drop these ERF Files onto the Toolset to browse and extract their content. If you have the Name, finding the Files will be easy. The Files will be in both &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot; and the quality setting in the game will decide which to choose. To make it compatible enough, taking them all may be neccessary.&lt;br /&gt;
&lt;br /&gt;
Incidentally, high and medium texture versions are only required for certain model types. For example, heraldry and props only have one texture, and these can be found in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\data\textures.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prepare for extracting the textures, we must create a directory mimicking the structure of the Dragon Age packages folder. To do this, create a new folder named &amp;quot;textures&amp;quot; in a convenient location (for example, on your desktop). Inside this folder, create two new folders, named &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot;. The &amp;quot;high&amp;quot; folder will be where the high-resolution textures are extracted to, and the &amp;quot;medium&amp;quot; folder will be where the medium-resolution textures are extracted to.&lt;br /&gt;
&lt;br /&gt;
For this tutorial, we are interested in the mage's robes. To locate the textures of the mage's robes, scroll down to &amp;quot;pf_rob_appa_0d.dds&amp;quot; in one of the two texturepack ERFs. In each texturepack.erf, select all of the image files prefixed with &amp;quot;pf_rob_appa&amp;quot; (from &amp;quot;pf_rob_appa_0d.dds&amp;quot; to &amp;quot;pf_rob_appa_0tl3.dds&amp;quot;). For the high-resolution texturepack.erf, extract these images to the &amp;quot;textures\high\&amp;quot; folder just created. Extract the medium-resolution textures to the &amp;quot;textures\medium\&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
The Suffixes for Texturefiles are describing their Formats, which is described under [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
To extract one of the textures, right-click on it and select &amp;quot;Extract Resource.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Editing the Textures ==&lt;br /&gt;
&lt;br /&gt;
At this stage, if we wanted to edit the existing robe textures, we could do so by changing these files. See [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
Once this has been done for all of the robe textures (in both the &amp;quot;High&amp;quot; and &amp;quot;Medium&amp;quot; folders), we'll be ready to override the default textures in Dragon Age.&lt;br /&gt;
&lt;br /&gt;
== Overriding the Existing Textures ==&lt;br /&gt;
[[Image:Demo-retexture.jpg|thumb|The end result: reskinned default mage robes.]]&lt;br /&gt;
&lt;br /&gt;
Comment : this section doesn't agree with the guidance on [[Compatibility]]. Surely textures should be placed in the module's texture folder?  &lt;br /&gt;
&lt;br /&gt;
To override the existing textures, copy the &amp;quot;textures&amp;quot; folder containing the modified textures, and paste this folder into the Dragon Age override folder. The override folder is found in:&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
for Windows Vista and 7, and in a similar location on Windows XP.&lt;br /&gt;
&lt;br /&gt;
So, after pasting in the modified textures, the structure of the override folder should look like this:&lt;br /&gt;
&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
**textures&lt;br /&gt;
***high&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
***medium&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
&lt;br /&gt;
== Further Tutorials ==&lt;br /&gt;
&lt;br /&gt;
[[Tutorial: Creating recolors of existing items]] - A way to change the tint of the new texture&lt;br /&gt;
&lt;br /&gt;
== Related Links ==&lt;br /&gt;
&lt;br /&gt;
[[Texture Formats]] - Texture formats in detail.&lt;br /&gt;
&lt;br /&gt;
[[Art Resources]] - Broad topic of Art Resources, which textures are a part of.&lt;br /&gt;
&lt;br /&gt;
[[category:tutorials]]&lt;br /&gt;
[[Category:Textures]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15264</id>
		<title>Reskinning an item tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15264"/>
				<updated>2010-12-22T11:40:01Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Locating the Model Textures the Hard Way */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
This tutorial describes how to reskin, or change the default texture, of items that already exist in-game. As an example, the default textures of the human female mage's apprentice robes will be changed.&lt;br /&gt;
&lt;br /&gt;
Tools needed are the Dragon Age Toolset, and a grafic editing Applications capable of Opening, Editing and Saving DDS Texture Files.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The game utilizes Tints, which reuse the same Texture in colorized or tinted versions. Thus the texture in our example doesn't look quite as it does in game, and vice versa. If you edit the Texture, it won't look quite like that when put back into the game. The difference is merely color differences, so this process is limited. However, you can only change Tints, or both. See below for further tutorials.&lt;br /&gt;
&lt;br /&gt;
== Locating the Model Textures the Hard Way==&lt;br /&gt;
&lt;br /&gt;
At the beginning, you only know how the [[Model]] looks and what its called. A somewhat difficult task will be finding out which files are tied to the model so that you can edit them. &lt;br /&gt;
&lt;br /&gt;
First and foremost, you are looking for DDS Files. How DDS Files are referenced by an Item you see in Game is a long list of database references.&lt;br /&gt;
&lt;br /&gt;
A quick rundown on references we need to be aware of&lt;br /&gt;
&lt;br /&gt;
#A DDS File is referenced by the Material Properties of a [[Model]]&lt;br /&gt;
#A [[Model]] is then referenced by the &amp;quot;ItemVariation&amp;quot; type of files. In our example, the sub &amp;quot;clothing_variation.gda&amp;quot;&lt;br /&gt;
#The different Clothing Variations are then referenced by the Item Type made via the Toolset&lt;br /&gt;
#The Item Type is lastly referenced by the Game, when choosing which gender and race this item is worn. And then displays the final version in your game.&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To track back to the DDS File, you need to run up this list in reverse. Starting up our example, the mages apprentice robe, as it is worn by human females. &lt;br /&gt;
&lt;br /&gt;
#Open up the Toolset and in the Resource Palette on the upper right click on &amp;quot;Items&amp;quot; (appears as a sword icon). Now comes guessing where this piece is to be found there. These Items are pretty well sorted though, it is to be found under _global / Clothing / Mage Robes / Unique. In the following list you see the ResourceName followed by ItemName &amp;quot;gen_im_cth_mag_app (Apprentice Robes)&amp;quot;. Any Item can be found in the &amp;quot;Item&amp;quot; Category.  Doubleclick that entry to look inside.&lt;br /&gt;
#In the listing of information that appears to the left of the item, note that the &amp;quot;Base Item Type&amp;quot; is &amp;quot;Clothing&amp;quot;, which is branching off into the Item Variation. The robe has a &amp;quot;Item Variation&amp;quot; called &amp;quot;Robe, Apprentice&amp;quot;. Variation in mind, onto the next step.&lt;br /&gt;
#Open up the &amp;quot;ItemVariations.xls&amp;quot; File located under &amp;quot;(dragon age install directory)/tools/Source/2da/rules&amp;quot;. It has many pages, locate page &amp;quot;clothing_variation&amp;quot; since we know our &amp;quot;Base Item Type&amp;quot; is of &amp;quot;Clothing&amp;quot;. In there, locate the Row called whatever Item Variation your Item had. &amp;quot;Robe, Apprentice&amp;quot; has Namestrings followed by &amp;quot;rob&amp;quot; &amp;quot;app&amp;quot; &amp;quot;a&amp;quot;.&lt;br /&gt;
#With these 3 Strings, and Dragon Age's [[Naming conventions|Naming Scheme]] you can find the [[MMH]] Main Modelfile.&lt;br /&gt;
#At the end of MMH file (extract, open and Expand All with the toolset), is the reference to the material object filename (page up two or three times from the end of the file).&lt;br /&gt;
#And inside the [[MAO]] File (open with Notepad) are the references to the texture filenames.&lt;br /&gt;
&lt;br /&gt;
Spend a little time browsing through these files, and the naming convention will become clear. The armor prefixes are a compound of a &amp;quot;race&amp;quot; letter -- h, d, e, q, k (for children) and p (for person, or humanoid) -- and a gender letter -- m, f or n. For instance, a Chest mesh (the actual model or msh file) is by necessity both race and usually gender specific, several mmh files will usually reference one msh and are prefixed similarly, while textures will map to any model with the correct UV map, so usually begin with &amp;quot;p&amp;quot; and may or may not be gender specific. Once you understand the prefixes, the textures can usually be located quickly in the relevant erf, with the part code (where applicable) coming next, followed by the item variation code, followed by the texture code.&lt;br /&gt;
&lt;br /&gt;
(There are some anomalies: for instance Ancient Elven Armor is listed in the toolset as Medium Armor E, but is in fact heavy armor so has an item variation code of &amp;quot;hvye&amp;quot; (it also has no tint map, being a one-off piece), but such cases are not too hard to track down once you understand the overall schema.)&lt;br /&gt;
&lt;br /&gt;
== Extracting the Texture from the Package ==&lt;br /&gt;
&lt;br /&gt;
Model textures are located in two &amp;quot;texturepack.erf&amp;quot; [[ERF]] packages, corresponding to high resolution and medium resolution textures. These packages can be found in the (dragon age install directory)\packages\core\textures\ folder. For example, the packages might be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\textures\high\texturepack.erf&lt;br /&gt;
C:\Program Files\Dragon Age\packages\core\textures\medium\texturepack.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drag and drop these ERF Files onto the Toolset to browse and extract their content. If you have the Name, finding the Files will be easy. The Files will be in both &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot; and the quality setting in the game will decide which to choose. To make it compatible enough, taking them all may be neccessary.&lt;br /&gt;
&lt;br /&gt;
Incidentally, high and medium texture versions are only required for certain model types. For example, heraldry and props only have one texture, and these can be found in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\data\textures.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prepare for extracting the textures, we must create a directory mimicking the structure of the Dragon Age packages folder. To do this, create a new folder named &amp;quot;textures&amp;quot; in a convenient location (for example, on your desktop). Inside this folder, create two new folders, named &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot;. The &amp;quot;high&amp;quot; folder will be where the high-resolution textures are extracted to, and the &amp;quot;medium&amp;quot; folder will be where the medium-resolution textures are extracted to.&lt;br /&gt;
&lt;br /&gt;
For this tutorial, we are interested in the mage's robes. To locate the textures of the mage's robes, scroll down to &amp;quot;pf_rob_appa_0d.dds&amp;quot; in one of the two texturepack ERFs. In each texturepack.erf, select all of the image files prefixed with &amp;quot;pf_rob_appa&amp;quot; (from &amp;quot;pf_rob_appa_0d.dds&amp;quot; to &amp;quot;pf_rob_appa_0tl3.dds&amp;quot;). For the high-resolution texturepack.erf, extract these images to the &amp;quot;textures\high\&amp;quot; folder just created. Extract the medium-resolution textures to the &amp;quot;textures\medium\&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
The Suffixes for Texturefiles are describing their Formats, which is described under [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
To extract one of the textures, right-click on it and select &amp;quot;Extract Resource.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Editing the Textures ==&lt;br /&gt;
&lt;br /&gt;
At this stage, if we wanted to edit the existing robe textures, we could do so by changing these files. See [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
Once this has been done for all of the robe textures (in both the &amp;quot;High&amp;quot; and &amp;quot;Medium&amp;quot; folders), we'll be ready to override the default textures in Dragon Age.&lt;br /&gt;
&lt;br /&gt;
== Overriding the Existing Textures ==&lt;br /&gt;
[[Image:Demo-retexture.jpg|thumb|The end result: reskinned default mage robes.]]&lt;br /&gt;
&lt;br /&gt;
Comment : this section doesn't agree with the guidance on [[Compatibility]]. Surely textures should be placed in the module's texture folder?  &lt;br /&gt;
&lt;br /&gt;
To override the existing textures, copy the &amp;quot;textures&amp;quot; folder containing the modified textures, and paste this folder into the Dragon Age override folder. The override folder is found in:&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
for Windows Vista and 7, and in a similar location on Windows XP.&lt;br /&gt;
&lt;br /&gt;
So, after pasting in the modified textures, the structure of the override folder should look like this:&lt;br /&gt;
&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
**textures&lt;br /&gt;
***high&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
***medium&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
&lt;br /&gt;
== Further Tutorials ==&lt;br /&gt;
&lt;br /&gt;
[[Tutorial: Creating recolors of existing items]] - A way to change the tint of the new texture&lt;br /&gt;
&lt;br /&gt;
== Related Links ==&lt;br /&gt;
&lt;br /&gt;
[[Texture Formats]] - Texture formats in detail.&lt;br /&gt;
&lt;br /&gt;
[[Art Resources]] - Broad topic of Art Resources, which textures are a part of.&lt;br /&gt;
&lt;br /&gt;
[[category:tutorials]]&lt;br /&gt;
[[Category:Textures]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15263</id>
		<title>Reskinning an item tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Reskinning_an_item_tutorial&amp;diff=15263"/>
				<updated>2010-12-22T10:44:45Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Locating the Model Textures the Hard Way */  removed wrong &amp;quot;hidden filename&amp;quot; stuff, replaced with simpler explanation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
This tutorial describes how to reskin, or change the default texture, of items that already exist in-game. As an example, the default textures of the human female mage's apprentice robes will be changed.&lt;br /&gt;
&lt;br /&gt;
Tools needed are the Dragon Age Toolset, and a grafic editing Applications capable of Opening, Editing and Saving DDS Texture Files.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The game utilizes Tints, which reuse the same Texture in colorized or tinted versions. Thus the texture in our example doesn't look quite as it does in game, and vice versa. If you edit the Texture, it won't look quite like that when put back into the game. The difference is merely color differences, so this process is limited. However, you can only change Tints, or both. See below for further tutorials.&lt;br /&gt;
&lt;br /&gt;
== Locating the Model Textures the Hard Way==&lt;br /&gt;
&lt;br /&gt;
At the beginning, you only know how the [[Model]] looks and what its called. A somewhat difficult task will be, finding out which files are tied to the model so that you can edit them. &lt;br /&gt;
&lt;br /&gt;
'''Note:''' You may want to read it once, to understand alternative ways.&lt;br /&gt;
&lt;br /&gt;
First and foremost, you are looking for DDS Files. How DDS Files are referenced by an Item you see in Game is a long list of database references.&lt;br /&gt;
&lt;br /&gt;
A quick rundown on references we need to be aware of&lt;br /&gt;
&lt;br /&gt;
#A DDS File is referenced by the Material Properties of a [[Model]]&lt;br /&gt;
#A [[Model]] is then referenced by the &amp;quot;ItemVariation&amp;quot; type of files. In our example, the sub &amp;quot;clothing_variation.gda&amp;quot;&lt;br /&gt;
#The different Clothing Variations are then referenced by the Item Type made via the Toolset&lt;br /&gt;
#The Item Type is lastly referenced by the Game, when choosing which gender and race this item is worn. And then displays the final version in your game.&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To track back to the DDS File, you need to run up this list in reverse. Starting up our example, the mages apprentice robe, as it is worn by human females. &lt;br /&gt;
&lt;br /&gt;
#Open up the Toolset and in the Resource Palette on the upper right click on &amp;quot;Items&amp;quot; (appears as a sword icon). Now comes guessing where this piece is to be found there. These Items are pretty well sorted though, it is to be found under _global / Clothing / Mage Robes / Unique. In the following list you see the ResourceName followed by ItemName &amp;quot;gen_im_cth_mag_app (Apprentice Robes)&amp;quot;. Any Item can be found in the &amp;quot;Item&amp;quot; Category.  Doubleclick that entry to look inside.&lt;br /&gt;
#In the listing of information that appears to the left of the item, note that the &amp;quot;Base Item Type&amp;quot; is &amp;quot;Clothing&amp;quot;, which is branching off into the Item Variation. The robe has a &amp;quot;Item Variation&amp;quot; called &amp;quot;Robe, Apprentice&amp;quot;. Variation in mind, onto the next step.&lt;br /&gt;
#Open up the &amp;quot;ItemVariations.xls&amp;quot; File located under &amp;quot;(dragon age install directory)/tools/Source/2da/rules&amp;quot;. It has many pages, locate page &amp;quot;clothing_variation&amp;quot; since we know our &amp;quot;Base Item Type&amp;quot; is of &amp;quot;Clothing&amp;quot;. In there, locate the Row called whatever Item Variation your Item had. &amp;quot;Robe, Apprentice&amp;quot; has Namestrings followed by &amp;quot;rob&amp;quot; &amp;quot;app&amp;quot; &amp;quot;a&amp;quot;.&lt;br /&gt;
#With these 3 Strings, and Dragon Age's [[Naming conventions|Naming Scheme]] you can find the [[MMH]] Main Modelfile.&lt;br /&gt;
#At the end of MMH file (extract, open and Expand All with the toolset), is the reference to the material object filename (page up two or three times from the end of the file).&lt;br /&gt;
#And inside the [[MAO]] File (open with Notepad) is the references to the Textures Filenames.&lt;br /&gt;
&lt;br /&gt;
Spend a little time browsing through these files, and the naming convention will become clear. The armor prefixes are a compound of a &amp;quot;race&amp;quot; letter -- h, d, e, q, k(for children) and p (for person, or humanoid) -- and a gender letter -- m, f or n. Chest models are by necessity both race and usually gender specific, while textures will map to any model with the correct UV map, so usually begin with &amp;quot;p&amp;quot; and may or may not be gender specific. Once you understand the prefixes, the textures can usually be located quickly, with the item variation code followed by the part code (where applicable) followed by the texture code.&lt;br /&gt;
&lt;br /&gt;
(There are some anomalies: for instance Ancient Elven Armor is listed in the toolset as Medium Armor E, but is in fact heavy armor so has an item variation code of &amp;quot;hvye&amp;quot; (it also has no tint map, being a one-off piece), but such cases are not too hard to track down once you understand the overall schema.)&lt;br /&gt;
&lt;br /&gt;
== Extracting the Texture from the Package ==&lt;br /&gt;
&lt;br /&gt;
Model textures are located in two &amp;quot;texturepack.erf&amp;quot; [[ERF]] packages, corresponding to high resolution and medium resolution textures. These packages can be found in the (dragon age install directory)\packages\core\textures\ folder. For example, the packages might be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\textures\high\texturepack.erf&lt;br /&gt;
C:\Program Files\Dragon Age\packages\core\textures\medium\texturepack.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Drag and drop these ERF Files onto the Toolset to browse and extract their content. If you have the Name, finding the Files will be easy. The Files will be in both &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot; and the quality setting in the game will decide which to choose. To make it compatible enough, taking them all may be neccessary.&lt;br /&gt;
&lt;br /&gt;
Incidentally, high and medium texture versions are only required for certain model types. For example, heraldry and props only have one texture, and these can be found in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;C:\Program Files\Dragon Age\packages\core\data\textures.erf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To prepare for extracting the textures, we must create a directory mimicking the structure of the Dragon Age packages folder. To do this, create a new folder named &amp;quot;textures&amp;quot; in a convenient location (for example, on your desktop). Inside this folder, create two new folders, named &amp;quot;high&amp;quot; and &amp;quot;medium&amp;quot;. The &amp;quot;high&amp;quot; folder will be where the high-resolution textures are extracted to, and the &amp;quot;medium&amp;quot; folder will be where the medium-resolution textures are extracted to.&lt;br /&gt;
&lt;br /&gt;
For this tutorial, we are interested in the mage's robes. To locate the textures of the mage's robes, scroll down to &amp;quot;pf_rob_appa_0d.dds&amp;quot; in one of the two texturepack ERFs. In each texturepack.erf, select all of the image files prefixed with &amp;quot;pf_rob_appa&amp;quot; (from &amp;quot;pf_rob_appa_0d.dds&amp;quot; to &amp;quot;pf_rob_appa_0tl3.dds&amp;quot;). For the high-resolution texturepack.erf, extract these images to the &amp;quot;textures\high\&amp;quot; folder just created. Extract the medium-resolution textures to the &amp;quot;textures\medium\&amp;quot; folder.&lt;br /&gt;
&lt;br /&gt;
The Suffixes for Texturefiles are describing their Formats, which is described under [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
To extract one of the textures, right-click on it and select &amp;quot;Extract Resource.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Editing the Textures ==&lt;br /&gt;
&lt;br /&gt;
At this stage, if we wanted to edit the existing robe textures, we could do so by changing these files. See [[Textureformats]].&lt;br /&gt;
&lt;br /&gt;
Once this has been done for all of the robe textures (in both the &amp;quot;High&amp;quot; and &amp;quot;Medium&amp;quot; folders), we'll be ready to override the default textures in Dragon Age.&lt;br /&gt;
&lt;br /&gt;
== Overriding the Existing Textures ==&lt;br /&gt;
[[Image:Demo-retexture.jpg|thumb|The end result: reskinned default mage robes.]]&lt;br /&gt;
&lt;br /&gt;
Comment : this section doesn't agree with the guidance on [[Compatibility]]. Surely textures should be placed in the module's texture folder?  &lt;br /&gt;
&lt;br /&gt;
To override the existing textures, copy the &amp;quot;textures&amp;quot; folder containing the modified textures, and paste this folder into the Dragon Age override folder. The override folder is found in:&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
for Windows Vista and 7, and in a similar location on Windows XP.&lt;br /&gt;
&lt;br /&gt;
So, after pasting in the modified textures, the structure of the override folder should look like this:&lt;br /&gt;
&lt;br /&gt;
*Documents\BioWare\Dragon Age\packages\core\override\&lt;br /&gt;
**textures&lt;br /&gt;
***high&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
***medium&lt;br /&gt;
****pf_rob_appa_0d.dds&lt;br /&gt;
****(...)&lt;br /&gt;
****pf_rob_appa_0tl3.dds&lt;br /&gt;
&lt;br /&gt;
== Further Tutorials ==&lt;br /&gt;
&lt;br /&gt;
[[Tutorial: Creating recolors of existing items]] - A way to change the tint of the new texture&lt;br /&gt;
&lt;br /&gt;
== Related Links ==&lt;br /&gt;
&lt;br /&gt;
[[Texture Formats]] - Texture formats in detail.&lt;br /&gt;
&lt;br /&gt;
[[Art Resources]] - Broad topic of Art Resources, which textures are a part of.&lt;br /&gt;
&lt;br /&gt;
[[category:tutorials]]&lt;br /&gt;
[[Category:Textures]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=High-Level_Character_Generation&amp;diff=15262</id>
		<title>High-Level Character Generation</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=High-Level_Character_Generation&amp;diff=15262"/>
				<updated>2010-12-22T09:44:09Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Editing the module_core */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This is a draft. Let me know on the BSN forum thread if these don't work or I'm unclear on what must be done.&lt;br /&gt;
&lt;br /&gt;
BSN thread: http://social.bioware.com/forum/1/topic/71/index/5020925&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
In the Awakening and post-Awakening DLC, anyone who created a new character may have noticed that the character generation screen didn't start at level 1. With this tutorial, custom modules made by players will be able to have similar funtionality.&lt;br /&gt;
&lt;br /&gt;
==Creating the scripts==&lt;br /&gt;
First, it is very important that you DUPLICATE the important core scripts. By creating your own scripts, you won't have to worry about screwing the official campaign or other modules.&lt;br /&gt;
&lt;br /&gt;
The scripts that must be duplicated for this tutorial:&lt;br /&gt;
- module_core&lt;br /&gt;
- sys_chargen_h&lt;br /&gt;
- sys_chargen&lt;br /&gt;
&lt;br /&gt;
If you already have duplicates of these for other systems/tutorials (such as the background tutorial), make your edits in those files.&lt;br /&gt;
&lt;br /&gt;
When you duplicate the files, make sure that the names are unique while still naming their purpose for easy editing. For example, you might add a module-specific prefix:&lt;br /&gt;
- scar_module_core&lt;br /&gt;
- scar_sys_chargen_h&lt;br /&gt;
- scar_sys_chargen&lt;br /&gt;
&lt;br /&gt;
==Editing the sys_chargen_h file==&lt;br /&gt;
The first thing you want to do is avoid duplicate functions, as this confuses the compiler. You won't need or want to edit every function, so at the top of the file place another include:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you can delete everything except the &amp;quot;Chargen_InitializeCharacter&amp;quot; function. (Leave any functions that you may have edited, but don't forget to integrate them when necessary.)&lt;br /&gt;
&lt;br /&gt;
Next you need to create a new name for this function. I suggest the prefix you used for the script files:&lt;br /&gt;
&lt;br /&gt;
scar_Chargen_InitializeCharacter&lt;br /&gt;
&lt;br /&gt;
Near the top of the function you should see a group of lines that look like this:&lt;br /&gt;
&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    // 2. Set Creature to Level and Experience 0&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_LEVEL,1.0f,PROPERTY_VALUE_BASE);&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_EXPERIENCE,0.0f,PROPERTY_VALUE_BASE);&lt;br /&gt;
&lt;br /&gt;
Set the level and XP to the appropriate values for your starting level. (You can give less XP, forcing a character to gain that extra XP before leveling. This does not affect companions.)&lt;br /&gt;
&lt;br /&gt;
You also need to find this group:&lt;br /&gt;
&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    // 6. Set up points available to distribute (skills only on humanoids)&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    if (IsHumanoid(oChar))&lt;br /&gt;
    {&lt;br /&gt;
        SetCreatureProperty(oChar,PROPERTY_SIMPLE_SKILL_POINTS,      1.0, PROPERTY_VALUE_BASE);&lt;br /&gt;
    }&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_ATTRIBUTE_POINTS,  5.0, PROPERTY_VALUE_BASE);&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_TALENT_POINTS,     2.0, PROPERTY_VALUE_BASE);&lt;br /&gt;
&lt;br /&gt;
And set the values to the appropriate level (or give more/less that usual for certain modules.)&lt;br /&gt;
&lt;br /&gt;
==Editing the sys_chargen file==&lt;br /&gt;
Now that the include file is created, open the sys_chargen file. Make sure that you have both chargen includes. For example:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;scar_sys_chargen_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This will keep normal functions from breaking.&lt;br /&gt;
&lt;br /&gt;
Find and replace all &amp;quot;Chargen_InitializeCharacter&amp;quot; functions with your custom function. This will start your character at the appropriate level.&lt;br /&gt;
&lt;br /&gt;
There is a bug that occurs during &amp;quot;Quick-Start&amp;quot; unless another step is taken. Find all instances of &amp;quot;AL_DoAutoLevelUp&amp;quot;. (There should be two in an unedited file.)&lt;br /&gt;
&lt;br /&gt;
The function that causes the problem looks like this:&lt;br /&gt;
&lt;br /&gt;
AL_DoAutoLevelUp(oChar, TRUE, TRUE);&lt;br /&gt;
&lt;br /&gt;
Either set both trues to falses or copy/paste the other function to this space.&lt;br /&gt;
&lt;br /&gt;
==Editing the module_core==&lt;br /&gt;
The home stretch. Now we have to associate the module chargen script with our custom script.&lt;br /&gt;
&lt;br /&gt;
Near the bottom of an unedited script, you should find:&lt;br /&gt;
&lt;br /&gt;
            // -----------------------------------------------------------------&lt;br /&gt;
            // Handle character generation events sent by the engine.&lt;br /&gt;
            // -----------------------------------------------------------------&lt;br /&gt;
            if ((nEvent &amp;gt;= EVENT_TYPE_CHARGEN_START &amp;amp;&amp;amp; nEvent &amp;lt;= EVENT_TYPE_CHARGEN_END) || nEvent == EVENT_TYPE_PLAYERLEVELUP )&lt;br /&gt;
            {&lt;br /&gt;
                HandleEvent(ev, R&amp;quot;sys_chargen.ncs&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
Switch the script handling the event to your custom script.&lt;br /&gt;
===An alternative view===&lt;br /&gt;
&lt;br /&gt;
Editing the module_core script is almost certainly a bad idea, and is probably not even what was intended. But to be crystal clear, this code should be placed in your own module script (see next section), with appropriate modification (depending on how you have defined your event variables in that script). For example, if your module script initialisations are:&lt;br /&gt;
    &amp;lt;dascript&amp;gt;event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    int bEventHandled = FALSE;&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then you will need:&lt;br /&gt;
&amp;lt;dascript&amp;gt;default:&lt;br /&gt;
   {&lt;br /&gt;
            if ((nEventType &amp;gt;= EVENT_TYPE_CHARGEN_START &amp;amp;&amp;amp; nEventType &amp;lt;= EVENT_TYPE_CHARGEN_END) || nEventType == EVENT_TYPE_PLAYERLEVELUP )&lt;br /&gt;
            {&lt;br /&gt;
                HandleEvent(ev, R&amp;quot;scar_sys_chargen.ncs&amp;quot;);&lt;br /&gt;
                bEventHandled = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
   }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Calling the custom module script==&lt;br /&gt;
For those who don't know, a module script now must be associated with the module itself. This is done through [File-&amp;gt;Manage Modules-&amp;gt;Poperties]. Make sure you have your module selected before you hit properties.&lt;br /&gt;
&lt;br /&gt;
Underneath the module name, there should be a parameter named &amp;quot;Script&amp;quot;. Enter the browser and select your custom module_core script. Once you're finished eidting the module, click OK.&lt;br /&gt;
&lt;br /&gt;
==Final steps==&lt;br /&gt;
Unless you already have the function in your module_core, you need to actually run character generation.&lt;br /&gt;
&lt;br /&gt;
Under &amp;quot;EVENT_TYPE_MODULE_START&amp;quot;, add these lines:&lt;br /&gt;
&lt;br /&gt;
            PreloadCharGen();&lt;br /&gt;
            StartCharGen(GetHero());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Export and Test==&lt;br /&gt;
Make sure you save each file along the way, and compile all scripts once finished. Export the scripts and play your module. You should begin character generation at the appropriate level.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=High-Level_Character_Generation&amp;diff=15261</id>
		<title>High-Level Character Generation</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=High-Level_Character_Generation&amp;diff=15261"/>
				<updated>2010-12-22T09:39:30Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Editing the module_core */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Note: This is a draft. Let me know on the BSN forum thread if these don't work or I'm unclear on what must be done.&lt;br /&gt;
&lt;br /&gt;
BSN thread: http://social.bioware.com/forum/1/topic/71/index/5020925&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
In the Awakening and post-Awakening DLC, anyone who created a new character may have noticed that the character generation screen didn't start at level 1. With this tutorial, custom modules made by players will be able to have similar funtionality.&lt;br /&gt;
&lt;br /&gt;
==Creating the scripts==&lt;br /&gt;
First, it is very important that you DUPLICATE the important core scripts. By creating your own scripts, you won't have to worry about screwing the official campaign or other modules.&lt;br /&gt;
&lt;br /&gt;
The scripts that must be duplicated for this tutorial:&lt;br /&gt;
- module_core&lt;br /&gt;
- sys_chargen_h&lt;br /&gt;
- sys_chargen&lt;br /&gt;
&lt;br /&gt;
If you already have duplicates of these for other systems/tutorials (such as the background tutorial), make your edits in those files.&lt;br /&gt;
&lt;br /&gt;
When you duplicate the files, make sure that the names are unique while still naming their purpose for easy editing. For example, you might add a module-specific prefix:&lt;br /&gt;
- scar_module_core&lt;br /&gt;
- scar_sys_chargen_h&lt;br /&gt;
- scar_sys_chargen&lt;br /&gt;
&lt;br /&gt;
==Editing the sys_chargen_h file==&lt;br /&gt;
The first thing you want to do is avoid duplicate functions, as this confuses the compiler. You won't need or want to edit every function, so at the top of the file place another include:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
For this tutorial, you can delete everything except the &amp;quot;Chargen_InitializeCharacter&amp;quot; function. (Leave any functions that you may have edited, but don't forget to integrate them when necessary.)&lt;br /&gt;
&lt;br /&gt;
Next you need to create a new name for this function. I suggest the prefix you used for the script files:&lt;br /&gt;
&lt;br /&gt;
scar_Chargen_InitializeCharacter&lt;br /&gt;
&lt;br /&gt;
Near the top of the function you should see a group of lines that look like this:&lt;br /&gt;
&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    // 2. Set Creature to Level and Experience 0&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_LEVEL,1.0f,PROPERTY_VALUE_BASE);&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_EXPERIENCE,0.0f,PROPERTY_VALUE_BASE);&lt;br /&gt;
&lt;br /&gt;
Set the level and XP to the appropriate values for your starting level. (You can give less XP, forcing a character to gain that extra XP before leveling. This does not affect companions.)&lt;br /&gt;
&lt;br /&gt;
You also need to find this group:&lt;br /&gt;
&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    // 6. Set up points available to distribute (skills only on humanoids)&lt;br /&gt;
    // -------------------------------------------------------------------------&lt;br /&gt;
    if (IsHumanoid(oChar))&lt;br /&gt;
    {&lt;br /&gt;
        SetCreatureProperty(oChar,PROPERTY_SIMPLE_SKILL_POINTS,      1.0, PROPERTY_VALUE_BASE);&lt;br /&gt;
    }&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_ATTRIBUTE_POINTS,  5.0, PROPERTY_VALUE_BASE);&lt;br /&gt;
    SetCreatureProperty(oChar,PROPERTY_SIMPLE_TALENT_POINTS,     2.0, PROPERTY_VALUE_BASE);&lt;br /&gt;
&lt;br /&gt;
And set the values to the appropriate level (or give more/less that usual for certain modules.)&lt;br /&gt;
&lt;br /&gt;
==Editing the sys_chargen file==&lt;br /&gt;
Now that the include file is created, open the sys_chargen file. Make sure that you have both chargen includes. For example:&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;scar_sys_chargen_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
This will keep normal functions from breaking.&lt;br /&gt;
&lt;br /&gt;
Find and replace all &amp;quot;Chargen_InitializeCharacter&amp;quot; functions with your custom function. This will start your character at the appropriate level.&lt;br /&gt;
&lt;br /&gt;
There is a bug that occurs during &amp;quot;Quick-Start&amp;quot; unless another step is taken. Find all instances of &amp;quot;AL_DoAutoLevelUp&amp;quot;. (There should be two in an unedited file.)&lt;br /&gt;
&lt;br /&gt;
The function that causes the problem looks like this:&lt;br /&gt;
&lt;br /&gt;
AL_DoAutoLevelUp(oChar, TRUE, TRUE);&lt;br /&gt;
&lt;br /&gt;
Either set both trues to falses or copy/paste the other function to this space.&lt;br /&gt;
&lt;br /&gt;
==Editing the module_core==&lt;br /&gt;
The home stretch. Now we have to associate the module chargen script with our custom script.&lt;br /&gt;
&lt;br /&gt;
Near the bottom of an unedited script, you should find:&lt;br /&gt;
&lt;br /&gt;
            // -----------------------------------------------------------------&lt;br /&gt;
            // Handle character generation events sent by the engine.&lt;br /&gt;
            // -----------------------------------------------------------------&lt;br /&gt;
            if ((nEvent &amp;gt;= EVENT_TYPE_CHARGEN_START &amp;amp;&amp;amp; nEvent &amp;lt;= EVENT_TYPE_CHARGEN_END) || nEvent == EVENT_TYPE_PLAYERLEVELUP )&lt;br /&gt;
            {&lt;br /&gt;
                HandleEvent(ev, R&amp;quot;sys_chargen.ncs&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
Switch the script handling the event to your custom script.&lt;br /&gt;
===An alternative view===&lt;br /&gt;
&lt;br /&gt;
Editing the module_core script is almost certainly a bad idea. This code should be placed in your own module script (see next section), with appropriate modification (depending on how you have defined your event variables in that script). For example, if your module script initialisations are:&lt;br /&gt;
    &amp;lt;dascript&amp;gt;event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    int bEventHandled = FALSE;&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then you will need:&lt;br /&gt;
&amp;lt;dascript&amp;gt;default:&lt;br /&gt;
   {&lt;br /&gt;
            if ((nEventType &amp;gt;= EVENT_TYPE_CHARGEN_START &amp;amp;&amp;amp; nEventType &amp;lt;= EVENT_TYPE_CHARGEN_END) || nEventType == EVENT_TYPE_PLAYERLEVELUP )&lt;br /&gt;
            {&lt;br /&gt;
                HandleEvent(ev, R&amp;quot;scar_sys_chargen.ncs&amp;quot;);&lt;br /&gt;
                bEventHandled = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
   }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Calling the custom module script==&lt;br /&gt;
For those who don't know, a module script now must be associated with the module itself. This is done through [File-&amp;gt;Manage Modules-&amp;gt;Poperties]. Make sure you have your module selected before you hit properties.&lt;br /&gt;
&lt;br /&gt;
Underneath the module name, there should be a parameter named &amp;quot;Script&amp;quot;. Enter the browser and select your custom module_core script. Once you're finished eidting the module, click OK.&lt;br /&gt;
&lt;br /&gt;
==Final steps==&lt;br /&gt;
Unless you already have the function in your module_core, you need to actually run character generation.&lt;br /&gt;
&lt;br /&gt;
Under &amp;quot;EVENT_TYPE_MODULE_START&amp;quot;, add these lines:&lt;br /&gt;
&lt;br /&gt;
            PreloadCharGen();&lt;br /&gt;
            StartCharGen(GetHero());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Export and Test==&lt;br /&gt;
Make sure you save each file along the way, and compile all scripts once finished. Export the scripts and play your module. You should begin character generation at the appropriate level.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Reskinning_an_item_tutorial&amp;diff=15222</id>
		<title>Talk:Reskinning an item tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Reskinning_an_item_tutorial&amp;diff=15222"/>
				<updated>2010-12-15T11:30:56Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Complete nonsense */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Thanks for the tutorial on reskinning an item!&lt;br /&gt;
&lt;br /&gt;
One question:  How do I ''recolor'' a texture?  The colors that the characters are wearing in-game seem to have nothing to do with the colors of the textures in the .dds files.&lt;br /&gt;
&lt;br /&gt;
The main mage robe texture file, pf_rob_appb_0dl2.dds, has very little color, and if I recolor it, as you'd expect, nothing happens.  And if I look at pf_rob_appb_0t.dds, it's intense shades of red, blue, and green, which seem designed to tell the game where to put various colors, rather than which colors those are.  So where do the specific colors come from?&lt;br /&gt;
&lt;br /&gt;
I've recolored a lot of files for ''The Witcher,'' so I know how to recolor a .dds file.  But in ''The Witcher,'' you get whatever color you've made the texture.  Where are the colors stored for ''Dragon Age''?&lt;br /&gt;
&lt;br /&gt;
My mage has an orange-and-green set of robes, and I'd like a different color scheme. &lt;br /&gt;
&lt;br /&gt;
Thanks!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Corylea&lt;br /&gt;
:You'll want to read up on the [[Material Tint System]] and check out [[Tutorial:_Creating_recolors_of_existing_items|this tutorial]] and [[Tutorial:_Understanding_Tints:_Overriding_Defaults_&amp;amp;_Creating_New_Ones|this tutorial]] on tinting. [[User:Nezroy|Nezroy]] 18:00, 26 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Where are the files for the Blood Dragon Armor called?&lt;br /&gt;
&lt;br /&gt;
What program do you use to open the ERFs?&lt;br /&gt;
---Skyintheeye&lt;br /&gt;
:The toolset can open ERFs. Just use the File-&amp;gt;Open command and locate the ERF to open. Then right-click on a file in the list and select &amp;quot;Extract Resource&amp;quot; (or alternatively you can use &amp;quot;Extract All Resources&amp;quot; to dump the contents of the entire ERF somewhere). [[User:Nezroy|Nezroy]] 18:01, 26 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Complete nonsense ==&lt;br /&gt;
&lt;br /&gt;
This &amp;quot;tutorial&amp;quot; states &amp;quot;In this File is a hidden reference to the MAO Material file.&amp;quot; referring to the MMH file. Rubbish. The material object filename is towards the end of the MMH. This, and what follows, is seriously misleading. Will fix when I get some time. --[[User:Gaxkang55|Gaxkang55]] 11:30, 15 December 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Creating_a_custom_placeable_from_a_model_tutorial&amp;diff=15206</id>
		<title>Talk:Creating a custom placeable from a model tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Creating_a_custom_placeable_from_a_model_tutorial&amp;diff=15206"/>
				<updated>2010-12-11T12:13:20Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: Created page with 'This was never going to work without changing the name the material object file in the MMH. Have now fixed. ~~~~'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This was never going to work without changing the name the material object file in the MMH. Have now fixed. [[User:Gaxkang55|Gaxkang55]] 12:13, 11 December 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Creating_a_custom_placeable_from_a_model_tutorial&amp;diff=15205</id>
		<title>Creating a custom placeable from a model tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Creating_a_custom_placeable_from_a_model_tutorial&amp;diff=15205"/>
				<updated>2010-12-11T12:09:14Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Edit your MMH and PHY files */ Added line on material object reference in the MMH.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This tutorial describes how to create a custom [[Placeable]] based on a [[Model]] that is already active in your toolset. This process should work with any model, whether custom or packaged with the game. It is assumed that the reader is familiar with the Toolset.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Set-up your [[2DA]] file==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [[Placeables.xls]] file contains the placeable_types xls sheet that you will need to edit. The [[2DA]] page describes the process of creating the 2da file that you will need.&lt;br /&gt;
&lt;br /&gt;
The columns you need to edit (or at least check) in the spreadsheet are ID, Label (something meaningful to you - does not have to be unique), ModelName (the name of your MMH file), OcclusionFactor (optional), StateController, and baseType (values are listed on the first tab in the excel file).&lt;br /&gt;
&lt;br /&gt;
Check the [[2DA ranges in use]] page to make sure you are not using row IDs in your 2da file that will conflict with the core game or other popular modules.&lt;br /&gt;
&lt;br /&gt;
The StateController field is very important because it determines the type of action that can be used with your placeable in game. For example, Informational objects can be examined, but cannot launch dialog. Puzzle items can launch a dialog. Think about what you want your placeable to do and choose the StateController to match it.&lt;br /&gt;
&lt;br /&gt;
Create your [[GDA]] file using Excel Processor and put it in Dragon Age/packages/core/override. See [[compiling 2DAs]] for details on how.&lt;br /&gt;
&lt;br /&gt;
Tip: Excel Processor will generate a GDA file for every tab (xls sheet) within the 2da/m2da. You do not need all of these. Only keep the one that you edited (in this case it would be placeable_types) and place that one in the override folder.&lt;br /&gt;
&lt;br /&gt;
==Extract model files==&lt;br /&gt;
&lt;br /&gt;
Use DATool by Adinos ([[http://social.bioware.com/project/41/]]) to extract the DDS, [[MAO]], PHY, [[MMH]], and [[MSH]] files for the model you want to make into a placeable. To do this with the DATool click File --&amp;gt; Save all. Put them some place easy to access so you can work on them.&lt;br /&gt;
&lt;br /&gt;
== Change the names of your MAO, MMH, and PHY files ==&lt;br /&gt;
&lt;br /&gt;
Change the names of your MAO, MMH, and PHY files so that they start with plc_ instead of prp_. The new name must have the same number of characters as the old name.&lt;br /&gt;
&lt;br /&gt;
== Edit your MAO file ==&lt;br /&gt;
&lt;br /&gt;
Open the MAO file using a text editor like Notepad.&lt;br /&gt;
&lt;br /&gt;
*In &amp;lt;MaterialObject Name=&amp;quot;filename&amp;quot;&amp;gt; change filename to the new name of the MAO file.&lt;br /&gt;
*In &amp;lt;Material Name=&amp;quot;static.mat&amp;quot;&amp;gt; replace static.mat with Prop.mat.&lt;br /&gt;
*Delete the line that starts with &amp;lt;Texture Name=&amp;quot;mml_tLightmap &lt;br /&gt;
*Delete the line that starts with &amp;lt;SoundType Name= &lt;br /&gt;
*Add a line that says &amp;lt;Texture Name=&amp;quot;mml_tTintMask&amp;quot; ResName=&amp;quot;Default_White.dds&amp;quot;&amp;gt;&amp;lt;/Texture&amp;gt;&lt;br /&gt;
*Save and close the MAO file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Edit your MMH and PHY files ==&lt;br /&gt;
&lt;br /&gt;
Launch the Toolset.&lt;br /&gt;
&lt;br /&gt;
Open the new MMH file. Change MMH_NAME to match your new MMH file name. Towards the end of the MMF is a field for material object, which needs to be changed to the name of your new MAO file. Save and close the MMH file.&lt;br /&gt;
&lt;br /&gt;
Open your new PHY file.&lt;br /&gt;
&lt;br /&gt;
*Change MMH_NAME to the name of your new MMH file.&lt;br /&gt;
*Change MMH_NODE_COLLISION_OBJ_TYPE from 2 to 1.&lt;br /&gt;
*Change MMH_SHAPE_COLLISION_MASK_PLACEABLES from 0 to 1. (This is the field that tells the toolset and the game to use your object as a placeable, making it clickable.)&lt;br /&gt;
*Change MMH_SHAPE_COLLISION_MASK_STATIC_GEOMETRY from 1 to 0. (This field tells the toolset and the game that your object is a prop and is not clickable.)&lt;br /&gt;
*Save and close the PHY file.&lt;br /&gt;
&lt;br /&gt;
Close your toolset.&lt;br /&gt;
&lt;br /&gt;
== Put files in override folder ==&lt;br /&gt;
&lt;br /&gt;
Put your new MAO, MMH, and PHY files in Dragon Age/Packages/Core/Override.&lt;br /&gt;
&lt;br /&gt;
== Create your custom placeable ==&lt;br /&gt;
&lt;br /&gt;
You can now create a new placeable in the toolset using your model. The process of creating a new placeable is described in the [[Placeable tutorial]] page.&lt;br /&gt;
[[Category:Tutorials]]&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15204</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15204"/>
				<updated>2010-12-11T11:59:17Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Step 3: Create package GDAs and reference them in you 2DA_base extension */  equipment mask line&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Simple Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
Follow these steps to create a follower that&lt;br /&gt;
&lt;br /&gt;
- Levels up with a default package&lt;br /&gt;
&lt;br /&gt;
- Can be chosen from the party picker&lt;br /&gt;
&lt;br /&gt;
- Can gain XP&lt;br /&gt;
&lt;br /&gt;
This guide assumes you know how to create a creature and are comfortable with basic scripting.&lt;br /&gt;
&lt;br /&gt;
You should only use this simple method if you are sure there will be empty space in the active party when your follower is recruited.&lt;br /&gt;
&lt;br /&gt;
A more comprehensive approach when there are more than three potential party members is discussed in the FAQ below. It's worth taking the time to understand the basics first, though. &lt;br /&gt;
&lt;br /&gt;
=== Create the creature ===&lt;br /&gt;
&lt;br /&gt;
Create a creature to act as your follower.  Set its name, appearance, gender, head morph, conversation, inventory etc as you want them to behave in-game.&lt;br /&gt;
&lt;br /&gt;
Set an appropriate '''Tag''' (you'll be using it a lot).  I suggest &amp;quot;party_charname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Make sure you choose a '''Class'''.  For most followers this should be Rogue, Warrior or Wizard.&lt;br /&gt;
&lt;br /&gt;
[[File:class.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under Package/Scaling set:&lt;br /&gt;
&lt;br /&gt;
'''General Package Type''' to be '''Party Members'''&lt;br /&gt;
&lt;br /&gt;
'''Package''' to be an appropriate value (probably &amp;quot;Generic - Wizard&amp;quot; or similar)&lt;br /&gt;
&lt;br /&gt;
'''Package AI''' (there should only be one choice)&lt;br /&gt;
&lt;br /&gt;
'''Rank''' to be '''Player'''&lt;br /&gt;
&lt;br /&gt;
[[File:package.jpg]]&lt;br /&gt;
&lt;br /&gt;
Save and export your character as normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overlay char_stage ===&lt;br /&gt;
&lt;br /&gt;
In the official campaign, the party picker uses a special area called char_stage. Whether you're extending the official campaign or making a standalone campaign, there is a function that allows you to overlap the offical stage with your own, so that both stages are active simultaneously in game.&lt;br /&gt;
&lt;br /&gt;
In your resource palette, right-click char_stage under the Global folder and select Duplicate to make a copy of the stage with a new resource name, e.g. my_char_stage. In the resource properties, ensure that both Module and Owner Module are set to your module, and the folder of your choice.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:area_palette.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a new waypoint for your follower to appear on the party picker.  This waypoint '''must''' have a tag in the form of &amp;quot;char_&amp;quot; followed by the exact tag of your follower.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:char_stage.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example the tag of my follower is '''bc_party_miera''' so her waypoint tag must be '''char_bc_party_miera'''&lt;br /&gt;
&lt;br /&gt;
For a standalone module (such as in this example), put your waypoint wherever you please.  The illustrated one is directly on top of Morrigan's.  For an add-in to the main campaign, you should position your wp appropriately relative to the core party members.&lt;br /&gt;
&lt;br /&gt;
Save and export the area.&lt;br /&gt;
&lt;br /&gt;
Add the following to your module event script:&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
case EVENT_TYPE_MODULE_GETCHARSTAGE:&lt;br /&gt;
{&lt;br /&gt;
   // Overlay the existing stage with my stage&lt;br /&gt;
   // &amp;quot;my_char_stage&amp;quot; is the resource name of the overlay area&lt;br /&gt;
   // &amp;quot;partypicker&amp;quot; is the name of the default GDA&lt;br /&gt;
   SetPartyPickerStage(&amp;quot;my_char_stage&amp;quot;, &amp;quot;partypicker&amp;quot;);&lt;br /&gt;
   break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create m2DAs for the Party Picker ===&lt;br /&gt;
&lt;br /&gt;
You will need to create two Excel spreadsheets.&lt;br /&gt;
&lt;br /&gt;
The first should be named (both worksheet and file) '''partypicker_''' with a unique suffix.  In this example, my first spreadsheet is named partypicker_fofbc.xls with a worksheet name of partypicker_fofbc - the suffix being the acronym of my module.&lt;br /&gt;
&lt;br /&gt;
Set up your columns as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:partypickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' for your follower must be '''12 or higher'''.  11 is the highest value used in the base 2DA.  12 is fine for standalone modules, add-ins will probably want to use an arbitrarily high number to avoid potential conflicts.&lt;br /&gt;
&lt;br /&gt;
The '''Label''' should be the follower's name as you wish it to appear on the party picker.&lt;br /&gt;
&lt;br /&gt;
The '''Tag''' must be your follower's tag.&lt;br /&gt;
&lt;br /&gt;
All other values are non-functioning defaults and should be specified as in the image above unless you know explicitly what you're doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION ANIMATIONS'''&lt;br /&gt;
 &lt;br /&gt;
Add Animation and Remove Animation are actually Id numbers of different animations, taken from anim_base.gda&lt;br /&gt;
&lt;br /&gt;
Enter and Exit version of animations are generally the best ones to use, altough one can try others. NOT ALL ANIMATIONS WILL WORK, since some require special conditions.&lt;br /&gt;
Here are some examples you can use:&lt;br /&gt;
&lt;br /&gt;
819 - talk cursing&lt;br /&gt;
&lt;br /&gt;
629 - reading a book (doesn't work, since it probably requires a book object)&lt;br /&gt;
&lt;br /&gt;
844 - hands behind back (848 and 849 are Enter and Exit versions respectfully)&lt;br /&gt;
&lt;br /&gt;
850 - chest pounding salute&lt;br /&gt;
&lt;br /&gt;
811 - fist pounding&lt;br /&gt;
&lt;br /&gt;
277 - dance&lt;br /&gt;
&lt;br /&gt;
247 - cast area spell&lt;br /&gt;
&lt;br /&gt;
500 - vfx cast&lt;br /&gt;
&lt;br /&gt;
600 - surprised&lt;br /&gt;
&lt;br /&gt;
603 - praying&lt;br /&gt;
&lt;br /&gt;
607 - head bow&lt;br /&gt;
&lt;br /&gt;
609 - standing at attention&lt;br /&gt;
&lt;br /&gt;
651,652 - crouch pray (Enter and exit)&lt;br /&gt;
&lt;br /&gt;
808 - point forward&lt;br /&gt;
&lt;br /&gt;
825 - nodding&lt;br /&gt;
&lt;br /&gt;
840 - hand chop or frustration&lt;br /&gt;
&lt;br /&gt;
905,906 - crouch (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
919,920 - sit on ground (enter, exit)&lt;br /&gt;
&lt;br /&gt;
965 - kneel down loop&lt;br /&gt;
&lt;br /&gt;
972 - wipe nose&lt;br /&gt;
&lt;br /&gt;
976,977 - squat (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
986 - wipe eyes&lt;br /&gt;
&lt;br /&gt;
998,999 - hands clasped (Enter, exit)&lt;br /&gt;
&lt;br /&gt;
3029 - inspect nails&lt;br /&gt;
&lt;br /&gt;
3031,3032 - playful (enter, exit)&lt;br /&gt;
&lt;br /&gt;
3054,3056 - slouch (enter, exit)&lt;br /&gt;
255 - in-place fly&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION VFX''' &lt;br /&gt;
&lt;br /&gt;
The VFX column is the ID of the vFX effect taken from vFx_base.gda. This one is a bit more tricky, since it also references the BlendTree value from the same file.&lt;br /&gt;
Find the ID of the spell effect and look for the BlendTreeName column (should the the 12th columun) and enter BOTH into the respective columns for your character in the partypicker file.&lt;br /&gt;
&lt;br /&gt;
Some examples:&lt;br /&gt;
&lt;br /&gt;
ID      ---      BLENDTREENAME      ---   EFFECT&lt;br /&gt;
&lt;br /&gt;
6039    ---     fxm_energy_up_p    ---    Lady of the Forest pillar of light&lt;br /&gt;
&lt;br /&gt;
6040    ---     fxm_power_in_p      ---   Branka - power in&lt;br /&gt;
&lt;br /&gt;
3054    ---     fxc_lotf_c          ---   Lady of the Forest - swirling leaves&lt;br /&gt;
&lt;br /&gt;
3009    ---     fxc_succubus_c     ---    Succubus crust&lt;br /&gt;
&lt;br /&gt;
1549    ---     fxa_hly_imp_c       ---   Holy Impact crust&lt;br /&gt;
&lt;br /&gt;
1076    ---     fxa_spi_aur_mht_c   ---   Spirit - Aura Might crust&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second spreadsheet should be named '''party_picker_''' (note middle underscore).  Once again append your unique suffix (in this example party_picker_fofbc.xls with party_picker_fofbc as its worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up your columns and data like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:party_pickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''ID''' and '''Tag''' should match what you did in the first spreadsheet.  Specify INVALID COLUMN for the third column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're familiar with m2DAs, generate them from these files, copy them to your module's override directory, and skip to the next step.  Otherwise, read on:&lt;br /&gt;
&lt;br /&gt;
- Go to '''\Program Files\Dragon Age\tools\ResourceBuild\Processors''' (or wherever you installed Dragon Age)&lt;br /&gt;
&lt;br /&gt;
- Copy '''ExcelProcessor.exe''' from that folder to whichever folder has the excel sheets you just created.&lt;br /&gt;
&lt;br /&gt;
- Drag and drop your xls files onto ExcelProcessor.  This will create .gda files.&lt;br /&gt;
&lt;br /&gt;
- Copy these .gda files to your module's export directory (probably \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetexport).  Make sure they are included in your .dazip when the time comes to build your module.&lt;br /&gt;
&lt;br /&gt;
If you are an OpenOffice user and have trouble with ExcelProcessor, you can use [http://social.bioware.com/project/755/ GDApp] to directly create the 2DAs.  It rocks!&lt;br /&gt;
&lt;br /&gt;
=== Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event ===&lt;br /&gt;
&lt;br /&gt;
Amusingly enough, the Party Picker does not actually add followers to the party.  However it raises an event that allows you to do so.  Your module script needs to capture this event and execute some code.&lt;br /&gt;
&lt;br /&gt;
The following example shows what to do with the event.  The full script would work as a module script for an add-in (assuming it didn't need to do anything else), but otherwise you'll have to incorporate the event into your own module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);  //Allows the follower to gain XP&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);  //Adds follower to the active party&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE)''' is the key statement to add the follower to the active party.  You must have this.&lt;br /&gt;
&lt;br /&gt;
'''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0)''' is a bug-fix, as followers hired with UT_HireFollower() do not receive XP by default.  This statement fixes that, and I consider it best practice to keep it in this event to ensure it is always set.  You will not wish to do this if you want a follower that should not gain XP to be on the party picker.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you do not need to intercept the corresponding event for a party member being removed - the party picker handles spawning/despawning, and thus will successfully remove members.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&lt;br /&gt;
&lt;br /&gt;
=== Create Your Hiring Script ===&lt;br /&gt;
&lt;br /&gt;
Now all that remains is to actually hire the follower :)&lt;br /&gt;
&lt;br /&gt;
Create a script to handle the hiring (which will most likely be fired from a conversation).  The script is quite simple:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
        object oFollower = GetObjectByTag(&amp;quot;bc_party_miera&amp;quot;); //Use CreateObject() if the creature isn't present in the module yet&lt;br /&gt;
&lt;br /&gt;
        UT_HireFollower(oFollower);   //Hires the follower&lt;br /&gt;
&lt;br /&gt;
        SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
        ShowPartyPickerGUI();  //Shows the Party Picker; necessary for the follower to gain XP&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use your own follower's tag and not the example one :)&lt;br /&gt;
&lt;br /&gt;
This script fires the party picker after hiring the follower.  That is absolutely necessary via this method, as we have put the XP fix onto an event fired by the party picker.  You cannot put the XP fix into this script, it must be called from a later one (the bug is caused by an errant call to an event in player_core, which will be executed AFTER this script).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If everything worked, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_success.jpg|thumb|200px|center]]&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow these steps to have full control over the creation of your follower, with options such as:&lt;br /&gt;
&lt;br /&gt;
- Unique level-up template&lt;br /&gt;
&lt;br /&gt;
- Class and specialisation chosen via script&lt;br /&gt;
&lt;br /&gt;
- Any starting state&lt;br /&gt;
&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&lt;br /&gt;
&lt;br /&gt;
- Set plot flags in the call to the hire script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prepare Creature, char_stage and Party Picker m2DAs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the same steps to create your follower creature, char_stage and Party Picker m2DAs as above.&lt;br /&gt;
&lt;br /&gt;
=== Create Party Plot ===&lt;br /&gt;
&lt;br /&gt;
While not necessary, it's very helpful to have plot flags set when a follower is hired or joins/leaves the active party.  This makes conversation interjections and the like very easy.&lt;br /&gt;
&lt;br /&gt;
Create a plot with appropriate flags.  There's no real need to associate journal text with them:&lt;br /&gt;
&lt;br /&gt;
[[File:follower_plot.jpg]]&lt;br /&gt;
&lt;br /&gt;
See FAQ for an alternative approach to plots when there are more than three potential party members.&lt;br /&gt;
&lt;br /&gt;
=== Add Plot Flags to Party Picker Event Intercept ===&lt;br /&gt;
&lt;br /&gt;
We then update our module script to make use of that plot, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //make sure you include your own plot, not mine&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            &lt;br /&gt;
            if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               //You must explicitly test for your follower's tag.&lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, TRUE);     //Make sure you use your own flags!&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            break;&lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_DROPPED:                    &lt;br /&gt;
        {&lt;br /&gt;
              object oFollower = GetEventObject(ev, 0); &lt;br /&gt;
              &lt;br /&gt;
              if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) { &lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, FALSE);     //As above, but set false.&lt;br /&gt;
              }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create a Level Up Template ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can skip this step if you're content to use one of the generic Rogue, Wizard or Warrior templates, but I don't recommend it.  Making a template that suits your character is easy and will almost always be better for the player than a generic one that spends points poorly.&lt;br /&gt;
&lt;br /&gt;
Go to \Program Files\Dragon Age\tools\Source\2DA (or wherever you installed Dragon Age).&lt;br /&gt;
&lt;br /&gt;
You should see a number of excel sheets of the form '''ALCharacter.xls''' (such as ALAlistair.xls, ALLeliana.xls, ALRogue_Default.xls etc).  Open the one closest to your character (ie Morrigan or Wynne for a wizard, Leliana or Zevran for a rogue).  Save a copy as '''ALYourcharacter.xls''' in whatever directory you're using to create your 2DAs, remembering to rename the worksheet '''ALYourcharacter''' (in this example, ALMiera.xls with ALMiera as its worksheet).&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:ALtable.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns B''' and '''C''' are the talents/spells available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
'''Columns F''' and '''G''' are the skills available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
We will edit the remaining columns like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Stat Weights ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The stat weights in '''column J''' determine how the follower will spend their attribute points, in a rough ratio.  So if Dexterity is set to 1.5 and Intelligence to 1, you should expect to see 3 points of Dex for every 2 points of Cunning in-game (note Intelligence is the label used in the toolset for Cunning).&lt;br /&gt;
&lt;br /&gt;
Simply change the values in J to reflect how you'd like the character to spend their points.  In this example we're creating a wizard, so we're not going to mess around:&lt;br /&gt;
&lt;br /&gt;
[[File:miera_stat_weights.jpg]]&lt;br /&gt;
&lt;br /&gt;
This character will only raise magic.  I set the value to 5 rather than something like 1 to provide room underneath for the other stats while still overwhelmingly favouring magic, but in practice I only really ever want that one stat. &lt;br /&gt;
&lt;br /&gt;
In a note left on this column in the existing templates, Bioware's Georg Zoeller writes, &amp;quot;This is the weight of each attribute (row id links into properties.xls.id). 1.0 means 'try to keep this attribute level' (spend 1 point per level). 0.5 means 'try to spend 1 point every two levels' and so on.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The default Mage, Rogue and Warrior templates include '''column L''' labeled &amp;quot;AttInit.&amp;quot; Editing these values seems to have no effect on followers set to use these templates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Talent and Skill Priorities ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns D''' and '''E''' are the talents/spells that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
'''Columns H''' and '''I''' are the skills that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change these, just copy the appropriate two cells from columns B&amp;amp;C or F&amp;amp;G over the ones you want to replace.&lt;br /&gt;
&lt;br /&gt;
For example, here we're copying Morrigan's template.  Morrigan has Spider Shape high in her preferences, which we do not want.&lt;br /&gt;
&lt;br /&gt;
[[File:AlMori_talent_pref.jpg]]&lt;br /&gt;
&lt;br /&gt;
We decide we'd prefer Flame Blast, so we find it in columns B&amp;amp;C and copy both cells:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_copy.jpg]]&lt;br /&gt;
&lt;br /&gt;
Then we select the cells we want to replace in columns D&amp;amp;E and paste over them:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_paste.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue this process until your priorities list for both skills and talents/spells is exactly as you want it.  Make sure you have at least as many priorities as the core follower you're copying - points that cannot be spent according to these priorities have a habit of vanishing.&lt;br /&gt;
&lt;br /&gt;
If you used any abilities from a specialisation, make sure you remember to set that specialisation with the function we'll introduce later.  The autolevel scripts will add specialisation abilities to a character regardless of whether they have that spec or not.&lt;br /&gt;
&lt;br /&gt;
==== Create a M2DA_base_ m2DA ====&lt;br /&gt;
&lt;br /&gt;
Dragon Age will need to know where to find your autolevel template.  We tell it by extending M2DA_base.gda&lt;br /&gt;
&lt;br /&gt;
Create a spreadsheet with the name and worksheet name in the form '''M2DA_base_''' with your unique suffix (in this example, M2DA_base_fofbc.xls with M2DA_base_fofbc as a worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up its columns and data like so (note I used GDApp because Open Office wasn't cooperating for this one!):&lt;br /&gt;
&lt;br /&gt;
[[File:m2da_base_fofbc.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' should be very high to avoid conflicts.  I've arbitrarily chosen 50,000+ here.  Carefully note the ID you've chosen for your character, you will need it later.&lt;br /&gt;
&lt;br /&gt;
Set the '''Label''' and '''Worksheet''' to be the name of your autolevel template worksheet (ALCharactername if you've been following this).&lt;br /&gt;
&lt;br /&gt;
Set the '''PackageIDForAI''' to be 0, it shouldn't be needed for followers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you're done, use ExcelProcessor to make GDAs of both spreadsheets and copy them to your module's export folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FOR AUTOLEVEL TO WORK AFTER RECRUITING:&lt;br /&gt;
&lt;br /&gt;
Look in packages.xls. &lt;br /&gt;
There is a column called LevelupTable. That links to a corresponding AL* table. For instance,  row 81 is for Leliana. Her LevelupTable value is 258. If you look that up in 2DA_base, you'll see it links to ALLeliana.&lt;br /&gt;
(alternatively, you could try packages_base.gda)&lt;br /&gt;
&lt;br /&gt;
=== Create a New Hire Function Include ===&lt;br /&gt;
&lt;br /&gt;
Many vital steps of follower addition happen inside an event in player_core.  Followers tend to be extremely buggy (no skill tree, for example) if this event does not fire.&lt;br /&gt;
&lt;br /&gt;
However, that event is not very flexible.  In order to control it to our requirements, we need to replicate its functionality inside our own script.  This is probably much safer than messing with player_core directly!&lt;br /&gt;
&lt;br /&gt;
Create a new script file, naming it something like '''hireCustomFollower_h'''.  We will be including this wherever we want to hire a follower.&lt;br /&gt;
&lt;br /&gt;
Paste in the following script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;approval_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_autolevelup_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*  Jye Nicolson 5-Jan-2010&lt;br /&gt;
This function set duplicates the full functionality chain of UT_HireFollower, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
-  Followers can gain XP&lt;br /&gt;
-  Autolevel status can be set (default off)&lt;br /&gt;
-  Followers can be set to any starting state (default Available) and will still be properly initalised and added to the party pool&lt;br /&gt;
-  Autolevel tables for non-core followers can be explicitly set.&lt;br /&gt;
-  Class and Specialisation can be chosen via script&lt;br /&gt;
-  Followers without specialisations are granted a spec point by default.&lt;br /&gt;
&lt;br /&gt;
It should only ever be called once each for characters you intend to be full followers.&lt;br /&gt;
Much of the protective code handling summoned creatures etc. in player_core is not present here.&lt;br /&gt;
&lt;br /&gt;
Calling the function:&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR);&lt;br /&gt;
&lt;br /&gt;
Change the class to CLASS_WIZARD or CLASS_ROGUE as appropriate.  &lt;br /&gt;
This will hire your follower and make them available.  &lt;br /&gt;
They will auto level up with a default package, and receive a free spec point.&lt;br /&gt;
&lt;br /&gt;
Best Practice:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR, PLT_YOUR_PARTY_PLOT, YOUR_FOLLOWER_JOINED_FLAG, ABILITY_TALENT_HIDDEN_CHAMPION);&lt;br /&gt;
&lt;br /&gt;
Where the plot and flag are those for your module (remember to create the plot and include it on the calling script), and ABILITY_TALENT_HIDDEN etc is the desired spec.&lt;br /&gt;
&lt;br /&gt;
You should also have a custom ALTable set up.  &lt;br /&gt;
See wiki for details, and remember to edit it in to GetCustomFollowerALTable below or pass it directly as an argument to hireCustomFollower.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Full argument list:&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower (&lt;br /&gt;
        object oFollower,   //Pass your follower object, mandatory&lt;br /&gt;
        &lt;br /&gt;
        int nForceClass,    //Pass a Class constant here, usually CLASS_ROGUE, CLASS_WARRIOR, CLASS_WIZARD.  Mandatory due to a bug.&lt;br /&gt;
        &lt;br /&gt;
        string sPlot = &amp;quot;&amp;quot;,   //It's recommended you have a plot flag to be set when the follower joins.  Pass the plot constant here.  Remember to #include in calling script&lt;br /&gt;
        &lt;br /&gt;
        int nPlotFlag = &amp;quot;&amp;quot;,  //And then pass the flag constant.  Will be set to TRUE if available.&lt;br /&gt;
        &lt;br /&gt;
        int nForceSpec = 0,  //This is the ID of the Specialisation you want.  Note they are NOT classes, but abilities.  The full list is:&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_ARCANE_WARRIOR, ABILITY_SPELL_HIDDEN_BLOODMAGE, ABILITY_SPELL_HIDDEN_SHAPESHIFTER, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_BARD, ABILITY_TALENT_HIDDEN_ASSASSIN, ABILITY_TALENT_HIDDEN_DUELIST, ABILITY_TALENT_HIDDEN_RANGER&lt;br /&gt;
                             //ABILITY_TALENT_HIDDEN_BERSERKER, ABILITY_TALENT_HIDDEN_CHAMPION, ABILITY_TALENT_HIDDEN_REAVER, ABILITY_TALENT_HIDDEN_TEMPLAR&lt;br /&gt;
                             //I recommended forcing a spec, particularly if your ALTable includes abilities from one.&lt;br /&gt;
        &lt;br /&gt;
        int nALTable = 0,    //This is the ID of an ALTable from 2DA_base.GDA or your module's m2DA_base_*.GDA  I recommended the latter, but you can edit that into GetCustomFollowerALTable below rather than passing it.&lt;br /&gt;
        &lt;br /&gt;
        int bInvokePicker = FALSE,  //Sets whether the party picker should be opened on hiring.  I think it's cleaner to call the picker outside this script, particularly if you have multiple hires at once.&lt;br /&gt;
        &lt;br /&gt;
        int nInitialState = FOLLOWER_STATE_AVAILABLE,  //This sets whether the follower joins the active party or not.  Options are:&lt;br /&gt;
                                                       //FOLLOWER_STATE_ACTIVE (put them in the active party)&lt;br /&gt;
                                                       //FOLLOWER_STATE_LOCKEDACTIVE (force them into the active party and keep them there, remember to change this later.&lt;br /&gt;
                                                       //FOLLOWER_STATE_AVAILABLE (make them available on the party picker (if you've set it up for them), but not in the active party)&lt;br /&gt;
                                                       //Plus some others you're unlikely to need at this time.  Defaults to AVAILABLE because having 4+ active followers is screwy.&lt;br /&gt;
                                                       &lt;br /&gt;
        string sCurrPlot = &amp;quot;&amp;quot;,  //If you set FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE, the script will check to see if you passed this.&lt;br /&gt;
                                //It is recommended that you have a plot flag set for a given follower being in the active party, this makes conversation interjection etc. much easier.&lt;br /&gt;
&lt;br /&gt;
        int nCurrPlotFlag = 0,  //This flag will be set if FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE are true&lt;br /&gt;
                                //AND sCurrPlot has a value AND nCurrPlotFlag is &amp;gt; 0.  &lt;br /&gt;
                                //ie if you added someone to the active party and have a plot flag to cope with it.&lt;br /&gt;
&lt;br /&gt;
        int nAutolevel = 0,     //Sets the Autolevel flag on the character sheet.  0 is off, 1 is on, 2 forces it on and removes it so the player can't turn it off.&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        bFreeSpecPoint = TRUE,  //This grants a specialisation point to the follower if they do not have a specialisation.  &lt;br /&gt;
                                //It's important to set this false for classes that do not have specs, such as CLASS_DOG.&lt;br /&gt;
                                &lt;br /&gt;
        int nTargetLevel = 0,   //If you want a specific level, set this.  Generally not worthwhile unless you set it higher than the player, since they'll just get XP from the party picker anyway.&lt;br /&gt;
        &lt;br /&gt;
        int nMinLevel = 0       //Set this if there's a specific level you don't want the follower to go below.  Probably only useful if the PC might be very low level but not necessarily so. &lt;br /&gt;
        &lt;br /&gt;
        )&lt;br /&gt;
*/       &lt;br /&gt;
/* GetCustomFollowerALTable()  &lt;br /&gt;
This function is where you put your custom table assignments.&lt;br /&gt;
&lt;br /&gt;
You should explicitly test for the tag of your follower (not mine!) and assign a value to nTable from your m2DA extension to M2DA_base &lt;br /&gt;
&lt;br /&gt;
See wiki for details on how to do this, or ignore it to get the default Warrior/Rogue/Wizard AL tables.&lt;br /&gt;
&lt;br /&gt;
NOTE: you MUST explicitly set a table for non-Warrior/Rogue/Wizards, eg dogs.  Use TABLE_AL_DOG for a default Mabari.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// This just cleans up the main function a little&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerTargetLevel(object oFollower, object oHero, int nPackage, int nMinLevel = 0) {&lt;br /&gt;
            int nPlayerLevel = GetLevel(oHero);&lt;br /&gt;
            int nTargetLevel = 0;&lt;br /&gt;
&lt;br /&gt;
            if((nPlayerLevel &amp;gt;= 13) || (nPlayerLevel == 1) || (!_UT_GetIsPlotFollower(oFollower))) {&lt;br /&gt;
               nTargetLevel = nPlayerLevel;&lt;br /&gt;
            } else {&lt;br /&gt;
               nTargetLevel = nPlayerLevel + 1;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (nMinLevel == 0) {  //If nMinLevel is not specified, checks package 2DA for a value&lt;br /&gt;
              nMinLevel = GetM2DAInt(TABLE_PACKAGES, &amp;quot;MinLevel&amp;quot;, nPackage);&lt;br /&gt;
             }&lt;br /&gt;
            if(nMinLevel &amp;gt; 0 &amp;amp;&amp;amp; nMinLevel &amp;gt; nTargetLevel) {&lt;br /&gt;
               nTargetLevel = nMinLevel;&lt;br /&gt;
            }          &lt;br /&gt;
            &lt;br /&gt;
            return nTargetLevel;&lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// Moving this black box out :)  I don't really understand it, but it should function if you have tactics set up in a package.&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerTactics(object oFollower, int nPackage) {&lt;br /&gt;
         int nTableID = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerTacticsTable&amp;quot;, nPackage);&lt;br /&gt;
         if (nTableID != -1)&lt;br /&gt;
            {&lt;br /&gt;
             int nRows = GetM2DARows(nTableID);&lt;br /&gt;
             int nMaxTactics = GetNumTactics(oFollower);&lt;br /&gt;
&lt;br /&gt;
             int nTacticsEntry = 1;&lt;br /&gt;
             int i;&lt;br /&gt;
             for (i = 1; i &amp;lt;= nRows &amp;amp;&amp;amp; nTacticsEntry &amp;lt;= nMaxTactics; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                        int bAddEntry = FALSE;&lt;br /&gt;
                        int nTargetType = GetM2DAInt(nTableID, &amp;quot;TargetType&amp;quot;, i);&lt;br /&gt;
                        int nCondition = GetM2DAInt(nTableID, &amp;quot;Condition&amp;quot;, i);&lt;br /&gt;
                        int nCommandType = GetM2DAInt(nTableID, &amp;quot;Command&amp;quot;, i);&lt;br /&gt;
                        int nCommandParam = GetM2DAInt(nTableID, &amp;quot;SubCommand&amp;quot;, i);&lt;br /&gt;
&lt;br /&gt;
                        int nUseType = GetM2DAInt(TABLE_COMMAND_TYPES, &amp;quot;UseType&amp;quot;, nCommandType);&lt;br /&gt;
                        if (nUseType == 0)&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = TRUE;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = HasAbility(oFollower, nCommandParam);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (bAddEntry)&lt;br /&gt;
                        {&lt;br /&gt;
                            SetTacticEntry(oFollower, nTacticsEntry, TRUE, nTargetType, nCondition, nCommandType, nCommandParam);&lt;br /&gt;
                            ++nTacticsEntry;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
/* InitCustomFollowerSpec:&lt;br /&gt;
&lt;br /&gt;
This function tries to set the forced Specialisation.  If there is none, it checks the package for one.  &lt;br /&gt;
&lt;br /&gt;
If there isn't either of those, it grants a free spec point if bFreeSpecPoint is true.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerSpec(object oFollower, int nPackage, int nForceSpec, int bFreeSpecPoint) {&lt;br /&gt;
    // Find specialization, and optionally add a spec point if none is found.&lt;br /&gt;
&lt;br /&gt;
        if (nForceSpec == 0) {&lt;br /&gt;
    &lt;br /&gt;
        int nSpecAbility = GetM2DAInt(TABLE_PACKAGES, &amp;quot;switch1_class&amp;quot;, nPackage); // followers can have only 1 advanced class&lt;br /&gt;
         if(nSpecAbility &amp;gt; 0)&lt;br /&gt;
         {&lt;br /&gt;
          AddAbility(oFollower, nSpecAbility);&lt;br /&gt;
         } else {&lt;br /&gt;
             if (bFreeSpecPoint) {&lt;br /&gt;
                 SetCreatureProperty(oFollower, 38, 1.00);&lt;br /&gt;
             }&lt;br /&gt;
         }                    &lt;br /&gt;
        &lt;br /&gt;
        } else {&lt;br /&gt;
         &lt;br /&gt;
             AddAbility(oFollower, nForceSpec);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* hireCustomFollower()  (See doco at top of page)&lt;br /&gt;
&lt;br /&gt;
I strongly suggest you reorder the parameters if you're adding many followers with advanced options.&lt;br /&gt;
&lt;br /&gt;
Feel free to leave them alone if you only want to set class, plot, spec or don't mind long declarations.&lt;br /&gt;
&lt;br /&gt;
Note nForceClass is currently compulsory due to flakiness with GetCreatureCoreClass()&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower(object oFollower, int nForceClass, string sPlot = &amp;quot;&amp;quot;, int nPlotFlag = 0, int nForceSpec = 0, &lt;br /&gt;
int nALTable = 0, int bInvokePicker = FALSE, int nInitialState = FOLLOWER_STATE_AVAILABLE, string sCurrPlot = &amp;quot;&amp;quot;, &lt;br /&gt;
int nCurrPlotFlag = 0, int nAutolevel = 0, int bFreeSpecPoint = TRUE, int nTargetLevel = 0, int nMinLevel = 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        object oHero = GetHero();&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN BASIC FOLLOWER JOIN BLOCK   ###################&lt;br /&gt;
&lt;br /&gt;
        This loosely replicates WR_SetFollowerState.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */    &lt;br /&gt;
        &lt;br /&gt;
        if (nForceClass == 0) {&lt;br /&gt;
            nForceClass = GetCreatureCoreClass(oFollower);           //This is not working.  Hence nForceClass mandatory.&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        SetGroupId(oFollower, GetGroupId(oHero));      //Puts the follower in the pc's Group.&lt;br /&gt;
        SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);  //This makes them act like a player.&lt;br /&gt;
        SetFollowerState(oFollower, nInitialState);  //This sets whether they are available, in the active party etc.&lt;br /&gt;
&lt;br /&gt;
        /* #################  END BASIC FOLLOWER JOIN BLOCK ##################### */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION #################&lt;br /&gt;
         This replicates the EVENT_TYPE_PARTY_MEMBER_HIRED handler from player_core, stripped down for simplicity and allowing our custom options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        Chargen_EnableTacticsPresets(oFollower);    //I assume this is important.&lt;br /&gt;
        &lt;br /&gt;
        SetLocalInt(oFollower, FOLLOWER_SCALED, 1);  //This should prevent the follower being rescaled by player_core or what have you&lt;br /&gt;
        &lt;br /&gt;
        int nPackage = GetPackage(oFollower);  //Gets the package, which will be used to find a number of 2DA IDs.&lt;br /&gt;
        int nPackageClass = GetM2DAInt(TABLE_PACKAGES, &amp;quot;StartingClass&amp;quot;, nPackage);  //I don't think this is used, even by player_core&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // set behavior according to package&lt;br /&gt;
        int nBehavior = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerBehavior&amp;quot;, nPackage);&lt;br /&gt;
&lt;br /&gt;
        if(nBehavior &amp;gt;= 0) {&lt;br /&gt;
            SetAIBehavior(oFollower, nBehavior);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        Chargen_InitializeCharacter(oFollower);      //We initialise the follower and choose race/class.&lt;br /&gt;
        &lt;br /&gt;
        Chargen_SelectRace(oFollower,GetCreatureRacialType(oFollower));&lt;br /&gt;
        Chargen_SelectCoreClass(oFollower,nForceClass);        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         if (nTargetLevel == 0) {   //This block picks a target level if not specified&lt;br /&gt;
            &lt;br /&gt;
              nTargetLevel = GetCustomFollowerTargetLevel(oFollower, oHero, nPackage, nMinLevel);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));      //Here is where the XP is calculated and rewarded&lt;br /&gt;
         RewardXP(oFollower, nXp, FALSE, FALSE);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // add hidden approval talents - (JN: I don't know how to set these yet, but when I figure it out this should make it work)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         int nIndex = Approval_GetFollowerIndex(oFollower);&lt;br /&gt;
         Approval_AddFollowerBonusAbility(nIndex, 0);&lt;br /&gt;
        &lt;br /&gt;
          //Handle Specialisation&lt;br /&gt;
          InitCustomFollowerSpec(oFollower, nPackage, nForceSpec, bFreeSpecPoint);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // This spends all available attribute and stat points on the&lt;br /&gt;
         // creature according to the levelup table.  (JN:  this replicates AL_DoAutoLevelUp but with our choice of table)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
         if (nALTable == 0) {&lt;br /&gt;
            nALTable = GetCustomFollowerALTable(oFollower);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         AL_SpendAttributePoints(oFollower, nALTable, FALSE);&lt;br /&gt;
         AL_SpendSkillPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
         AL_SpendSpecializationPoints(oFollower, nALTable);&lt;br /&gt;
         AL_SpendTalentSpellPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        // Update various UIs&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        Chargen_SetNumTactics(oFollower);&lt;br /&gt;
        SetCanLevelUp(oFollower,Chargen_HasPointsToSpend(oFollower));&lt;br /&gt;
&lt;br /&gt;
        // load tactics&lt;br /&gt;
         InitCustomFollowerTactics(oFollower, nPackage);&lt;br /&gt;
&lt;br /&gt;
         /* #################  END PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION ################# */     &lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
         SetAutoLevelUp(oFollower, nAutolevel);         //This is the autolevel flag on the character sheet.&lt;br /&gt;
         &lt;br /&gt;
         //Set plot flags&lt;br /&gt;
         &lt;br /&gt;
         if (!((sPlot == &amp;quot;&amp;quot;) || (nPlotFlag == 0))) {           //Joined Party&lt;br /&gt;
            WR_SetPlotFlag(sPlot, nPlotFlag, TRUE);   &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         if ((nInitialState == FOLLOWER_STATE_ACTIVE) || (nInitialState == FOLLOWER_STATE_LOCKEDACTIVE)) {&lt;br /&gt;
            if (!((sCurrPlot == &amp;quot;&amp;quot;) || (nCurrPlotFlag == 0))) {&lt;br /&gt;
                WR_SetPlotFlag(sCurrPlot, nCurrPlotFlag, TRUE);   //Currently in Party&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
                     &lt;br /&gt;
        // Invoke picker if requested.&lt;br /&gt;
&lt;br /&gt;
        if (bInvokePicker) {&lt;br /&gt;
             SetPartyPickerGUIStatus(2);&lt;br /&gt;
             ShowPartyPickerGUI();&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yeah, I know.  It can't really be any smaller.  Feel free to modify it if you're confident with scripting.&lt;br /&gt;
==== Add Your Custom Autolevel Template to GetCustomFollowerALTable() ====&lt;br /&gt;
While you can pass the ID you made for your autolevel template to that monster function as an argument, it's better to have them all in one place if you have multiple followers.&lt;br /&gt;
&lt;br /&gt;
GetCustomFollowerALTable() is the first function in our include, and you can add an explicit if test for your follower there to assign the correct table id (the one from your M2DA_base_ m2DA).  There is a function very much like it in sys_autolevel_h.nss for the core followers, so we'll copy Bioware's practice.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the function by itself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we have a test for each follower tag from my module, matching up to an ID which is assigned to nTable.  All you need to do is change a tag from my follower to yours, and my ID to the correct one from your M2DA_base_* m2DA.  Then you should delete the rest of the example if statements :)&lt;br /&gt;
&lt;br /&gt;
Save and export the script.  Ignore the compiler error about lack of main();&lt;br /&gt;
&lt;br /&gt;
=== Include Function In Your Hire Script and Call It ===&lt;br /&gt;
&lt;br /&gt;
So instead of a hire script that calls UT_HireFollower(), we want one that includes our shiny new function and calls it.&lt;br /&gt;
&lt;br /&gt;
Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //Make sure you include your party handling plot&lt;br /&gt;
#include &amp;quot;hireCustomFollower_h&amp;quot;  // And include the function script - which will in turn include a bunch of stuff&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
                    //Initialising my objects, not super-relevant to the example &lt;br /&gt;
                     &lt;br /&gt;
                    object oHero = GetHero();&lt;br /&gt;
                    object oMiera = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_miera.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oJysavin = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_jysavin.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oBraghon = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_braghon.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oSpider = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_geldual.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
&lt;br /&gt;
                    //Simplest hire call - adds to the party as a wizard.  Class is currently compulsory due to a bug.&lt;br /&gt;
                    hireCustomFollower(oMiera, CLASS_WIZARD);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party and set joining plot flags&lt;br /&gt;
                    hireCustomFollower(oJysavin, CLASS_WARRIOR, PLT_BC_CREATE_PARTY, PARTY_JYSAVIN_JOINED);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party, set plot flags, force a specialisation&lt;br /&gt;
                    hireCustomFollower(oBraghon, CLASS_ROGUE, PLT_BC_CREATE_PARTY, PARTY_BRAGHON_JOINED, ABILITY_TALENT_HIDDEN_ASSASSIN);&lt;br /&gt;
&lt;br /&gt;
                    //More complex example - Follower added as a unique class (Dog), not granted a specialisation or spec point.  &lt;br /&gt;
                    //Note unique classes must have an ALTable passed here or specified in GetCustomFollowerALTable() or they won't work&lt;br /&gt;
                    hireCustomFollower(oSpider, CLASS_DOG, PLT_BC_CREATE_PARTY, PARTY_GELDUAL_JOINED, 0, 0, FALSE, FOLLOWER_STATE_AVAILABLE, &amp;quot;&amp;quot;, 0, 0, FALSE);&lt;br /&gt;
                   &lt;br /&gt;
                    //Show the party picker to let the player choose from their new companions!&lt;br /&gt;
                    SetPartyPickerGUIStatus(2);&lt;br /&gt;
                    ShowPartyPickerGUI();                                                                                                                    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example shows several of the more simple ways of invoking the function.  Check the comments at the start of the function for a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
I would suggest best practice for most followers would be to call as follows:&lt;br /&gt;
&lt;br /&gt;
'''hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION)'''&lt;br /&gt;
&lt;br /&gt;
This will safely set the follower up as the desired class and specialisation (doubly important if there are spec abilities in their ALTable) while setting your plot flag for them being in the party.  hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION, 0, TRUE) will do the same while invoking the Party Picker automatically.&lt;br /&gt;
&lt;br /&gt;
Note that the specialisations are abilities and not classes - you'll find them as ABILITY_HIDDEN_ constants.&lt;br /&gt;
&lt;br /&gt;
If it's all worked, you should find you can now add followers with a lot more flexibility!&lt;br /&gt;
&lt;br /&gt;
[[File:picker_advanced.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Common Follower Problems &amp;amp; FAQ ==&lt;br /&gt;
&lt;br /&gt;
====Why don't my followers gain XP?====&lt;br /&gt;
There is a bug in UT_HireFollower. For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
(Note: Be aware if you use the name UT_HireFollower_Fixed you may end up finding your include file conflicting with someone else who has named it the same in their include.)&lt;br /&gt;
&lt;br /&gt;
Alternately you need to clear a flag in a separate script to the one in which they're hired.&lt;br /&gt;
&lt;br /&gt;
You must use the '''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);''' statement in a script you can be sure will run soon after your hiring script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====When I choose followers from the Party Picker, they spawn into the area but do not join.====&lt;br /&gt;
&lt;br /&gt;
You need to intercept the EVENT_TYPE_PARTYMEMBER_ADDED event and set the follower to FOLLOWER_STATE_ACTIVE.  See Simple Follower Creation earlier in this document.&lt;br /&gt;
&lt;br /&gt;
====My followers don't have skill trees!====&lt;br /&gt;
&lt;br /&gt;
If a follower hasn't been through an initial chargen/autolevel event (via player_core/sys_autolevel_h) then the skill tree doesn't show.  You're probably trying to be clever and get around UT_HireFollower without going all the way (see monster function above ^_^).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have a class====&lt;br /&gt;
&lt;br /&gt;
GetCreatureCoreClass() seems flaky under some conditions.  It's best to explicitly set the class yourself; this is why class is currently a mandatory argument to hireCustomFollower()&lt;br /&gt;
&lt;br /&gt;
====Dog talents don't work====&lt;br /&gt;
Symptoms: dog talents appear on the talents screen but remain greyed out on level up. Warrior talents appear in the quickslots.&lt;br /&gt;
&lt;br /&gt;
Line 78 of packages_base in packages.xls (Dog) should have the LevelUpTable column set to 257 which is the ALDog table.&lt;br /&gt;
&lt;br /&gt;
====Isn't there an easier way to do this?====&lt;br /&gt;
&lt;br /&gt;
Possibly.  There is a way of recruiting a follower by setting a plot flag.  However I don't understand it, and I expect it still doesn't allow custom autolevel templates, full control over specialisations etc.  There's still a fair bit of stuff hardcoded for the core followers, I'm not sure putting a custom follower through the same process as Al, Leli et al will have good results.&lt;br /&gt;
&lt;br /&gt;
The next section answers this question, up to a point.&lt;br /&gt;
&lt;br /&gt;
==== What if there are more than three potential followers? ====&lt;br /&gt;
This example handles larger numbers of followers, and doesn't force the player to use the party picker unless the party is already full.&lt;br /&gt;
&lt;br /&gt;
The prefix zzz, used throughout, can be replaced with whatever [[Prefixes_in_use | prefix]] you are using for your resources.&lt;br /&gt;
&lt;br /&gt;
If you're making a new campaign, to keep life simple, allocate a unique number to each follower. You could either use a creature variable or a script, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Party member id (e.g. 1=Alicia, 2=Godwin...)&lt;br /&gt;
int zzzPartyMemberID(object oPartyMember)&lt;br /&gt;
{&lt;br /&gt;
  string sPartyMember = GetTag(oPartyMember);&lt;br /&gt;
&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_alicia&amp;quot;) return 1;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_godwin&amp;quot;) return 2;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_harold&amp;quot;) return 3;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_lara&amp;quot;  ) return 4;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make two separate plots, e.g. zzzpt_hired for when a follower is first recruited, and zzzpt_party to flag whether they're currently in the party. Use flag values that correspond to the unique follower id, e.g. ZZZPT_HIRED_GODWIN will be 2.&lt;br /&gt;
&lt;br /&gt;
If you're modifying the official campaign, you won't be able to make this simplification - you'll need a set of plot flags for your new party members, similar to the official ones. The logic of what follows is still correct, it just means that instead of having one set of common code that works for everyone, you have to explicitly script each party member individually using their personal plot flags.&lt;br /&gt;
&lt;br /&gt;
Follower conversation is now very simple. In Godwin's dialogue, the hiring line will be conditional - when ZZZPT_HIRED_GODWIN is clear - and it will set ZZZPT_HIRED_GODWIN.  No conversation script is necessary. Instead, in the properties of the plot zzzpt_hired, we add a plot event script, as follows.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// PARTY HIRE PLOT SCRIPT&lt;br /&gt;
//&lt;br /&gt;
// This is called in conversation when a party member is hired for the first time.&lt;br /&gt;
// If the party is full, the party picker is displayed, which forces the PARTYMEMBER_ADDED&lt;br /&gt;
// module event.&lt;br /&gt;
//&lt;br /&gt;
// The flag value is never referenced, because the code is common for all party members.&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;log_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plot_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;zzz_h&amp;quot;                  // A header containing the zzzPartyMemberID function&lt;br /&gt;
#include &amp;quot;plt_zzzpt_hired&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_zzzpt_party&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int StartingConditional()&lt;br /&gt;
{&lt;br /&gt;
    event  eParms             = GetCurrentEvent();&lt;br /&gt;
    int    nType              = GetEventType(eParms);       // GET or SET&lt;br /&gt;
    string strPlot            = GetEventString(eParms, 0);  // Plot GUID&lt;br /&gt;
    int    nFlag              = GetEventInteger(eParms, 1); // Plot flag&lt;br /&gt;
    object oParty             = GetEventCreator(eParms);    // Plot table owner&lt;br /&gt;
    object oFollower          = GetEventObject(eParms, 0);  // Conversation owner (if any)&lt;br /&gt;
    int    nPlotType          = GetEventInteger(eParms, 5); // Plot type&lt;br /&gt;
&lt;br /&gt;
    int    bIsTutorial        = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsTutorial&amp;quot;, nPlotType);&lt;br /&gt;
    int    bIsCodex           = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsCodex&amp;quot;, nPlotType);&lt;br /&gt;
&lt;br /&gt;
    int    nResult            = FALSE;                      // return value for DEFINED GET&lt;br /&gt;
    object oPC                = GetPartyLeader();&lt;br /&gt;
&lt;br /&gt;
    plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info&lt;br /&gt;
&lt;br /&gt;
    if (nType == EVENT_TYPE_SET_PLOT) // actions -&amp;gt; normal flags only&lt;br /&gt;
    {&lt;br /&gt;
        int nValue    = GetEventInteger(eParms, 2); // 0=Clear 1=Set&lt;br /&gt;
        int nOldValue = GetEventInteger(eParms, 3); // Current flag value&lt;br /&gt;
&lt;br /&gt;
        if (nValue)&lt;br /&gt;
          {&lt;br /&gt;
            if (GetArraySize(GetPartyList(oPC)) &amp;lt; 4)&lt;br /&gt;
              {&lt;br /&gt;
                UT_HireFollower(oFollower);&lt;br /&gt;
                SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
                AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
                SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
                WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
              }&lt;br /&gt;
            else&lt;br /&gt;
              {&lt;br /&gt;
                WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
                SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);&lt;br /&gt;
                SendPartyMemberHiredEvent(oFollower, TRUE);&lt;br /&gt;
//                SetPartyPickerGUIStatus(PP_GUI_STATUS_USE);&lt;br /&gt;
//                ShowPartyPickerGUI();&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
     else // EVENT_TYPE_GET_PLOT -&amp;gt; defined conditions only&lt;br /&gt;
     {&lt;br /&gt;
        switch(nFlag)&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    plot_OutputDefinedFlag(eParms, nResult);&lt;br /&gt;
    return nResult;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We still need to handle the party picker events in our module event script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         // PARTY MEMBER ADDED - Allow XP gain. Come here, follow me, flag as party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
         {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
            break;&lt;br /&gt;
         }&lt;br /&gt;
         // PARTY MEMBER DROPPED - flag as not party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_DROPPED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), FALSE);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
When we need to refer to a particular follower explicitly, we can still do so - for example, the flag ZZZPT_PARTY_GODWIN will tell use whether Godwin is currently in the party or not.&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation: An Alternative Approach ==&lt;br /&gt;
&lt;br /&gt;
While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfectly good wheel at hand. The following describes how to adapt the existing machinery for the recruitment and tracking of your own party members.&lt;br /&gt;
&lt;br /&gt;
First create the setup as described above in Simple Follower Creation, except for the scripts and plot tables. In addition, create the GDA extensions for a level-up table and the M2DA which points to those tables, as described in Advanced Follower Creation above.&lt;br /&gt;
&lt;br /&gt;
Now ...&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Create a party plot table ===&lt;br /&gt;
&lt;br /&gt;
Have a look at the gen00pt_party plot table and create a similar table for your own followers. Don't bother with the Defined Flags for the moment, just the Main Flags will do, ie recruited, in-camp and in-party for each follower. (Critical Note: Do not duplicate the plot table, create one from scratch. This is the case for ALL plot tables because of a show-stopping bug which means a new GUID is not assigned on Duplicate of a plot.)&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create a party script ===&lt;br /&gt;
&lt;br /&gt;
Duplicate the gen00pt_party script and rename for your module (conventionally plot tables and their plot scripts have the same name). Delete (or comment out) the Defined Flags section at the end and any lines dealing with logging and tutorials. Change names to those of your party members. If you are using gifting, approval or forced inclusion you may wish to retain those sections of code, but additional machinery will be needed for these facilities to work. For approval you can specify a starting level of approval here for each follower if you want it to be other than zero (as per the existing section dealing with Dog). Note that the custom hire function at the head of the script allows you to specify whether or not to invoke the party picker on recruitment. You may not want to do so for the first couple of followers (but see below). You should already have defined all required constants in a separate file for your module, eg &amp;lt;module prefix&amp;gt;_constants_h. If not, do so now and include it, as well as your plot table, at the head of the script. Delete includes that only refer to the main campaign. (If this is all Greek to you, spend a couple of hours examining the set-up of the Demo, which is packaged with the toolset, and go through the introductory tutorials referenced on the main page of this wiki).&lt;br /&gt;
&lt;br /&gt;
Looking at the new party script, notice that the follower-in-camp function is not defined. This is because for some arcane reason it is defined in party_h, and unhappily references the main campaign's plot table. So we will have to create a new function to replace it, change the other function's flag reference (for the sake of neatness), and change the call in the main body of the script. (You may decide later for other reasons to replicate and customise party_h, but that won't interfere with re-creating this function here.)&lt;br /&gt;
&lt;br /&gt;
Our two functions at the head of the script should be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;void SetFollowerInParty(object oFollower, string sPlot, int nCampFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nCampFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, TRUE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE);&lt;br /&gt;
    command cJump = CommandJumpToObject(GetPartyLeader());&lt;br /&gt;
    WR_AddCommand(oFollower, cJump);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SetFollowerInCamp(object oFollower, string sPlot, int nPartyFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nPartyFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, FALSE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
}&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the line in the in-camp sections for each follower should now be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;SetFollowerInCamp(o&amp;lt;follower&amp;gt;, strPlot, &amp;lt;follower&amp;gt;_IN_PARTY);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Step 3: Create package GDAs and reference them in you 2DA_base extension ===&lt;br /&gt;
&lt;br /&gt;
Look at the packages_base GDA and create an extension GDA with one line for each follower based on a main campaign follower that is most like your own follower, eg a sword-shield warrior can be a copy of Alistair, a battle mage a copy of Morrigan, etc. You can look at the Excel version of this GDA to more easily see what the fields mean. It is here that you can specify what if any specialisation will be assigned on hire and the level at which this spec point becomes available. (The IDs for each spec are in the 4000-range of ABI_base.)&lt;br /&gt;
&lt;br /&gt;
Most importantly, it is here also that you define the ID of both your level-up table and the AIP table you are about to create.&lt;br /&gt;
&lt;br /&gt;
Now create aip_follower_&amp;lt;follower name&amp;gt; gda tables, again based on a existing tables most like your own followers. No changes should be required to the copies you create.&lt;br /&gt;
&lt;br /&gt;
In the m2da_base_&amp;lt;your module&amp;gt; extension you have already created, add lines for your AIP tables with a package ID referencing the IDs you assigned in your packages extension table.&lt;br /&gt;
&lt;br /&gt;
Carefully check that all IDs in your GDAs are correct and cross-reference properly, and save the GDAs to your override directory.&lt;br /&gt;
&lt;br /&gt;
Desirable but not obligatory (except for non-humanoid characters), is an extension to the Portraits gda. Finally the Equipment Layout gda will need an extension for non-humanoids, who use a different equipment mask.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Module script addition ===&lt;br /&gt;
&lt;br /&gt;
Modify your own module script to point to the new plot table and your own followers. To see an example of the required code for the two new sections look at the relevant section of module_core, which are for EVENT_TYPE_PARTYMEMBER_ADDED and EVENT_TYPE_PARTYMEMBER_DROPPED.&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The recruit flag is set in a conversation (usually, but it could be a script) and that event is then processed by the plot script, which among other things sets both the in-camp and in-party flags, and fires up the party picker by default. If the player then selects the follower in the picker, the in-camp flag is unset (or vice versa if the follower is not selected to join). Subsequently, if the character is selected (or unselected) in the picker, the event is picked up by the module script, which sets the relevant plot flag as true, and that plot event is then sent to the plot scipt which sets the other flag as false. &lt;br /&gt;
&lt;br /&gt;
(Note that if the party picker is turned off for a particular follower's recruit event, that follower will be placed in the active party regardless of the number of members, so ONLY do this for a follower who cannot be recruited when there are already 3 possible followers.)&lt;br /&gt;
&lt;br /&gt;
On recruitment, player_core rebuilds the character according to the specifications laid out in the GDAs, so no further scripting is required.&lt;br /&gt;
&lt;br /&gt;
=== Uses ===&lt;br /&gt;
&lt;br /&gt;
To recruit a party member, set the recruit flag from your plot table in the relevant dialogue. Adding or subtracting followers from the active party is automatically tracked via this machinery, and the plot flags can be interrogated in all your scripts and conversations if you need to know who is currently in the party and who is in camp.&lt;br /&gt;
&lt;br /&gt;
Defined flags can be added as you need them to the script and plot table but there is no point having flags that you will not use, so as with all Defined Flags this is an as-you-go decision, but quite easy to do.&lt;br /&gt;
&lt;br /&gt;
Hiring and firing of temporary party members at the start of a campaign (such as Ser Jory, or Jowan, or Soris, etc) can be handled by UT_HireFollower, and the party picker is not invoked (nor is the Party Camp an available destination).&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If you haven't done so already, create a simple debugging area for your module where you can dump the player, all followers and a couple of conversation dummies, and set up a dialogue in which you can invoke all required flags and conditions and see if they actually work as expected. (This setup can be used to test many other components as well.) Global machinery such as this can be painful to set up and get right (unless you are of an exceptionally methodical cast of mind), but it is worthwhile to ensure they are absolutely bullet-proof before you develop the specifics of your module.&lt;br /&gt;
&lt;br /&gt;
=== The KISS principle ===&lt;br /&gt;
&lt;br /&gt;
This is an &amp;quot;out-of-the-box&amp;quot; solution, and once set up is quite robust. If you want variants not catered for here, do NOT try to modify what you already have working.&lt;br /&gt;
&lt;br /&gt;
'''Use-case:''' You want a follower (example tag: dairren) to be recruited without a set specialisation and one level higher than the PC.&lt;br /&gt;
&lt;br /&gt;
Go to your packages gda and set the spec field to 0. In the character's plot table (you should have at least one for each follower) create a flag which we will call BLAH_BLAH. In the table's plot scipt insert the following very simple event handler:&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;dascript&amp;gt;case BLAH_BLAH:&lt;br /&gt;
         {&lt;br /&gt;
           SetCreatureProperty(oDairren, 38, 1.00); //awards the spec point; field from the properties gda&lt;br /&gt;
           int aLevel = GetLevel(oHero); //some simple arithmetic to find out the XP we need to award&lt;br /&gt;
           int bLevel = (aLevel+1);&lt;br /&gt;
           int aPoints = RW_GetXPNeededForLevel(aLevel);&lt;br /&gt;
           int bPoints = RW_GetXPNeededForLevel(bLevel);&lt;br /&gt;
           int targetPoints = (bPoints - aPoints);&lt;br /&gt;
           RewardXP(oDairren, targetPoints, FALSE, TRUE); //award the XP, and we're done&lt;br /&gt;
           break;&lt;br /&gt;
	 }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The flag can be set in the same conversation as the recruit flag, so long as it comes afterwards. This way you not only maintain the integrity of your core machinery, but keep exceptions/variations for particular characters where they belong -- with that character's plot tables and scripts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
{{Languages}}&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15203</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15203"/>
				<updated>2010-12-11T11:50:15Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: Added line on portraits gda&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Simple Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
Follow these steps to create a follower that&lt;br /&gt;
&lt;br /&gt;
- Levels up with a default package&lt;br /&gt;
&lt;br /&gt;
- Can be chosen from the party picker&lt;br /&gt;
&lt;br /&gt;
- Can gain XP&lt;br /&gt;
&lt;br /&gt;
This guide assumes you know how to create a creature and are comfortable with basic scripting.&lt;br /&gt;
&lt;br /&gt;
You should only use this simple method if you are sure there will be empty space in the active party when your follower is recruited.&lt;br /&gt;
&lt;br /&gt;
A more comprehensive approach when there are more than three potential party members is discussed in the FAQ below. It's worth taking the time to understand the basics first, though. &lt;br /&gt;
&lt;br /&gt;
=== Create the creature ===&lt;br /&gt;
&lt;br /&gt;
Create a creature to act as your follower.  Set its name, appearance, gender, head morph, conversation, inventory etc as you want them to behave in-game.&lt;br /&gt;
&lt;br /&gt;
Set an appropriate '''Tag''' (you'll be using it a lot).  I suggest &amp;quot;party_charname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Make sure you choose a '''Class'''.  For most followers this should be Rogue, Warrior or Wizard.&lt;br /&gt;
&lt;br /&gt;
[[File:class.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under Package/Scaling set:&lt;br /&gt;
&lt;br /&gt;
'''General Package Type''' to be '''Party Members'''&lt;br /&gt;
&lt;br /&gt;
'''Package''' to be an appropriate value (probably &amp;quot;Generic - Wizard&amp;quot; or similar)&lt;br /&gt;
&lt;br /&gt;
'''Package AI''' (there should only be one choice)&lt;br /&gt;
&lt;br /&gt;
'''Rank''' to be '''Player'''&lt;br /&gt;
&lt;br /&gt;
[[File:package.jpg]]&lt;br /&gt;
&lt;br /&gt;
Save and export your character as normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overlay char_stage ===&lt;br /&gt;
&lt;br /&gt;
In the official campaign, the party picker uses a special area called char_stage. Whether you're extending the official campaign or making a standalone campaign, there is a function that allows you to overlap the offical stage with your own, so that both stages are active simultaneously in game.&lt;br /&gt;
&lt;br /&gt;
In your resource palette, right-click char_stage under the Global folder and select Duplicate to make a copy of the stage with a new resource name, e.g. my_char_stage. In the resource properties, ensure that both Module and Owner Module are set to your module, and the folder of your choice.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:area_palette.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a new waypoint for your follower to appear on the party picker.  This waypoint '''must''' have a tag in the form of &amp;quot;char_&amp;quot; followed by the exact tag of your follower.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:char_stage.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example the tag of my follower is '''bc_party_miera''' so her waypoint tag must be '''char_bc_party_miera'''&lt;br /&gt;
&lt;br /&gt;
For a standalone module (such as in this example), put your waypoint wherever you please.  The illustrated one is directly on top of Morrigan's.  For an add-in to the main campaign, you should position your wp appropriately relative to the core party members.&lt;br /&gt;
&lt;br /&gt;
Save and export the area.&lt;br /&gt;
&lt;br /&gt;
Add the following to your module event script:&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
case EVENT_TYPE_MODULE_GETCHARSTAGE:&lt;br /&gt;
{&lt;br /&gt;
   // Overlay the existing stage with my stage&lt;br /&gt;
   // &amp;quot;my_char_stage&amp;quot; is the resource name of the overlay area&lt;br /&gt;
   // &amp;quot;partypicker&amp;quot; is the name of the default GDA&lt;br /&gt;
   SetPartyPickerStage(&amp;quot;my_char_stage&amp;quot;, &amp;quot;partypicker&amp;quot;);&lt;br /&gt;
   break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create m2DAs for the Party Picker ===&lt;br /&gt;
&lt;br /&gt;
You will need to create two Excel spreadsheets.&lt;br /&gt;
&lt;br /&gt;
The first should be named (both worksheet and file) '''partypicker_''' with a unique suffix.  In this example, my first spreadsheet is named partypicker_fofbc.xls with a worksheet name of partypicker_fofbc - the suffix being the acronym of my module.&lt;br /&gt;
&lt;br /&gt;
Set up your columns as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:partypickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' for your follower must be '''12 or higher'''.  11 is the highest value used in the base 2DA.  12 is fine for standalone modules, add-ins will probably want to use an arbitrarily high number to avoid potential conflicts.&lt;br /&gt;
&lt;br /&gt;
The '''Label''' should be the follower's name as you wish it to appear on the party picker.&lt;br /&gt;
&lt;br /&gt;
The '''Tag''' must be your follower's tag.&lt;br /&gt;
&lt;br /&gt;
All other values are non-functioning defaults and should be specified as in the image above unless you know explicitly what you're doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION ANIMATIONS'''&lt;br /&gt;
 &lt;br /&gt;
Add Animation and Remove Animation are actually Id numbers of different animations, taken from anim_base.gda&lt;br /&gt;
&lt;br /&gt;
Enter and Exit version of animations are generally the best ones to use, altough one can try others. NOT ALL ANIMATIONS WILL WORK, since some require special conditions.&lt;br /&gt;
Here are some examples you can use:&lt;br /&gt;
&lt;br /&gt;
819 - talk cursing&lt;br /&gt;
&lt;br /&gt;
629 - reading a book (doesn't work, since it probably requires a book object)&lt;br /&gt;
&lt;br /&gt;
844 - hands behind back (848 and 849 are Enter and Exit versions respectfully)&lt;br /&gt;
&lt;br /&gt;
850 - chest pounding salute&lt;br /&gt;
&lt;br /&gt;
811 - fist pounding&lt;br /&gt;
&lt;br /&gt;
277 - dance&lt;br /&gt;
&lt;br /&gt;
247 - cast area spell&lt;br /&gt;
&lt;br /&gt;
500 - vfx cast&lt;br /&gt;
&lt;br /&gt;
600 - surprised&lt;br /&gt;
&lt;br /&gt;
603 - praying&lt;br /&gt;
&lt;br /&gt;
607 - head bow&lt;br /&gt;
&lt;br /&gt;
609 - standing at attention&lt;br /&gt;
&lt;br /&gt;
651,652 - crouch pray (Enter and exit)&lt;br /&gt;
&lt;br /&gt;
808 - point forward&lt;br /&gt;
&lt;br /&gt;
825 - nodding&lt;br /&gt;
&lt;br /&gt;
840 - hand chop or frustration&lt;br /&gt;
&lt;br /&gt;
905,906 - crouch (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
919,920 - sit on ground (enter, exit)&lt;br /&gt;
&lt;br /&gt;
965 - kneel down loop&lt;br /&gt;
&lt;br /&gt;
972 - wipe nose&lt;br /&gt;
&lt;br /&gt;
976,977 - squat (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
986 - wipe eyes&lt;br /&gt;
&lt;br /&gt;
998,999 - hands clasped (Enter, exit)&lt;br /&gt;
&lt;br /&gt;
3029 - inspect nails&lt;br /&gt;
&lt;br /&gt;
3031,3032 - playful (enter, exit)&lt;br /&gt;
&lt;br /&gt;
3054,3056 - slouch (enter, exit)&lt;br /&gt;
255 - in-place fly&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION VFX''' &lt;br /&gt;
&lt;br /&gt;
The VFX column is the ID of the vFX effect taken from vFx_base.gda. This one is a bit more tricky, since it also references the BlendTree value from the same file.&lt;br /&gt;
Find the ID of the spell effect and look for the BlendTreeName column (should the the 12th columun) and enter BOTH into the respective columns for your character in the partypicker file.&lt;br /&gt;
&lt;br /&gt;
Some examples:&lt;br /&gt;
&lt;br /&gt;
ID      ---      BLENDTREENAME      ---   EFFECT&lt;br /&gt;
&lt;br /&gt;
6039    ---     fxm_energy_up_p    ---    Lady of the Forest pillar of light&lt;br /&gt;
&lt;br /&gt;
6040    ---     fxm_power_in_p      ---   Branka - power in&lt;br /&gt;
&lt;br /&gt;
3054    ---     fxc_lotf_c          ---   Lady of the Forest - swirling leaves&lt;br /&gt;
&lt;br /&gt;
3009    ---     fxc_succubus_c     ---    Succubus crust&lt;br /&gt;
&lt;br /&gt;
1549    ---     fxa_hly_imp_c       ---   Holy Impact crust&lt;br /&gt;
&lt;br /&gt;
1076    ---     fxa_spi_aur_mht_c   ---   Spirit - Aura Might crust&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second spreadsheet should be named '''party_picker_''' (note middle underscore).  Once again append your unique suffix (in this example party_picker_fofbc.xls with party_picker_fofbc as its worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up your columns and data like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:party_pickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''ID''' and '''Tag''' should match what you did in the first spreadsheet.  Specify INVALID COLUMN for the third column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're familiar with m2DAs, generate them from these files, copy them to your module's override directory, and skip to the next step.  Otherwise, read on:&lt;br /&gt;
&lt;br /&gt;
- Go to '''\Program Files\Dragon Age\tools\ResourceBuild\Processors''' (or wherever you installed Dragon Age)&lt;br /&gt;
&lt;br /&gt;
- Copy '''ExcelProcessor.exe''' from that folder to whichever folder has the excel sheets you just created.&lt;br /&gt;
&lt;br /&gt;
- Drag and drop your xls files onto ExcelProcessor.  This will create .gda files.&lt;br /&gt;
&lt;br /&gt;
- Copy these .gda files to your module's export directory (probably \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetexport).  Make sure they are included in your .dazip when the time comes to build your module.&lt;br /&gt;
&lt;br /&gt;
If you are an OpenOffice user and have trouble with ExcelProcessor, you can use [http://social.bioware.com/project/755/ GDApp] to directly create the 2DAs.  It rocks!&lt;br /&gt;
&lt;br /&gt;
=== Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event ===&lt;br /&gt;
&lt;br /&gt;
Amusingly enough, the Party Picker does not actually add followers to the party.  However it raises an event that allows you to do so.  Your module script needs to capture this event and execute some code.&lt;br /&gt;
&lt;br /&gt;
The following example shows what to do with the event.  The full script would work as a module script for an add-in (assuming it didn't need to do anything else), but otherwise you'll have to incorporate the event into your own module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);  //Allows the follower to gain XP&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);  //Adds follower to the active party&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE)''' is the key statement to add the follower to the active party.  You must have this.&lt;br /&gt;
&lt;br /&gt;
'''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0)''' is a bug-fix, as followers hired with UT_HireFollower() do not receive XP by default.  This statement fixes that, and I consider it best practice to keep it in this event to ensure it is always set.  You will not wish to do this if you want a follower that should not gain XP to be on the party picker.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you do not need to intercept the corresponding event for a party member being removed - the party picker handles spawning/despawning, and thus will successfully remove members.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&lt;br /&gt;
&lt;br /&gt;
=== Create Your Hiring Script ===&lt;br /&gt;
&lt;br /&gt;
Now all that remains is to actually hire the follower :)&lt;br /&gt;
&lt;br /&gt;
Create a script to handle the hiring (which will most likely be fired from a conversation).  The script is quite simple:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
        object oFollower = GetObjectByTag(&amp;quot;bc_party_miera&amp;quot;); //Use CreateObject() if the creature isn't present in the module yet&lt;br /&gt;
&lt;br /&gt;
        UT_HireFollower(oFollower);   //Hires the follower&lt;br /&gt;
&lt;br /&gt;
        SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
        ShowPartyPickerGUI();  //Shows the Party Picker; necessary for the follower to gain XP&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use your own follower's tag and not the example one :)&lt;br /&gt;
&lt;br /&gt;
This script fires the party picker after hiring the follower.  That is absolutely necessary via this method, as we have put the XP fix onto an event fired by the party picker.  You cannot put the XP fix into this script, it must be called from a later one (the bug is caused by an errant call to an event in player_core, which will be executed AFTER this script).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If everything worked, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_success.jpg|thumb|200px|center]]&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow these steps to have full control over the creation of your follower, with options such as:&lt;br /&gt;
&lt;br /&gt;
- Unique level-up template&lt;br /&gt;
&lt;br /&gt;
- Class and specialisation chosen via script&lt;br /&gt;
&lt;br /&gt;
- Any starting state&lt;br /&gt;
&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&lt;br /&gt;
&lt;br /&gt;
- Set plot flags in the call to the hire script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prepare Creature, char_stage and Party Picker m2DAs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the same steps to create your follower creature, char_stage and Party Picker m2DAs as above.&lt;br /&gt;
&lt;br /&gt;
=== Create Party Plot ===&lt;br /&gt;
&lt;br /&gt;
While not necessary, it's very helpful to have plot flags set when a follower is hired or joins/leaves the active party.  This makes conversation interjections and the like very easy.&lt;br /&gt;
&lt;br /&gt;
Create a plot with appropriate flags.  There's no real need to associate journal text with them:&lt;br /&gt;
&lt;br /&gt;
[[File:follower_plot.jpg]]&lt;br /&gt;
&lt;br /&gt;
See FAQ for an alternative approach to plots when there are more than three potential party members.&lt;br /&gt;
&lt;br /&gt;
=== Add Plot Flags to Party Picker Event Intercept ===&lt;br /&gt;
&lt;br /&gt;
We then update our module script to make use of that plot, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //make sure you include your own plot, not mine&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            &lt;br /&gt;
            if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               //You must explicitly test for your follower's tag.&lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, TRUE);     //Make sure you use your own flags!&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            break;&lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_DROPPED:                    &lt;br /&gt;
        {&lt;br /&gt;
              object oFollower = GetEventObject(ev, 0); &lt;br /&gt;
              &lt;br /&gt;
              if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) { &lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, FALSE);     //As above, but set false.&lt;br /&gt;
              }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create a Level Up Template ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can skip this step if you're content to use one of the generic Rogue, Wizard or Warrior templates, but I don't recommend it.  Making a template that suits your character is easy and will almost always be better for the player than a generic one that spends points poorly.&lt;br /&gt;
&lt;br /&gt;
Go to \Program Files\Dragon Age\tools\Source\2DA (or wherever you installed Dragon Age).&lt;br /&gt;
&lt;br /&gt;
You should see a number of excel sheets of the form '''ALCharacter.xls''' (such as ALAlistair.xls, ALLeliana.xls, ALRogue_Default.xls etc).  Open the one closest to your character (ie Morrigan or Wynne for a wizard, Leliana or Zevran for a rogue).  Save a copy as '''ALYourcharacter.xls''' in whatever directory you're using to create your 2DAs, remembering to rename the worksheet '''ALYourcharacter''' (in this example, ALMiera.xls with ALMiera as its worksheet).&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:ALtable.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns B''' and '''C''' are the talents/spells available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
'''Columns F''' and '''G''' are the skills available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
We will edit the remaining columns like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Stat Weights ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The stat weights in '''column J''' determine how the follower will spend their attribute points, in a rough ratio.  So if Dexterity is set to 1.5 and Intelligence to 1, you should expect to see 3 points of Dex for every 2 points of Cunning in-game (note Intelligence is the label used in the toolset for Cunning).&lt;br /&gt;
&lt;br /&gt;
Simply change the values in J to reflect how you'd like the character to spend their points.  In this example we're creating a wizard, so we're not going to mess around:&lt;br /&gt;
&lt;br /&gt;
[[File:miera_stat_weights.jpg]]&lt;br /&gt;
&lt;br /&gt;
This character will only raise magic.  I set the value to 5 rather than something like 1 to provide room underneath for the other stats while still overwhelmingly favouring magic, but in practice I only really ever want that one stat. &lt;br /&gt;
&lt;br /&gt;
In a note left on this column in the existing templates, Bioware's Georg Zoeller writes, &amp;quot;This is the weight of each attribute (row id links into properties.xls.id). 1.0 means 'try to keep this attribute level' (spend 1 point per level). 0.5 means 'try to spend 1 point every two levels' and so on.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The default Mage, Rogue and Warrior templates include '''column L''' labeled &amp;quot;AttInit.&amp;quot; Editing these values seems to have no effect on followers set to use these templates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Talent and Skill Priorities ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns D''' and '''E''' are the talents/spells that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
'''Columns H''' and '''I''' are the skills that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change these, just copy the appropriate two cells from columns B&amp;amp;C or F&amp;amp;G over the ones you want to replace.&lt;br /&gt;
&lt;br /&gt;
For example, here we're copying Morrigan's template.  Morrigan has Spider Shape high in her preferences, which we do not want.&lt;br /&gt;
&lt;br /&gt;
[[File:AlMori_talent_pref.jpg]]&lt;br /&gt;
&lt;br /&gt;
We decide we'd prefer Flame Blast, so we find it in columns B&amp;amp;C and copy both cells:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_copy.jpg]]&lt;br /&gt;
&lt;br /&gt;
Then we select the cells we want to replace in columns D&amp;amp;E and paste over them:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_paste.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue this process until your priorities list for both skills and talents/spells is exactly as you want it.  Make sure you have at least as many priorities as the core follower you're copying - points that cannot be spent according to these priorities have a habit of vanishing.&lt;br /&gt;
&lt;br /&gt;
If you used any abilities from a specialisation, make sure you remember to set that specialisation with the function we'll introduce later.  The autolevel scripts will add specialisation abilities to a character regardless of whether they have that spec or not.&lt;br /&gt;
&lt;br /&gt;
==== Create a M2DA_base_ m2DA ====&lt;br /&gt;
&lt;br /&gt;
Dragon Age will need to know where to find your autolevel template.  We tell it by extending M2DA_base.gda&lt;br /&gt;
&lt;br /&gt;
Create a spreadsheet with the name and worksheet name in the form '''M2DA_base_''' with your unique suffix (in this example, M2DA_base_fofbc.xls with M2DA_base_fofbc as a worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up its columns and data like so (note I used GDApp because Open Office wasn't cooperating for this one!):&lt;br /&gt;
&lt;br /&gt;
[[File:m2da_base_fofbc.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' should be very high to avoid conflicts.  I've arbitrarily chosen 50,000+ here.  Carefully note the ID you've chosen for your character, you will need it later.&lt;br /&gt;
&lt;br /&gt;
Set the '''Label''' and '''Worksheet''' to be the name of your autolevel template worksheet (ALCharactername if you've been following this).&lt;br /&gt;
&lt;br /&gt;
Set the '''PackageIDForAI''' to be 0, it shouldn't be needed for followers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you're done, use ExcelProcessor to make GDAs of both spreadsheets and copy them to your module's export folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FOR AUTOLEVEL TO WORK AFTER RECRUITING:&lt;br /&gt;
&lt;br /&gt;
Look in packages.xls. &lt;br /&gt;
There is a column called LevelupTable. That links to a corresponding AL* table. For instance,  row 81 is for Leliana. Her LevelupTable value is 258. If you look that up in 2DA_base, you'll see it links to ALLeliana.&lt;br /&gt;
(alternatively, you could try packages_base.gda)&lt;br /&gt;
&lt;br /&gt;
=== Create a New Hire Function Include ===&lt;br /&gt;
&lt;br /&gt;
Many vital steps of follower addition happen inside an event in player_core.  Followers tend to be extremely buggy (no skill tree, for example) if this event does not fire.&lt;br /&gt;
&lt;br /&gt;
However, that event is not very flexible.  In order to control it to our requirements, we need to replicate its functionality inside our own script.  This is probably much safer than messing with player_core directly!&lt;br /&gt;
&lt;br /&gt;
Create a new script file, naming it something like '''hireCustomFollower_h'''.  We will be including this wherever we want to hire a follower.&lt;br /&gt;
&lt;br /&gt;
Paste in the following script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;approval_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_autolevelup_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*  Jye Nicolson 5-Jan-2010&lt;br /&gt;
This function set duplicates the full functionality chain of UT_HireFollower, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
-  Followers can gain XP&lt;br /&gt;
-  Autolevel status can be set (default off)&lt;br /&gt;
-  Followers can be set to any starting state (default Available) and will still be properly initalised and added to the party pool&lt;br /&gt;
-  Autolevel tables for non-core followers can be explicitly set.&lt;br /&gt;
-  Class and Specialisation can be chosen via script&lt;br /&gt;
-  Followers without specialisations are granted a spec point by default.&lt;br /&gt;
&lt;br /&gt;
It should only ever be called once each for characters you intend to be full followers.&lt;br /&gt;
Much of the protective code handling summoned creatures etc. in player_core is not present here.&lt;br /&gt;
&lt;br /&gt;
Calling the function:&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR);&lt;br /&gt;
&lt;br /&gt;
Change the class to CLASS_WIZARD or CLASS_ROGUE as appropriate.  &lt;br /&gt;
This will hire your follower and make them available.  &lt;br /&gt;
They will auto level up with a default package, and receive a free spec point.&lt;br /&gt;
&lt;br /&gt;
Best Practice:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR, PLT_YOUR_PARTY_PLOT, YOUR_FOLLOWER_JOINED_FLAG, ABILITY_TALENT_HIDDEN_CHAMPION);&lt;br /&gt;
&lt;br /&gt;
Where the plot and flag are those for your module (remember to create the plot and include it on the calling script), and ABILITY_TALENT_HIDDEN etc is the desired spec.&lt;br /&gt;
&lt;br /&gt;
You should also have a custom ALTable set up.  &lt;br /&gt;
See wiki for details, and remember to edit it in to GetCustomFollowerALTable below or pass it directly as an argument to hireCustomFollower.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Full argument list:&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower (&lt;br /&gt;
        object oFollower,   //Pass your follower object, mandatory&lt;br /&gt;
        &lt;br /&gt;
        int nForceClass,    //Pass a Class constant here, usually CLASS_ROGUE, CLASS_WARRIOR, CLASS_WIZARD.  Mandatory due to a bug.&lt;br /&gt;
        &lt;br /&gt;
        string sPlot = &amp;quot;&amp;quot;,   //It's recommended you have a plot flag to be set when the follower joins.  Pass the plot constant here.  Remember to #include in calling script&lt;br /&gt;
        &lt;br /&gt;
        int nPlotFlag = &amp;quot;&amp;quot;,  //And then pass the flag constant.  Will be set to TRUE if available.&lt;br /&gt;
        &lt;br /&gt;
        int nForceSpec = 0,  //This is the ID of the Specialisation you want.  Note they are NOT classes, but abilities.  The full list is:&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_ARCANE_WARRIOR, ABILITY_SPELL_HIDDEN_BLOODMAGE, ABILITY_SPELL_HIDDEN_SHAPESHIFTER, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_BARD, ABILITY_TALENT_HIDDEN_ASSASSIN, ABILITY_TALENT_HIDDEN_DUELIST, ABILITY_TALENT_HIDDEN_RANGER&lt;br /&gt;
                             //ABILITY_TALENT_HIDDEN_BERSERKER, ABILITY_TALENT_HIDDEN_CHAMPION, ABILITY_TALENT_HIDDEN_REAVER, ABILITY_TALENT_HIDDEN_TEMPLAR&lt;br /&gt;
                             //I recommended forcing a spec, particularly if your ALTable includes abilities from one.&lt;br /&gt;
        &lt;br /&gt;
        int nALTable = 0,    //This is the ID of an ALTable from 2DA_base.GDA or your module's m2DA_base_*.GDA  I recommended the latter, but you can edit that into GetCustomFollowerALTable below rather than passing it.&lt;br /&gt;
        &lt;br /&gt;
        int bInvokePicker = FALSE,  //Sets whether the party picker should be opened on hiring.  I think it's cleaner to call the picker outside this script, particularly if you have multiple hires at once.&lt;br /&gt;
        &lt;br /&gt;
        int nInitialState = FOLLOWER_STATE_AVAILABLE,  //This sets whether the follower joins the active party or not.  Options are:&lt;br /&gt;
                                                       //FOLLOWER_STATE_ACTIVE (put them in the active party)&lt;br /&gt;
                                                       //FOLLOWER_STATE_LOCKEDACTIVE (force them into the active party and keep them there, remember to change this later.&lt;br /&gt;
                                                       //FOLLOWER_STATE_AVAILABLE (make them available on the party picker (if you've set it up for them), but not in the active party)&lt;br /&gt;
                                                       //Plus some others you're unlikely to need at this time.  Defaults to AVAILABLE because having 4+ active followers is screwy.&lt;br /&gt;
                                                       &lt;br /&gt;
        string sCurrPlot = &amp;quot;&amp;quot;,  //If you set FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE, the script will check to see if you passed this.&lt;br /&gt;
                                //It is recommended that you have a plot flag set for a given follower being in the active party, this makes conversation interjection etc. much easier.&lt;br /&gt;
&lt;br /&gt;
        int nCurrPlotFlag = 0,  //This flag will be set if FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE are true&lt;br /&gt;
                                //AND sCurrPlot has a value AND nCurrPlotFlag is &amp;gt; 0.  &lt;br /&gt;
                                //ie if you added someone to the active party and have a plot flag to cope with it.&lt;br /&gt;
&lt;br /&gt;
        int nAutolevel = 0,     //Sets the Autolevel flag on the character sheet.  0 is off, 1 is on, 2 forces it on and removes it so the player can't turn it off.&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        bFreeSpecPoint = TRUE,  //This grants a specialisation point to the follower if they do not have a specialisation.  &lt;br /&gt;
                                //It's important to set this false for classes that do not have specs, such as CLASS_DOG.&lt;br /&gt;
                                &lt;br /&gt;
        int nTargetLevel = 0,   //If you want a specific level, set this.  Generally not worthwhile unless you set it higher than the player, since they'll just get XP from the party picker anyway.&lt;br /&gt;
        &lt;br /&gt;
        int nMinLevel = 0       //Set this if there's a specific level you don't want the follower to go below.  Probably only useful if the PC might be very low level but not necessarily so. &lt;br /&gt;
        &lt;br /&gt;
        )&lt;br /&gt;
*/       &lt;br /&gt;
/* GetCustomFollowerALTable()  &lt;br /&gt;
This function is where you put your custom table assignments.&lt;br /&gt;
&lt;br /&gt;
You should explicitly test for the tag of your follower (not mine!) and assign a value to nTable from your m2DA extension to M2DA_base &lt;br /&gt;
&lt;br /&gt;
See wiki for details on how to do this, or ignore it to get the default Warrior/Rogue/Wizard AL tables.&lt;br /&gt;
&lt;br /&gt;
NOTE: you MUST explicitly set a table for non-Warrior/Rogue/Wizards, eg dogs.  Use TABLE_AL_DOG for a default Mabari.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// This just cleans up the main function a little&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerTargetLevel(object oFollower, object oHero, int nPackage, int nMinLevel = 0) {&lt;br /&gt;
            int nPlayerLevel = GetLevel(oHero);&lt;br /&gt;
            int nTargetLevel = 0;&lt;br /&gt;
&lt;br /&gt;
            if((nPlayerLevel &amp;gt;= 13) || (nPlayerLevel == 1) || (!_UT_GetIsPlotFollower(oFollower))) {&lt;br /&gt;
               nTargetLevel = nPlayerLevel;&lt;br /&gt;
            } else {&lt;br /&gt;
               nTargetLevel = nPlayerLevel + 1;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (nMinLevel == 0) {  //If nMinLevel is not specified, checks package 2DA for a value&lt;br /&gt;
              nMinLevel = GetM2DAInt(TABLE_PACKAGES, &amp;quot;MinLevel&amp;quot;, nPackage);&lt;br /&gt;
             }&lt;br /&gt;
            if(nMinLevel &amp;gt; 0 &amp;amp;&amp;amp; nMinLevel &amp;gt; nTargetLevel) {&lt;br /&gt;
               nTargetLevel = nMinLevel;&lt;br /&gt;
            }          &lt;br /&gt;
            &lt;br /&gt;
            return nTargetLevel;&lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// Moving this black box out :)  I don't really understand it, but it should function if you have tactics set up in a package.&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerTactics(object oFollower, int nPackage) {&lt;br /&gt;
         int nTableID = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerTacticsTable&amp;quot;, nPackage);&lt;br /&gt;
         if (nTableID != -1)&lt;br /&gt;
            {&lt;br /&gt;
             int nRows = GetM2DARows(nTableID);&lt;br /&gt;
             int nMaxTactics = GetNumTactics(oFollower);&lt;br /&gt;
&lt;br /&gt;
             int nTacticsEntry = 1;&lt;br /&gt;
             int i;&lt;br /&gt;
             for (i = 1; i &amp;lt;= nRows &amp;amp;&amp;amp; nTacticsEntry &amp;lt;= nMaxTactics; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                        int bAddEntry = FALSE;&lt;br /&gt;
                        int nTargetType = GetM2DAInt(nTableID, &amp;quot;TargetType&amp;quot;, i);&lt;br /&gt;
                        int nCondition = GetM2DAInt(nTableID, &amp;quot;Condition&amp;quot;, i);&lt;br /&gt;
                        int nCommandType = GetM2DAInt(nTableID, &amp;quot;Command&amp;quot;, i);&lt;br /&gt;
                        int nCommandParam = GetM2DAInt(nTableID, &amp;quot;SubCommand&amp;quot;, i);&lt;br /&gt;
&lt;br /&gt;
                        int nUseType = GetM2DAInt(TABLE_COMMAND_TYPES, &amp;quot;UseType&amp;quot;, nCommandType);&lt;br /&gt;
                        if (nUseType == 0)&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = TRUE;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = HasAbility(oFollower, nCommandParam);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (bAddEntry)&lt;br /&gt;
                        {&lt;br /&gt;
                            SetTacticEntry(oFollower, nTacticsEntry, TRUE, nTargetType, nCondition, nCommandType, nCommandParam);&lt;br /&gt;
                            ++nTacticsEntry;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
/* InitCustomFollowerSpec:&lt;br /&gt;
&lt;br /&gt;
This function tries to set the forced Specialisation.  If there is none, it checks the package for one.  &lt;br /&gt;
&lt;br /&gt;
If there isn't either of those, it grants a free spec point if bFreeSpecPoint is true.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerSpec(object oFollower, int nPackage, int nForceSpec, int bFreeSpecPoint) {&lt;br /&gt;
    // Find specialization, and optionally add a spec point if none is found.&lt;br /&gt;
&lt;br /&gt;
        if (nForceSpec == 0) {&lt;br /&gt;
    &lt;br /&gt;
        int nSpecAbility = GetM2DAInt(TABLE_PACKAGES, &amp;quot;switch1_class&amp;quot;, nPackage); // followers can have only 1 advanced class&lt;br /&gt;
         if(nSpecAbility &amp;gt; 0)&lt;br /&gt;
         {&lt;br /&gt;
          AddAbility(oFollower, nSpecAbility);&lt;br /&gt;
         } else {&lt;br /&gt;
             if (bFreeSpecPoint) {&lt;br /&gt;
                 SetCreatureProperty(oFollower, 38, 1.00);&lt;br /&gt;
             }&lt;br /&gt;
         }                    &lt;br /&gt;
        &lt;br /&gt;
        } else {&lt;br /&gt;
         &lt;br /&gt;
             AddAbility(oFollower, nForceSpec);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* hireCustomFollower()  (See doco at top of page)&lt;br /&gt;
&lt;br /&gt;
I strongly suggest you reorder the parameters if you're adding many followers with advanced options.&lt;br /&gt;
&lt;br /&gt;
Feel free to leave them alone if you only want to set class, plot, spec or don't mind long declarations.&lt;br /&gt;
&lt;br /&gt;
Note nForceClass is currently compulsory due to flakiness with GetCreatureCoreClass()&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower(object oFollower, int nForceClass, string sPlot = &amp;quot;&amp;quot;, int nPlotFlag = 0, int nForceSpec = 0, &lt;br /&gt;
int nALTable = 0, int bInvokePicker = FALSE, int nInitialState = FOLLOWER_STATE_AVAILABLE, string sCurrPlot = &amp;quot;&amp;quot;, &lt;br /&gt;
int nCurrPlotFlag = 0, int nAutolevel = 0, int bFreeSpecPoint = TRUE, int nTargetLevel = 0, int nMinLevel = 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        object oHero = GetHero();&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN BASIC FOLLOWER JOIN BLOCK   ###################&lt;br /&gt;
&lt;br /&gt;
        This loosely replicates WR_SetFollowerState.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */    &lt;br /&gt;
        &lt;br /&gt;
        if (nForceClass == 0) {&lt;br /&gt;
            nForceClass = GetCreatureCoreClass(oFollower);           //This is not working.  Hence nForceClass mandatory.&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        SetGroupId(oFollower, GetGroupId(oHero));      //Puts the follower in the pc's Group.&lt;br /&gt;
        SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);  //This makes them act like a player.&lt;br /&gt;
        SetFollowerState(oFollower, nInitialState);  //This sets whether they are available, in the active party etc.&lt;br /&gt;
&lt;br /&gt;
        /* #################  END BASIC FOLLOWER JOIN BLOCK ##################### */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION #################&lt;br /&gt;
         This replicates the EVENT_TYPE_PARTY_MEMBER_HIRED handler from player_core, stripped down for simplicity and allowing our custom options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        Chargen_EnableTacticsPresets(oFollower);    //I assume this is important.&lt;br /&gt;
        &lt;br /&gt;
        SetLocalInt(oFollower, FOLLOWER_SCALED, 1);  //This should prevent the follower being rescaled by player_core or what have you&lt;br /&gt;
        &lt;br /&gt;
        int nPackage = GetPackage(oFollower);  //Gets the package, which will be used to find a number of 2DA IDs.&lt;br /&gt;
        int nPackageClass = GetM2DAInt(TABLE_PACKAGES, &amp;quot;StartingClass&amp;quot;, nPackage);  //I don't think this is used, even by player_core&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // set behavior according to package&lt;br /&gt;
        int nBehavior = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerBehavior&amp;quot;, nPackage);&lt;br /&gt;
&lt;br /&gt;
        if(nBehavior &amp;gt;= 0) {&lt;br /&gt;
            SetAIBehavior(oFollower, nBehavior);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        Chargen_InitializeCharacter(oFollower);      //We initialise the follower and choose race/class.&lt;br /&gt;
        &lt;br /&gt;
        Chargen_SelectRace(oFollower,GetCreatureRacialType(oFollower));&lt;br /&gt;
        Chargen_SelectCoreClass(oFollower,nForceClass);        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         if (nTargetLevel == 0) {   //This block picks a target level if not specified&lt;br /&gt;
            &lt;br /&gt;
              nTargetLevel = GetCustomFollowerTargetLevel(oFollower, oHero, nPackage, nMinLevel);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));      //Here is where the XP is calculated and rewarded&lt;br /&gt;
         RewardXP(oFollower, nXp, FALSE, FALSE);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // add hidden approval talents - (JN: I don't know how to set these yet, but when I figure it out this should make it work)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         int nIndex = Approval_GetFollowerIndex(oFollower);&lt;br /&gt;
         Approval_AddFollowerBonusAbility(nIndex, 0);&lt;br /&gt;
        &lt;br /&gt;
          //Handle Specialisation&lt;br /&gt;
          InitCustomFollowerSpec(oFollower, nPackage, nForceSpec, bFreeSpecPoint);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // This spends all available attribute and stat points on the&lt;br /&gt;
         // creature according to the levelup table.  (JN:  this replicates AL_DoAutoLevelUp but with our choice of table)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
         if (nALTable == 0) {&lt;br /&gt;
            nALTable = GetCustomFollowerALTable(oFollower);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         AL_SpendAttributePoints(oFollower, nALTable, FALSE);&lt;br /&gt;
         AL_SpendSkillPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
         AL_SpendSpecializationPoints(oFollower, nALTable);&lt;br /&gt;
         AL_SpendTalentSpellPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        // Update various UIs&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        Chargen_SetNumTactics(oFollower);&lt;br /&gt;
        SetCanLevelUp(oFollower,Chargen_HasPointsToSpend(oFollower));&lt;br /&gt;
&lt;br /&gt;
        // load tactics&lt;br /&gt;
         InitCustomFollowerTactics(oFollower, nPackage);&lt;br /&gt;
&lt;br /&gt;
         /* #################  END PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION ################# */     &lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
         SetAutoLevelUp(oFollower, nAutolevel);         //This is the autolevel flag on the character sheet.&lt;br /&gt;
         &lt;br /&gt;
         //Set plot flags&lt;br /&gt;
         &lt;br /&gt;
         if (!((sPlot == &amp;quot;&amp;quot;) || (nPlotFlag == 0))) {           //Joined Party&lt;br /&gt;
            WR_SetPlotFlag(sPlot, nPlotFlag, TRUE);   &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         if ((nInitialState == FOLLOWER_STATE_ACTIVE) || (nInitialState == FOLLOWER_STATE_LOCKEDACTIVE)) {&lt;br /&gt;
            if (!((sCurrPlot == &amp;quot;&amp;quot;) || (nCurrPlotFlag == 0))) {&lt;br /&gt;
                WR_SetPlotFlag(sCurrPlot, nCurrPlotFlag, TRUE);   //Currently in Party&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
                     &lt;br /&gt;
        // Invoke picker if requested.&lt;br /&gt;
&lt;br /&gt;
        if (bInvokePicker) {&lt;br /&gt;
             SetPartyPickerGUIStatus(2);&lt;br /&gt;
             ShowPartyPickerGUI();&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yeah, I know.  It can't really be any smaller.  Feel free to modify it if you're confident with scripting.&lt;br /&gt;
==== Add Your Custom Autolevel Template to GetCustomFollowerALTable() ====&lt;br /&gt;
While you can pass the ID you made for your autolevel template to that monster function as an argument, it's better to have them all in one place if you have multiple followers.&lt;br /&gt;
&lt;br /&gt;
GetCustomFollowerALTable() is the first function in our include, and you can add an explicit if test for your follower there to assign the correct table id (the one from your M2DA_base_ m2DA).  There is a function very much like it in sys_autolevel_h.nss for the core followers, so we'll copy Bioware's practice.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the function by itself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we have a test for each follower tag from my module, matching up to an ID which is assigned to nTable.  All you need to do is change a tag from my follower to yours, and my ID to the correct one from your M2DA_base_* m2DA.  Then you should delete the rest of the example if statements :)&lt;br /&gt;
&lt;br /&gt;
Save and export the script.  Ignore the compiler error about lack of main();&lt;br /&gt;
&lt;br /&gt;
=== Include Function In Your Hire Script and Call It ===&lt;br /&gt;
&lt;br /&gt;
So instead of a hire script that calls UT_HireFollower(), we want one that includes our shiny new function and calls it.&lt;br /&gt;
&lt;br /&gt;
Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //Make sure you include your party handling plot&lt;br /&gt;
#include &amp;quot;hireCustomFollower_h&amp;quot;  // And include the function script - which will in turn include a bunch of stuff&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
                    //Initialising my objects, not super-relevant to the example &lt;br /&gt;
                     &lt;br /&gt;
                    object oHero = GetHero();&lt;br /&gt;
                    object oMiera = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_miera.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oJysavin = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_jysavin.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oBraghon = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_braghon.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oSpider = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_geldual.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
&lt;br /&gt;
                    //Simplest hire call - adds to the party as a wizard.  Class is currently compulsory due to a bug.&lt;br /&gt;
                    hireCustomFollower(oMiera, CLASS_WIZARD);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party and set joining plot flags&lt;br /&gt;
                    hireCustomFollower(oJysavin, CLASS_WARRIOR, PLT_BC_CREATE_PARTY, PARTY_JYSAVIN_JOINED);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party, set plot flags, force a specialisation&lt;br /&gt;
                    hireCustomFollower(oBraghon, CLASS_ROGUE, PLT_BC_CREATE_PARTY, PARTY_BRAGHON_JOINED, ABILITY_TALENT_HIDDEN_ASSASSIN);&lt;br /&gt;
&lt;br /&gt;
                    //More complex example - Follower added as a unique class (Dog), not granted a specialisation or spec point.  &lt;br /&gt;
                    //Note unique classes must have an ALTable passed here or specified in GetCustomFollowerALTable() or they won't work&lt;br /&gt;
                    hireCustomFollower(oSpider, CLASS_DOG, PLT_BC_CREATE_PARTY, PARTY_GELDUAL_JOINED, 0, 0, FALSE, FOLLOWER_STATE_AVAILABLE, &amp;quot;&amp;quot;, 0, 0, FALSE);&lt;br /&gt;
                   &lt;br /&gt;
                    //Show the party picker to let the player choose from their new companions!&lt;br /&gt;
                    SetPartyPickerGUIStatus(2);&lt;br /&gt;
                    ShowPartyPickerGUI();                                                                                                                    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example shows several of the more simple ways of invoking the function.  Check the comments at the start of the function for a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
I would suggest best practice for most followers would be to call as follows:&lt;br /&gt;
&lt;br /&gt;
'''hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION)'''&lt;br /&gt;
&lt;br /&gt;
This will safely set the follower up as the desired class and specialisation (doubly important if there are spec abilities in their ALTable) while setting your plot flag for them being in the party.  hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION, 0, TRUE) will do the same while invoking the Party Picker automatically.&lt;br /&gt;
&lt;br /&gt;
Note that the specialisations are abilities and not classes - you'll find them as ABILITY_HIDDEN_ constants.&lt;br /&gt;
&lt;br /&gt;
If it's all worked, you should find you can now add followers with a lot more flexibility!&lt;br /&gt;
&lt;br /&gt;
[[File:picker_advanced.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Common Follower Problems &amp;amp; FAQ ==&lt;br /&gt;
&lt;br /&gt;
====Why don't my followers gain XP?====&lt;br /&gt;
There is a bug in UT_HireFollower. For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
(Note: Be aware if you use the name UT_HireFollower_Fixed you may end up finding your include file conflicting with someone else who has named it the same in their include.)&lt;br /&gt;
&lt;br /&gt;
Alternately you need to clear a flag in a separate script to the one in which they're hired.&lt;br /&gt;
&lt;br /&gt;
You must use the '''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);''' statement in a script you can be sure will run soon after your hiring script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====When I choose followers from the Party Picker, they spawn into the area but do not join.====&lt;br /&gt;
&lt;br /&gt;
You need to intercept the EVENT_TYPE_PARTYMEMBER_ADDED event and set the follower to FOLLOWER_STATE_ACTIVE.  See Simple Follower Creation earlier in this document.&lt;br /&gt;
&lt;br /&gt;
====My followers don't have skill trees!====&lt;br /&gt;
&lt;br /&gt;
If a follower hasn't been through an initial chargen/autolevel event (via player_core/sys_autolevel_h) then the skill tree doesn't show.  You're probably trying to be clever and get around UT_HireFollower without going all the way (see monster function above ^_^).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have a class====&lt;br /&gt;
&lt;br /&gt;
GetCreatureCoreClass() seems flaky under some conditions.  It's best to explicitly set the class yourself; this is why class is currently a mandatory argument to hireCustomFollower()&lt;br /&gt;
&lt;br /&gt;
====Dog talents don't work====&lt;br /&gt;
Symptoms: dog talents appear on the talents screen but remain greyed out on level up. Warrior talents appear in the quickslots.&lt;br /&gt;
&lt;br /&gt;
Line 78 of packages_base in packages.xls (Dog) should have the LevelUpTable column set to 257 which is the ALDog table.&lt;br /&gt;
&lt;br /&gt;
====Isn't there an easier way to do this?====&lt;br /&gt;
&lt;br /&gt;
Possibly.  There is a way of recruiting a follower by setting a plot flag.  However I don't understand it, and I expect it still doesn't allow custom autolevel templates, full control over specialisations etc.  There's still a fair bit of stuff hardcoded for the core followers, I'm not sure putting a custom follower through the same process as Al, Leli et al will have good results.&lt;br /&gt;
&lt;br /&gt;
The next section answers this question, up to a point.&lt;br /&gt;
&lt;br /&gt;
==== What if there are more than three potential followers? ====&lt;br /&gt;
This example handles larger numbers of followers, and doesn't force the player to use the party picker unless the party is already full.&lt;br /&gt;
&lt;br /&gt;
The prefix zzz, used throughout, can be replaced with whatever [[Prefixes_in_use | prefix]] you are using for your resources.&lt;br /&gt;
&lt;br /&gt;
If you're making a new campaign, to keep life simple, allocate a unique number to each follower. You could either use a creature variable or a script, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Party member id (e.g. 1=Alicia, 2=Godwin...)&lt;br /&gt;
int zzzPartyMemberID(object oPartyMember)&lt;br /&gt;
{&lt;br /&gt;
  string sPartyMember = GetTag(oPartyMember);&lt;br /&gt;
&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_alicia&amp;quot;) return 1;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_godwin&amp;quot;) return 2;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_harold&amp;quot;) return 3;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_lara&amp;quot;  ) return 4;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make two separate plots, e.g. zzzpt_hired for when a follower is first recruited, and zzzpt_party to flag whether they're currently in the party. Use flag values that correspond to the unique follower id, e.g. ZZZPT_HIRED_GODWIN will be 2.&lt;br /&gt;
&lt;br /&gt;
If you're modifying the official campaign, you won't be able to make this simplification - you'll need a set of plot flags for your new party members, similar to the official ones. The logic of what follows is still correct, it just means that instead of having one set of common code that works for everyone, you have to explicitly script each party member individually using their personal plot flags.&lt;br /&gt;
&lt;br /&gt;
Follower conversation is now very simple. In Godwin's dialogue, the hiring line will be conditional - when ZZZPT_HIRED_GODWIN is clear - and it will set ZZZPT_HIRED_GODWIN.  No conversation script is necessary. Instead, in the properties of the plot zzzpt_hired, we add a plot event script, as follows.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// PARTY HIRE PLOT SCRIPT&lt;br /&gt;
//&lt;br /&gt;
// This is called in conversation when a party member is hired for the first time.&lt;br /&gt;
// If the party is full, the party picker is displayed, which forces the PARTYMEMBER_ADDED&lt;br /&gt;
// module event.&lt;br /&gt;
//&lt;br /&gt;
// The flag value is never referenced, because the code is common for all party members.&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;log_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plot_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;zzz_h&amp;quot;                  // A header containing the zzzPartyMemberID function&lt;br /&gt;
#include &amp;quot;plt_zzzpt_hired&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_zzzpt_party&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int StartingConditional()&lt;br /&gt;
{&lt;br /&gt;
    event  eParms             = GetCurrentEvent();&lt;br /&gt;
    int    nType              = GetEventType(eParms);       // GET or SET&lt;br /&gt;
    string strPlot            = GetEventString(eParms, 0);  // Plot GUID&lt;br /&gt;
    int    nFlag              = GetEventInteger(eParms, 1); // Plot flag&lt;br /&gt;
    object oParty             = GetEventCreator(eParms);    // Plot table owner&lt;br /&gt;
    object oFollower          = GetEventObject(eParms, 0);  // Conversation owner (if any)&lt;br /&gt;
    int    nPlotType          = GetEventInteger(eParms, 5); // Plot type&lt;br /&gt;
&lt;br /&gt;
    int    bIsTutorial        = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsTutorial&amp;quot;, nPlotType);&lt;br /&gt;
    int    bIsCodex           = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsCodex&amp;quot;, nPlotType);&lt;br /&gt;
&lt;br /&gt;
    int    nResult            = FALSE;                      // return value for DEFINED GET&lt;br /&gt;
    object oPC                = GetPartyLeader();&lt;br /&gt;
&lt;br /&gt;
    plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info&lt;br /&gt;
&lt;br /&gt;
    if (nType == EVENT_TYPE_SET_PLOT) // actions -&amp;gt; normal flags only&lt;br /&gt;
    {&lt;br /&gt;
        int nValue    = GetEventInteger(eParms, 2); // 0=Clear 1=Set&lt;br /&gt;
        int nOldValue = GetEventInteger(eParms, 3); // Current flag value&lt;br /&gt;
&lt;br /&gt;
        if (nValue)&lt;br /&gt;
          {&lt;br /&gt;
            if (GetArraySize(GetPartyList(oPC)) &amp;lt; 4)&lt;br /&gt;
              {&lt;br /&gt;
                UT_HireFollower(oFollower);&lt;br /&gt;
                SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
                AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
                SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
                WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
              }&lt;br /&gt;
            else&lt;br /&gt;
              {&lt;br /&gt;
                WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
                SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);&lt;br /&gt;
                SendPartyMemberHiredEvent(oFollower, TRUE);&lt;br /&gt;
//                SetPartyPickerGUIStatus(PP_GUI_STATUS_USE);&lt;br /&gt;
//                ShowPartyPickerGUI();&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
     else // EVENT_TYPE_GET_PLOT -&amp;gt; defined conditions only&lt;br /&gt;
     {&lt;br /&gt;
        switch(nFlag)&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    plot_OutputDefinedFlag(eParms, nResult);&lt;br /&gt;
    return nResult;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We still need to handle the party picker events in our module event script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         // PARTY MEMBER ADDED - Allow XP gain. Come here, follow me, flag as party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
         {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
            break;&lt;br /&gt;
         }&lt;br /&gt;
         // PARTY MEMBER DROPPED - flag as not party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_DROPPED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), FALSE);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
When we need to refer to a particular follower explicitly, we can still do so - for example, the flag ZZZPT_PARTY_GODWIN will tell use whether Godwin is currently in the party or not.&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation: An Alternative Approach ==&lt;br /&gt;
&lt;br /&gt;
While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfectly good wheel at hand. The following describes how to adapt the existing machinery for the recruitment and tracking of your own party members.&lt;br /&gt;
&lt;br /&gt;
First create the setup as described above in Simple Follower Creation, except for the scripts and plot tables. In addition, create the GDA extensions for a level-up table and the M2DA which points to those tables, as described in Advanced Follower Creation above.&lt;br /&gt;
&lt;br /&gt;
Now ...&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Create a party plot table ===&lt;br /&gt;
&lt;br /&gt;
Have a look at the gen00pt_party plot table and create a similar table for your own followers. Don't bother with the Defined Flags for the moment, just the Main Flags will do, ie recruited, in-camp and in-party for each follower. (Critical Note: Do not duplicate the plot table, create one from scratch. This is the case for ALL plot tables because of a show-stopping bug which means a new GUID is not assigned on Duplicate of a plot.)&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create a party script ===&lt;br /&gt;
&lt;br /&gt;
Duplicate the gen00pt_party script and rename for your module (conventionally plot tables and their plot scripts have the same name). Delete (or comment out) the Defined Flags section at the end and any lines dealing with logging and tutorials. Change names to those of your party members. If you are using gifting, approval or forced inclusion you may wish to retain those sections of code, but additional machinery will be needed for these facilities to work. For approval you can specify a starting level of approval here for each follower if you want it to be other than zero (as per the existing section dealing with Dog). Note that the custom hire function at the head of the script allows you to specify whether or not to invoke the party picker on recruitment. You may not want to do so for the first couple of followers (but see below). You should already have defined all required constants in a separate file for your module, eg &amp;lt;module prefix&amp;gt;_constants_h. If not, do so now and include it, as well as your plot table, at the head of the script. Delete includes that only refer to the main campaign. (If this is all Greek to you, spend a couple of hours examining the set-up of the Demo, which is packaged with the toolset, and go through the introductory tutorials referenced on the main page of this wiki).&lt;br /&gt;
&lt;br /&gt;
Looking at the new party script, notice that the follower-in-camp function is not defined. This is because for some arcane reason it is defined in party_h, and unhappily references the main campaign's plot table. So we will have to create a new function to replace it, change the other function's flag reference (for the sake of neatness), and change the call in the main body of the script. (You may decide later for other reasons to replicate and customise party_h, but that won't interfere with re-creating this function here.)&lt;br /&gt;
&lt;br /&gt;
Our two functions at the head of the script should be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;void SetFollowerInParty(object oFollower, string sPlot, int nCampFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nCampFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, TRUE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE);&lt;br /&gt;
    command cJump = CommandJumpToObject(GetPartyLeader());&lt;br /&gt;
    WR_AddCommand(oFollower, cJump);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SetFollowerInCamp(object oFollower, string sPlot, int nPartyFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nPartyFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, FALSE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
}&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the line in the in-camp sections for each follower should now be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;SetFollowerInCamp(o&amp;lt;follower&amp;gt;, strPlot, &amp;lt;follower&amp;gt;_IN_PARTY);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Step 3: Create package GDAs and reference them in you 2DA_base extension ===&lt;br /&gt;
&lt;br /&gt;
Look at the packages_base GDA and create an extension GDA with one line for each follower based on a main campaign follower that is most like your own follower, eg a sword-shield warrior can be a copy of Alistair, a battle mage a copy of Morrigan, etc. You can look at the Excel version of this GDA to more easily see what the fields mean. It is here that you can specify what if any specialisation will be assigned on hire and the level at which this spec point becomes available. (The IDs for each spec are in the 4000-range of ABI_base.)&lt;br /&gt;
&lt;br /&gt;
Most importantly, it is here also that you define the ID of both your level-up table and the AIP table you are about to create.&lt;br /&gt;
&lt;br /&gt;
Now create aip_follower_&amp;lt;follower name&amp;gt; gda tables, again based on a existing tables most like your own followers. No changes should be required to the copies you create.&lt;br /&gt;
&lt;br /&gt;
In the m2da_base_&amp;lt;your module&amp;gt; extension you have already created, add lines for your AIP tables with a package ID referencing the IDs you assigned in your packages extension table.&lt;br /&gt;
&lt;br /&gt;
Carefully check that all IDs in your GDAs are correct and cross-reference properly, and save the GDAs to your override directory.&lt;br /&gt;
&lt;br /&gt;
Desirable but not obligatory (except for non-humanoid characters), is an extension to the Portraits gda.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Module script addition ===&lt;br /&gt;
&lt;br /&gt;
Modify your own module script to point to the new plot table and your own followers. To see an example of the required code for the two new sections look at the relevant section of module_core, which are for EVENT_TYPE_PARTYMEMBER_ADDED and EVENT_TYPE_PARTYMEMBER_DROPPED.&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The recruit flag is set in a conversation (usually, but it could be a script) and that event is then processed by the plot script, which among other things sets both the in-camp and in-party flags, and fires up the party picker by default. If the player then selects the follower in the picker, the in-camp flag is unset (or vice versa if the follower is not selected to join). Subsequently, if the character is selected (or unselected) in the picker, the event is picked up by the module script, which sets the relevant plot flag as true, and that plot event is then sent to the plot scipt which sets the other flag as false. &lt;br /&gt;
&lt;br /&gt;
(Note that if the party picker is turned off for a particular follower's recruit event, that follower will be placed in the active party regardless of the number of members, so ONLY do this for a follower who cannot be recruited when there are already 3 possible followers.)&lt;br /&gt;
&lt;br /&gt;
On recruitment, player_core rebuilds the character according to the specifications laid out in the GDAs, so no further scripting is required.&lt;br /&gt;
&lt;br /&gt;
=== Uses ===&lt;br /&gt;
&lt;br /&gt;
To recruit a party member, set the recruit flag from your plot table in the relevant dialogue. Adding or subtracting followers from the active party is automatically tracked via this machinery, and the plot flags can be interrogated in all your scripts and conversations if you need to know who is currently in the party and who is in camp.&lt;br /&gt;
&lt;br /&gt;
Defined flags can be added as you need them to the script and plot table but there is no point having flags that you will not use, so as with all Defined Flags this is an as-you-go decision, but quite easy to do.&lt;br /&gt;
&lt;br /&gt;
Hiring and firing of temporary party members at the start of a campaign (such as Ser Jory, or Jowan, or Soris, etc) can be handled by UT_HireFollower, and the party picker is not invoked (nor is the Party Camp an available destination).&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If you haven't done so already, create a simple debugging area for your module where you can dump the player, all followers and a couple of conversation dummies, and set up a dialogue in which you can invoke all required flags and conditions and see if they actually work as expected. (This setup can be used to test many other components as well.) Global machinery such as this can be painful to set up and get right (unless you are of an exceptionally methodical cast of mind), but it is worthwhile to ensure they are absolutely bullet-proof before you develop the specifics of your module.&lt;br /&gt;
&lt;br /&gt;
=== The KISS principle ===&lt;br /&gt;
&lt;br /&gt;
This is an &amp;quot;out-of-the-box&amp;quot; solution, and once set up is quite robust. If you want variants not catered for here, do NOT try to modify what you already have working.&lt;br /&gt;
&lt;br /&gt;
'''Use-case:''' You want a follower (example tag: dairren) to be recruited without a set specialisation and one level higher than the PC.&lt;br /&gt;
&lt;br /&gt;
Go to your packages gda and set the spec field to 0. In the character's plot table (you should have at least one for each follower) create a flag which we will call BLAH_BLAH. In the table's plot scipt insert the following very simple event handler:&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;dascript&amp;gt;case BLAH_BLAH:&lt;br /&gt;
         {&lt;br /&gt;
           SetCreatureProperty(oDairren, 38, 1.00); //awards the spec point; field from the properties gda&lt;br /&gt;
           int aLevel = GetLevel(oHero); //some simple arithmetic to find out the XP we need to award&lt;br /&gt;
           int bLevel = (aLevel+1);&lt;br /&gt;
           int aPoints = RW_GetXPNeededForLevel(aLevel);&lt;br /&gt;
           int bPoints = RW_GetXPNeededForLevel(bLevel);&lt;br /&gt;
           int targetPoints = (bPoints - aPoints);&lt;br /&gt;
           RewardXP(oDairren, targetPoints, FALSE, TRUE); //award the XP, and we're done&lt;br /&gt;
           break;&lt;br /&gt;
	 }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The flag can be set in the same conversation as the recruit flag, so long as it comes afterwards. This way you not only maintain the integrity of your core machinery, but keep exceptions/variations for particular characters where they belong -- with that character's plot tables and scripts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
{{Languages}}&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15202</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15202"/>
				<updated>2010-12-11T10:59:21Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Simple Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
Follow these steps to create a follower that&lt;br /&gt;
&lt;br /&gt;
- Levels up with a default package&lt;br /&gt;
&lt;br /&gt;
- Can be chosen from the party picker&lt;br /&gt;
&lt;br /&gt;
- Can gain XP&lt;br /&gt;
&lt;br /&gt;
This guide assumes you know how to create a creature and are comfortable with basic scripting.&lt;br /&gt;
&lt;br /&gt;
You should only use this simple method if you are sure there will be empty space in the active party when your follower is recruited.&lt;br /&gt;
&lt;br /&gt;
A more comprehensive approach when there are more than three potential party members is discussed in the FAQ below. It's worth taking the time to understand the basics first, though. &lt;br /&gt;
&lt;br /&gt;
=== Create the creature ===&lt;br /&gt;
&lt;br /&gt;
Create a creature to act as your follower.  Set its name, appearance, gender, head morph, conversation, inventory etc as you want them to behave in-game.&lt;br /&gt;
&lt;br /&gt;
Set an appropriate '''Tag''' (you'll be using it a lot).  I suggest &amp;quot;party_charname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Make sure you choose a '''Class'''.  For most followers this should be Rogue, Warrior or Wizard.&lt;br /&gt;
&lt;br /&gt;
[[File:class.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under Package/Scaling set:&lt;br /&gt;
&lt;br /&gt;
'''General Package Type''' to be '''Party Members'''&lt;br /&gt;
&lt;br /&gt;
'''Package''' to be an appropriate value (probably &amp;quot;Generic - Wizard&amp;quot; or similar)&lt;br /&gt;
&lt;br /&gt;
'''Package AI''' (there should only be one choice)&lt;br /&gt;
&lt;br /&gt;
'''Rank''' to be '''Player'''&lt;br /&gt;
&lt;br /&gt;
[[File:package.jpg]]&lt;br /&gt;
&lt;br /&gt;
Save and export your character as normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overlay char_stage ===&lt;br /&gt;
&lt;br /&gt;
In the official campaign, the party picker uses a special area called char_stage. Whether you're extending the official campaign or making a standalone campaign, there is a function that allows you to overlap the offical stage with your own, so that both stages are active simultaneously in game.&lt;br /&gt;
&lt;br /&gt;
In your resource palette, right-click char_stage under the Global folder and select Duplicate to make a copy of the stage with a new resource name, e.g. my_char_stage. In the resource properties, ensure that both Module and Owner Module are set to your module, and the folder of your choice.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:area_palette.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a new waypoint for your follower to appear on the party picker.  This waypoint '''must''' have a tag in the form of &amp;quot;char_&amp;quot; followed by the exact tag of your follower.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:char_stage.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example the tag of my follower is '''bc_party_miera''' so her waypoint tag must be '''char_bc_party_miera'''&lt;br /&gt;
&lt;br /&gt;
For a standalone module (such as in this example), put your waypoint wherever you please.  The illustrated one is directly on top of Morrigan's.  For an add-in to the main campaign, you should position your wp appropriately relative to the core party members.&lt;br /&gt;
&lt;br /&gt;
Save and export the area.&lt;br /&gt;
&lt;br /&gt;
Add the following to your module event script:&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
case EVENT_TYPE_MODULE_GETCHARSTAGE:&lt;br /&gt;
{&lt;br /&gt;
   // Overlay the existing stage with my stage&lt;br /&gt;
   // &amp;quot;my_char_stage&amp;quot; is the resource name of the overlay area&lt;br /&gt;
   // &amp;quot;partypicker&amp;quot; is the name of the default GDA&lt;br /&gt;
   SetPartyPickerStage(&amp;quot;my_char_stage&amp;quot;, &amp;quot;partypicker&amp;quot;);&lt;br /&gt;
   break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create m2DAs for the Party Picker ===&lt;br /&gt;
&lt;br /&gt;
You will need to create two Excel spreadsheets.&lt;br /&gt;
&lt;br /&gt;
The first should be named (both worksheet and file) '''partypicker_''' with a unique suffix.  In this example, my first spreadsheet is named partypicker_fofbc.xls with a worksheet name of partypicker_fofbc - the suffix being the acronym of my module.&lt;br /&gt;
&lt;br /&gt;
Set up your columns as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:partypickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' for your follower must be '''12 or higher'''.  11 is the highest value used in the base 2DA.  12 is fine for standalone modules, add-ins will probably want to use an arbitrarily high number to avoid potential conflicts.&lt;br /&gt;
&lt;br /&gt;
The '''Label''' should be the follower's name as you wish it to appear on the party picker.&lt;br /&gt;
&lt;br /&gt;
The '''Tag''' must be your follower's tag.&lt;br /&gt;
&lt;br /&gt;
All other values are non-functioning defaults and should be specified as in the image above unless you know explicitly what you're doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION ANIMATIONS'''&lt;br /&gt;
 &lt;br /&gt;
Add Animation and Remove Animation are actually Id numbers of different animations, taken from anim_base.gda&lt;br /&gt;
&lt;br /&gt;
Enter and Exit version of animations are generally the best ones to use, altough one can try others. NOT ALL ANIMATIONS WILL WORK, since some require special conditions.&lt;br /&gt;
Here are some examples you can use:&lt;br /&gt;
&lt;br /&gt;
819 - talk cursing&lt;br /&gt;
&lt;br /&gt;
629 - reading a book (doesn't work, since it probably requires a book object)&lt;br /&gt;
&lt;br /&gt;
844 - hands behind back (848 and 849 are Enter and Exit versions respectfully)&lt;br /&gt;
&lt;br /&gt;
850 - chest pounding salute&lt;br /&gt;
&lt;br /&gt;
811 - fist pounding&lt;br /&gt;
&lt;br /&gt;
277 - dance&lt;br /&gt;
&lt;br /&gt;
247 - cast area spell&lt;br /&gt;
&lt;br /&gt;
500 - vfx cast&lt;br /&gt;
&lt;br /&gt;
600 - surprised&lt;br /&gt;
&lt;br /&gt;
603 - praying&lt;br /&gt;
&lt;br /&gt;
607 - head bow&lt;br /&gt;
&lt;br /&gt;
609 - standing at attention&lt;br /&gt;
&lt;br /&gt;
651,652 - crouch pray (Enter and exit)&lt;br /&gt;
&lt;br /&gt;
808 - point forward&lt;br /&gt;
&lt;br /&gt;
825 - nodding&lt;br /&gt;
&lt;br /&gt;
840 - hand chop or frustration&lt;br /&gt;
&lt;br /&gt;
905,906 - crouch (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
919,920 - sit on ground (enter, exit)&lt;br /&gt;
&lt;br /&gt;
965 - kneel down loop&lt;br /&gt;
&lt;br /&gt;
972 - wipe nose&lt;br /&gt;
&lt;br /&gt;
976,977 - squat (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
986 - wipe eyes&lt;br /&gt;
&lt;br /&gt;
998,999 - hands clasped (Enter, exit)&lt;br /&gt;
&lt;br /&gt;
3029 - inspect nails&lt;br /&gt;
&lt;br /&gt;
3031,3032 - playful (enter, exit)&lt;br /&gt;
&lt;br /&gt;
3054,3056 - slouch (enter, exit)&lt;br /&gt;
255 - in-place fly&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION VFX''' &lt;br /&gt;
&lt;br /&gt;
The VFX column is the ID of the vFX effect taken from vFx_base.gda. This one is a bit more tricky, since it also references the BlendTree value from the same file.&lt;br /&gt;
Find the ID of the spell effect and look for the BlendTreeName column (should the the 12th columun) and enter BOTH into the respective columns for your character in the partypicker file.&lt;br /&gt;
&lt;br /&gt;
Some examples:&lt;br /&gt;
&lt;br /&gt;
ID      ---      BLENDTREENAME      ---   EFFECT&lt;br /&gt;
&lt;br /&gt;
6039    ---     fxm_energy_up_p    ---    Lady of the Forest pillar of light&lt;br /&gt;
&lt;br /&gt;
6040    ---     fxm_power_in_p      ---   Branka - power in&lt;br /&gt;
&lt;br /&gt;
3054    ---     fxc_lotf_c          ---   Lady of the Forest - swirling leaves&lt;br /&gt;
&lt;br /&gt;
3009    ---     fxc_succubus_c     ---    Succubus crust&lt;br /&gt;
&lt;br /&gt;
1549    ---     fxa_hly_imp_c       ---   Holy Impact crust&lt;br /&gt;
&lt;br /&gt;
1076    ---     fxa_spi_aur_mht_c   ---   Spirit - Aura Might crust&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second spreadsheet should be named '''party_picker_''' (note middle underscore).  Once again append your unique suffix (in this example party_picker_fofbc.xls with party_picker_fofbc as its worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up your columns and data like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:party_pickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''ID''' and '''Tag''' should match what you did in the first spreadsheet.  Specify INVALID COLUMN for the third column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're familiar with m2DAs, generate them from these files, copy them to your module's override directory, and skip to the next step.  Otherwise, read on:&lt;br /&gt;
&lt;br /&gt;
- Go to '''\Program Files\Dragon Age\tools\ResourceBuild\Processors''' (or wherever you installed Dragon Age)&lt;br /&gt;
&lt;br /&gt;
- Copy '''ExcelProcessor.exe''' from that folder to whichever folder has the excel sheets you just created.&lt;br /&gt;
&lt;br /&gt;
- Drag and drop your xls files onto ExcelProcessor.  This will create .gda files.&lt;br /&gt;
&lt;br /&gt;
- Copy these .gda files to your module's export directory (probably \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetexport).  Make sure they are included in your .dazip when the time comes to build your module.&lt;br /&gt;
&lt;br /&gt;
If you are an OpenOffice user and have trouble with ExcelProcessor, you can use [http://social.bioware.com/project/755/ GDApp] to directly create the 2DAs.  It rocks!&lt;br /&gt;
&lt;br /&gt;
=== Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event ===&lt;br /&gt;
&lt;br /&gt;
Amusingly enough, the Party Picker does not actually add followers to the party.  However it raises an event that allows you to do so.  Your module script needs to capture this event and execute some code.&lt;br /&gt;
&lt;br /&gt;
The following example shows what to do with the event.  The full script would work as a module script for an add-in (assuming it didn't need to do anything else), but otherwise you'll have to incorporate the event into your own module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);  //Allows the follower to gain XP&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);  //Adds follower to the active party&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE)''' is the key statement to add the follower to the active party.  You must have this.&lt;br /&gt;
&lt;br /&gt;
'''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0)''' is a bug-fix, as followers hired with UT_HireFollower() do not receive XP by default.  This statement fixes that, and I consider it best practice to keep it in this event to ensure it is always set.  You will not wish to do this if you want a follower that should not gain XP to be on the party picker.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you do not need to intercept the corresponding event for a party member being removed - the party picker handles spawning/despawning, and thus will successfully remove members.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&lt;br /&gt;
&lt;br /&gt;
=== Create Your Hiring Script ===&lt;br /&gt;
&lt;br /&gt;
Now all that remains is to actually hire the follower :)&lt;br /&gt;
&lt;br /&gt;
Create a script to handle the hiring (which will most likely be fired from a conversation).  The script is quite simple:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
        object oFollower = GetObjectByTag(&amp;quot;bc_party_miera&amp;quot;); //Use CreateObject() if the creature isn't present in the module yet&lt;br /&gt;
&lt;br /&gt;
        UT_HireFollower(oFollower);   //Hires the follower&lt;br /&gt;
&lt;br /&gt;
        SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
        ShowPartyPickerGUI();  //Shows the Party Picker; necessary for the follower to gain XP&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use your own follower's tag and not the example one :)&lt;br /&gt;
&lt;br /&gt;
This script fires the party picker after hiring the follower.  That is absolutely necessary via this method, as we have put the XP fix onto an event fired by the party picker.  You cannot put the XP fix into this script, it must be called from a later one (the bug is caused by an errant call to an event in player_core, which will be executed AFTER this script).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If everything worked, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_success.jpg|thumb|200px|center]]&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow these steps to have full control over the creation of your follower, with options such as:&lt;br /&gt;
&lt;br /&gt;
- Unique level-up template&lt;br /&gt;
&lt;br /&gt;
- Class and specialisation chosen via script&lt;br /&gt;
&lt;br /&gt;
- Any starting state&lt;br /&gt;
&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&lt;br /&gt;
&lt;br /&gt;
- Set plot flags in the call to the hire script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prepare Creature, char_stage and Party Picker m2DAs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the same steps to create your follower creature, char_stage and Party Picker m2DAs as above.&lt;br /&gt;
&lt;br /&gt;
=== Create Party Plot ===&lt;br /&gt;
&lt;br /&gt;
While not necessary, it's very helpful to have plot flags set when a follower is hired or joins/leaves the active party.  This makes conversation interjections and the like very easy.&lt;br /&gt;
&lt;br /&gt;
Create a plot with appropriate flags.  There's no real need to associate journal text with them:&lt;br /&gt;
&lt;br /&gt;
[[File:follower_plot.jpg]]&lt;br /&gt;
&lt;br /&gt;
See FAQ for an alternative approach to plots when there are more than three potential party members.&lt;br /&gt;
&lt;br /&gt;
=== Add Plot Flags to Party Picker Event Intercept ===&lt;br /&gt;
&lt;br /&gt;
We then update our module script to make use of that plot, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //make sure you include your own plot, not mine&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            &lt;br /&gt;
            if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               //You must explicitly test for your follower's tag.&lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, TRUE);     //Make sure you use your own flags!&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            break;&lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_DROPPED:                    &lt;br /&gt;
        {&lt;br /&gt;
              object oFollower = GetEventObject(ev, 0); &lt;br /&gt;
              &lt;br /&gt;
              if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) { &lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, FALSE);     //As above, but set false.&lt;br /&gt;
              }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create a Level Up Template ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can skip this step if you're content to use one of the generic Rogue, Wizard or Warrior templates, but I don't recommend it.  Making a template that suits your character is easy and will almost always be better for the player than a generic one that spends points poorly.&lt;br /&gt;
&lt;br /&gt;
Go to \Program Files\Dragon Age\tools\Source\2DA (or wherever you installed Dragon Age).&lt;br /&gt;
&lt;br /&gt;
You should see a number of excel sheets of the form '''ALCharacter.xls''' (such as ALAlistair.xls, ALLeliana.xls, ALRogue_Default.xls etc).  Open the one closest to your character (ie Morrigan or Wynne for a wizard, Leliana or Zevran for a rogue).  Save a copy as '''ALYourcharacter.xls''' in whatever directory you're using to create your 2DAs, remembering to rename the worksheet '''ALYourcharacter''' (in this example, ALMiera.xls with ALMiera as its worksheet).&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:ALtable.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns B''' and '''C''' are the talents/spells available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
'''Columns F''' and '''G''' are the skills available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
We will edit the remaining columns like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Stat Weights ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The stat weights in '''column J''' determine how the follower will spend their attribute points, in a rough ratio.  So if Dexterity is set to 1.5 and Intelligence to 1, you should expect to see 3 points of Dex for every 2 points of Cunning in-game (note Intelligence is the label used in the toolset for Cunning).&lt;br /&gt;
&lt;br /&gt;
Simply change the values in J to reflect how you'd like the character to spend their points.  In this example we're creating a wizard, so we're not going to mess around:&lt;br /&gt;
&lt;br /&gt;
[[File:miera_stat_weights.jpg]]&lt;br /&gt;
&lt;br /&gt;
This character will only raise magic.  I set the value to 5 rather than something like 1 to provide room underneath for the other stats while still overwhelmingly favouring magic, but in practice I only really ever want that one stat. &lt;br /&gt;
&lt;br /&gt;
In a note left on this column in the existing templates, Bioware's Georg Zoeller writes, &amp;quot;This is the weight of each attribute (row id links into properties.xls.id). 1.0 means 'try to keep this attribute level' (spend 1 point per level). 0.5 means 'try to spend 1 point every two levels' and so on.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The default Mage, Rogue and Warrior templates include '''column L''' labeled &amp;quot;AttInit.&amp;quot; Editing these values seems to have no effect on followers set to use these templates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Talent and Skill Priorities ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns D''' and '''E''' are the talents/spells that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
'''Columns H''' and '''I''' are the skills that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change these, just copy the appropriate two cells from columns B&amp;amp;C or F&amp;amp;G over the ones you want to replace.&lt;br /&gt;
&lt;br /&gt;
For example, here we're copying Morrigan's template.  Morrigan has Spider Shape high in her preferences, which we do not want.&lt;br /&gt;
&lt;br /&gt;
[[File:AlMori_talent_pref.jpg]]&lt;br /&gt;
&lt;br /&gt;
We decide we'd prefer Flame Blast, so we find it in columns B&amp;amp;C and copy both cells:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_copy.jpg]]&lt;br /&gt;
&lt;br /&gt;
Then we select the cells we want to replace in columns D&amp;amp;E and paste over them:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_paste.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue this process until your priorities list for both skills and talents/spells is exactly as you want it.  Make sure you have at least as many priorities as the core follower you're copying - points that cannot be spent according to these priorities have a habit of vanishing.&lt;br /&gt;
&lt;br /&gt;
If you used any abilities from a specialisation, make sure you remember to set that specialisation with the function we'll introduce later.  The autolevel scripts will add specialisation abilities to a character regardless of whether they have that spec or not.&lt;br /&gt;
&lt;br /&gt;
==== Create a M2DA_base_ m2DA ====&lt;br /&gt;
&lt;br /&gt;
Dragon Age will need to know where to find your autolevel template.  We tell it by extending M2DA_base.gda&lt;br /&gt;
&lt;br /&gt;
Create a spreadsheet with the name and worksheet name in the form '''M2DA_base_''' with your unique suffix (in this example, M2DA_base_fofbc.xls with M2DA_base_fofbc as a worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up its columns and data like so (note I used GDApp because Open Office wasn't cooperating for this one!):&lt;br /&gt;
&lt;br /&gt;
[[File:m2da_base_fofbc.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' should be very high to avoid conflicts.  I've arbitrarily chosen 50,000+ here.  Carefully note the ID you've chosen for your character, you will need it later.&lt;br /&gt;
&lt;br /&gt;
Set the '''Label''' and '''Worksheet''' to be the name of your autolevel template worksheet (ALCharactername if you've been following this).&lt;br /&gt;
&lt;br /&gt;
Set the '''PackageIDForAI''' to be 0, it shouldn't be needed for followers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you're done, use ExcelProcessor to make GDAs of both spreadsheets and copy them to your module's export folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FOR AUTOLEVEL TO WORK AFTER RECRUITING:&lt;br /&gt;
&lt;br /&gt;
Look in packages.xls. &lt;br /&gt;
There is a column called LevelupTable. That links to a corresponding AL* table. For instance,  row 81 is for Leliana. Her LevelupTable value is 258. If you look that up in 2DA_base, you'll see it links to ALLeliana.&lt;br /&gt;
(alternatively, you could try packages_base.gda)&lt;br /&gt;
&lt;br /&gt;
=== Create a New Hire Function Include ===&lt;br /&gt;
&lt;br /&gt;
Many vital steps of follower addition happen inside an event in player_core.  Followers tend to be extremely buggy (no skill tree, for example) if this event does not fire.&lt;br /&gt;
&lt;br /&gt;
However, that event is not very flexible.  In order to control it to our requirements, we need to replicate its functionality inside our own script.  This is probably much safer than messing with player_core directly!&lt;br /&gt;
&lt;br /&gt;
Create a new script file, naming it something like '''hireCustomFollower_h'''.  We will be including this wherever we want to hire a follower.&lt;br /&gt;
&lt;br /&gt;
Paste in the following script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;approval_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_autolevelup_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*  Jye Nicolson 5-Jan-2010&lt;br /&gt;
This function set duplicates the full functionality chain of UT_HireFollower, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
-  Followers can gain XP&lt;br /&gt;
-  Autolevel status can be set (default off)&lt;br /&gt;
-  Followers can be set to any starting state (default Available) and will still be properly initalised and added to the party pool&lt;br /&gt;
-  Autolevel tables for non-core followers can be explicitly set.&lt;br /&gt;
-  Class and Specialisation can be chosen via script&lt;br /&gt;
-  Followers without specialisations are granted a spec point by default.&lt;br /&gt;
&lt;br /&gt;
It should only ever be called once each for characters you intend to be full followers.&lt;br /&gt;
Much of the protective code handling summoned creatures etc. in player_core is not present here.&lt;br /&gt;
&lt;br /&gt;
Calling the function:&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR);&lt;br /&gt;
&lt;br /&gt;
Change the class to CLASS_WIZARD or CLASS_ROGUE as appropriate.  &lt;br /&gt;
This will hire your follower and make them available.  &lt;br /&gt;
They will auto level up with a default package, and receive a free spec point.&lt;br /&gt;
&lt;br /&gt;
Best Practice:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR, PLT_YOUR_PARTY_PLOT, YOUR_FOLLOWER_JOINED_FLAG, ABILITY_TALENT_HIDDEN_CHAMPION);&lt;br /&gt;
&lt;br /&gt;
Where the plot and flag are those for your module (remember to create the plot and include it on the calling script), and ABILITY_TALENT_HIDDEN etc is the desired spec.&lt;br /&gt;
&lt;br /&gt;
You should also have a custom ALTable set up.  &lt;br /&gt;
See wiki for details, and remember to edit it in to GetCustomFollowerALTable below or pass it directly as an argument to hireCustomFollower.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Full argument list:&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower (&lt;br /&gt;
        object oFollower,   //Pass your follower object, mandatory&lt;br /&gt;
        &lt;br /&gt;
        int nForceClass,    //Pass a Class constant here, usually CLASS_ROGUE, CLASS_WARRIOR, CLASS_WIZARD.  Mandatory due to a bug.&lt;br /&gt;
        &lt;br /&gt;
        string sPlot = &amp;quot;&amp;quot;,   //It's recommended you have a plot flag to be set when the follower joins.  Pass the plot constant here.  Remember to #include in calling script&lt;br /&gt;
        &lt;br /&gt;
        int nPlotFlag = &amp;quot;&amp;quot;,  //And then pass the flag constant.  Will be set to TRUE if available.&lt;br /&gt;
        &lt;br /&gt;
        int nForceSpec = 0,  //This is the ID of the Specialisation you want.  Note they are NOT classes, but abilities.  The full list is:&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_ARCANE_WARRIOR, ABILITY_SPELL_HIDDEN_BLOODMAGE, ABILITY_SPELL_HIDDEN_SHAPESHIFTER, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_BARD, ABILITY_TALENT_HIDDEN_ASSASSIN, ABILITY_TALENT_HIDDEN_DUELIST, ABILITY_TALENT_HIDDEN_RANGER&lt;br /&gt;
                             //ABILITY_TALENT_HIDDEN_BERSERKER, ABILITY_TALENT_HIDDEN_CHAMPION, ABILITY_TALENT_HIDDEN_REAVER, ABILITY_TALENT_HIDDEN_TEMPLAR&lt;br /&gt;
                             //I recommended forcing a spec, particularly if your ALTable includes abilities from one.&lt;br /&gt;
        &lt;br /&gt;
        int nALTable = 0,    //This is the ID of an ALTable from 2DA_base.GDA or your module's m2DA_base_*.GDA  I recommended the latter, but you can edit that into GetCustomFollowerALTable below rather than passing it.&lt;br /&gt;
        &lt;br /&gt;
        int bInvokePicker = FALSE,  //Sets whether the party picker should be opened on hiring.  I think it's cleaner to call the picker outside this script, particularly if you have multiple hires at once.&lt;br /&gt;
        &lt;br /&gt;
        int nInitialState = FOLLOWER_STATE_AVAILABLE,  //This sets whether the follower joins the active party or not.  Options are:&lt;br /&gt;
                                                       //FOLLOWER_STATE_ACTIVE (put them in the active party)&lt;br /&gt;
                                                       //FOLLOWER_STATE_LOCKEDACTIVE (force them into the active party and keep them there, remember to change this later.&lt;br /&gt;
                                                       //FOLLOWER_STATE_AVAILABLE (make them available on the party picker (if you've set it up for them), but not in the active party)&lt;br /&gt;
                                                       //Plus some others you're unlikely to need at this time.  Defaults to AVAILABLE because having 4+ active followers is screwy.&lt;br /&gt;
                                                       &lt;br /&gt;
        string sCurrPlot = &amp;quot;&amp;quot;,  //If you set FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE, the script will check to see if you passed this.&lt;br /&gt;
                                //It is recommended that you have a plot flag set for a given follower being in the active party, this makes conversation interjection etc. much easier.&lt;br /&gt;
&lt;br /&gt;
        int nCurrPlotFlag = 0,  //This flag will be set if FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE are true&lt;br /&gt;
                                //AND sCurrPlot has a value AND nCurrPlotFlag is &amp;gt; 0.  &lt;br /&gt;
                                //ie if you added someone to the active party and have a plot flag to cope with it.&lt;br /&gt;
&lt;br /&gt;
        int nAutolevel = 0,     //Sets the Autolevel flag on the character sheet.  0 is off, 1 is on, 2 forces it on and removes it so the player can't turn it off.&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        bFreeSpecPoint = TRUE,  //This grants a specialisation point to the follower if they do not have a specialisation.  &lt;br /&gt;
                                //It's important to set this false for classes that do not have specs, such as CLASS_DOG.&lt;br /&gt;
                                &lt;br /&gt;
        int nTargetLevel = 0,   //If you want a specific level, set this.  Generally not worthwhile unless you set it higher than the player, since they'll just get XP from the party picker anyway.&lt;br /&gt;
        &lt;br /&gt;
        int nMinLevel = 0       //Set this if there's a specific level you don't want the follower to go below.  Probably only useful if the PC might be very low level but not necessarily so. &lt;br /&gt;
        &lt;br /&gt;
        )&lt;br /&gt;
*/       &lt;br /&gt;
/* GetCustomFollowerALTable()  &lt;br /&gt;
This function is where you put your custom table assignments.&lt;br /&gt;
&lt;br /&gt;
You should explicitly test for the tag of your follower (not mine!) and assign a value to nTable from your m2DA extension to M2DA_base &lt;br /&gt;
&lt;br /&gt;
See wiki for details on how to do this, or ignore it to get the default Warrior/Rogue/Wizard AL tables.&lt;br /&gt;
&lt;br /&gt;
NOTE: you MUST explicitly set a table for non-Warrior/Rogue/Wizards, eg dogs.  Use TABLE_AL_DOG for a default Mabari.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// This just cleans up the main function a little&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerTargetLevel(object oFollower, object oHero, int nPackage, int nMinLevel = 0) {&lt;br /&gt;
            int nPlayerLevel = GetLevel(oHero);&lt;br /&gt;
            int nTargetLevel = 0;&lt;br /&gt;
&lt;br /&gt;
            if((nPlayerLevel &amp;gt;= 13) || (nPlayerLevel == 1) || (!_UT_GetIsPlotFollower(oFollower))) {&lt;br /&gt;
               nTargetLevel = nPlayerLevel;&lt;br /&gt;
            } else {&lt;br /&gt;
               nTargetLevel = nPlayerLevel + 1;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (nMinLevel == 0) {  //If nMinLevel is not specified, checks package 2DA for a value&lt;br /&gt;
              nMinLevel = GetM2DAInt(TABLE_PACKAGES, &amp;quot;MinLevel&amp;quot;, nPackage);&lt;br /&gt;
             }&lt;br /&gt;
            if(nMinLevel &amp;gt; 0 &amp;amp;&amp;amp; nMinLevel &amp;gt; nTargetLevel) {&lt;br /&gt;
               nTargetLevel = nMinLevel;&lt;br /&gt;
            }          &lt;br /&gt;
            &lt;br /&gt;
            return nTargetLevel;&lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// Moving this black box out :)  I don't really understand it, but it should function if you have tactics set up in a package.&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerTactics(object oFollower, int nPackage) {&lt;br /&gt;
         int nTableID = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerTacticsTable&amp;quot;, nPackage);&lt;br /&gt;
         if (nTableID != -1)&lt;br /&gt;
            {&lt;br /&gt;
             int nRows = GetM2DARows(nTableID);&lt;br /&gt;
             int nMaxTactics = GetNumTactics(oFollower);&lt;br /&gt;
&lt;br /&gt;
             int nTacticsEntry = 1;&lt;br /&gt;
             int i;&lt;br /&gt;
             for (i = 1; i &amp;lt;= nRows &amp;amp;&amp;amp; nTacticsEntry &amp;lt;= nMaxTactics; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                        int bAddEntry = FALSE;&lt;br /&gt;
                        int nTargetType = GetM2DAInt(nTableID, &amp;quot;TargetType&amp;quot;, i);&lt;br /&gt;
                        int nCondition = GetM2DAInt(nTableID, &amp;quot;Condition&amp;quot;, i);&lt;br /&gt;
                        int nCommandType = GetM2DAInt(nTableID, &amp;quot;Command&amp;quot;, i);&lt;br /&gt;
                        int nCommandParam = GetM2DAInt(nTableID, &amp;quot;SubCommand&amp;quot;, i);&lt;br /&gt;
&lt;br /&gt;
                        int nUseType = GetM2DAInt(TABLE_COMMAND_TYPES, &amp;quot;UseType&amp;quot;, nCommandType);&lt;br /&gt;
                        if (nUseType == 0)&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = TRUE;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = HasAbility(oFollower, nCommandParam);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (bAddEntry)&lt;br /&gt;
                        {&lt;br /&gt;
                            SetTacticEntry(oFollower, nTacticsEntry, TRUE, nTargetType, nCondition, nCommandType, nCommandParam);&lt;br /&gt;
                            ++nTacticsEntry;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
/* InitCustomFollowerSpec:&lt;br /&gt;
&lt;br /&gt;
This function tries to set the forced Specialisation.  If there is none, it checks the package for one.  &lt;br /&gt;
&lt;br /&gt;
If there isn't either of those, it grants a free spec point if bFreeSpecPoint is true.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerSpec(object oFollower, int nPackage, int nForceSpec, int bFreeSpecPoint) {&lt;br /&gt;
    // Find specialization, and optionally add a spec point if none is found.&lt;br /&gt;
&lt;br /&gt;
        if (nForceSpec == 0) {&lt;br /&gt;
    &lt;br /&gt;
        int nSpecAbility = GetM2DAInt(TABLE_PACKAGES, &amp;quot;switch1_class&amp;quot;, nPackage); // followers can have only 1 advanced class&lt;br /&gt;
         if(nSpecAbility &amp;gt; 0)&lt;br /&gt;
         {&lt;br /&gt;
          AddAbility(oFollower, nSpecAbility);&lt;br /&gt;
         } else {&lt;br /&gt;
             if (bFreeSpecPoint) {&lt;br /&gt;
                 SetCreatureProperty(oFollower, 38, 1.00);&lt;br /&gt;
             }&lt;br /&gt;
         }                    &lt;br /&gt;
        &lt;br /&gt;
        } else {&lt;br /&gt;
         &lt;br /&gt;
             AddAbility(oFollower, nForceSpec);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* hireCustomFollower()  (See doco at top of page)&lt;br /&gt;
&lt;br /&gt;
I strongly suggest you reorder the parameters if you're adding many followers with advanced options.&lt;br /&gt;
&lt;br /&gt;
Feel free to leave them alone if you only want to set class, plot, spec or don't mind long declarations.&lt;br /&gt;
&lt;br /&gt;
Note nForceClass is currently compulsory due to flakiness with GetCreatureCoreClass()&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower(object oFollower, int nForceClass, string sPlot = &amp;quot;&amp;quot;, int nPlotFlag = 0, int nForceSpec = 0, &lt;br /&gt;
int nALTable = 0, int bInvokePicker = FALSE, int nInitialState = FOLLOWER_STATE_AVAILABLE, string sCurrPlot = &amp;quot;&amp;quot;, &lt;br /&gt;
int nCurrPlotFlag = 0, int nAutolevel = 0, int bFreeSpecPoint = TRUE, int nTargetLevel = 0, int nMinLevel = 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        object oHero = GetHero();&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN BASIC FOLLOWER JOIN BLOCK   ###################&lt;br /&gt;
&lt;br /&gt;
        This loosely replicates WR_SetFollowerState.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */    &lt;br /&gt;
        &lt;br /&gt;
        if (nForceClass == 0) {&lt;br /&gt;
            nForceClass = GetCreatureCoreClass(oFollower);           //This is not working.  Hence nForceClass mandatory.&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        SetGroupId(oFollower, GetGroupId(oHero));      //Puts the follower in the pc's Group.&lt;br /&gt;
        SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);  //This makes them act like a player.&lt;br /&gt;
        SetFollowerState(oFollower, nInitialState);  //This sets whether they are available, in the active party etc.&lt;br /&gt;
&lt;br /&gt;
        /* #################  END BASIC FOLLOWER JOIN BLOCK ##################### */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION #################&lt;br /&gt;
         This replicates the EVENT_TYPE_PARTY_MEMBER_HIRED handler from player_core, stripped down for simplicity and allowing our custom options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        Chargen_EnableTacticsPresets(oFollower);    //I assume this is important.&lt;br /&gt;
        &lt;br /&gt;
        SetLocalInt(oFollower, FOLLOWER_SCALED, 1);  //This should prevent the follower being rescaled by player_core or what have you&lt;br /&gt;
        &lt;br /&gt;
        int nPackage = GetPackage(oFollower);  //Gets the package, which will be used to find a number of 2DA IDs.&lt;br /&gt;
        int nPackageClass = GetM2DAInt(TABLE_PACKAGES, &amp;quot;StartingClass&amp;quot;, nPackage);  //I don't think this is used, even by player_core&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // set behavior according to package&lt;br /&gt;
        int nBehavior = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerBehavior&amp;quot;, nPackage);&lt;br /&gt;
&lt;br /&gt;
        if(nBehavior &amp;gt;= 0) {&lt;br /&gt;
            SetAIBehavior(oFollower, nBehavior);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        Chargen_InitializeCharacter(oFollower);      //We initialise the follower and choose race/class.&lt;br /&gt;
        &lt;br /&gt;
        Chargen_SelectRace(oFollower,GetCreatureRacialType(oFollower));&lt;br /&gt;
        Chargen_SelectCoreClass(oFollower,nForceClass);        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         if (nTargetLevel == 0) {   //This block picks a target level if not specified&lt;br /&gt;
            &lt;br /&gt;
              nTargetLevel = GetCustomFollowerTargetLevel(oFollower, oHero, nPackage, nMinLevel);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));      //Here is where the XP is calculated and rewarded&lt;br /&gt;
         RewardXP(oFollower, nXp, FALSE, FALSE);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // add hidden approval talents - (JN: I don't know how to set these yet, but when I figure it out this should make it work)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         int nIndex = Approval_GetFollowerIndex(oFollower);&lt;br /&gt;
         Approval_AddFollowerBonusAbility(nIndex, 0);&lt;br /&gt;
        &lt;br /&gt;
          //Handle Specialisation&lt;br /&gt;
          InitCustomFollowerSpec(oFollower, nPackage, nForceSpec, bFreeSpecPoint);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // This spends all available attribute and stat points on the&lt;br /&gt;
         // creature according to the levelup table.  (JN:  this replicates AL_DoAutoLevelUp but with our choice of table)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
         if (nALTable == 0) {&lt;br /&gt;
            nALTable = GetCustomFollowerALTable(oFollower);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         AL_SpendAttributePoints(oFollower, nALTable, FALSE);&lt;br /&gt;
         AL_SpendSkillPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
         AL_SpendSpecializationPoints(oFollower, nALTable);&lt;br /&gt;
         AL_SpendTalentSpellPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        // Update various UIs&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        Chargen_SetNumTactics(oFollower);&lt;br /&gt;
        SetCanLevelUp(oFollower,Chargen_HasPointsToSpend(oFollower));&lt;br /&gt;
&lt;br /&gt;
        // load tactics&lt;br /&gt;
         InitCustomFollowerTactics(oFollower, nPackage);&lt;br /&gt;
&lt;br /&gt;
         /* #################  END PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION ################# */     &lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
         SetAutoLevelUp(oFollower, nAutolevel);         //This is the autolevel flag on the character sheet.&lt;br /&gt;
         &lt;br /&gt;
         //Set plot flags&lt;br /&gt;
         &lt;br /&gt;
         if (!((sPlot == &amp;quot;&amp;quot;) || (nPlotFlag == 0))) {           //Joined Party&lt;br /&gt;
            WR_SetPlotFlag(sPlot, nPlotFlag, TRUE);   &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         if ((nInitialState == FOLLOWER_STATE_ACTIVE) || (nInitialState == FOLLOWER_STATE_LOCKEDACTIVE)) {&lt;br /&gt;
            if (!((sCurrPlot == &amp;quot;&amp;quot;) || (nCurrPlotFlag == 0))) {&lt;br /&gt;
                WR_SetPlotFlag(sCurrPlot, nCurrPlotFlag, TRUE);   //Currently in Party&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
                     &lt;br /&gt;
        // Invoke picker if requested.&lt;br /&gt;
&lt;br /&gt;
        if (bInvokePicker) {&lt;br /&gt;
             SetPartyPickerGUIStatus(2);&lt;br /&gt;
             ShowPartyPickerGUI();&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yeah, I know.  It can't really be any smaller.  Feel free to modify it if you're confident with scripting.&lt;br /&gt;
==== Add Your Custom Autolevel Template to GetCustomFollowerALTable() ====&lt;br /&gt;
While you can pass the ID you made for your autolevel template to that monster function as an argument, it's better to have them all in one place if you have multiple followers.&lt;br /&gt;
&lt;br /&gt;
GetCustomFollowerALTable() is the first function in our include, and you can add an explicit if test for your follower there to assign the correct table id (the one from your M2DA_base_ m2DA).  There is a function very much like it in sys_autolevel_h.nss for the core followers, so we'll copy Bioware's practice.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the function by itself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we have a test for each follower tag from my module, matching up to an ID which is assigned to nTable.  All you need to do is change a tag from my follower to yours, and my ID to the correct one from your M2DA_base_* m2DA.  Then you should delete the rest of the example if statements :)&lt;br /&gt;
&lt;br /&gt;
Save and export the script.  Ignore the compiler error about lack of main();&lt;br /&gt;
&lt;br /&gt;
=== Include Function In Your Hire Script and Call It ===&lt;br /&gt;
&lt;br /&gt;
So instead of a hire script that calls UT_HireFollower(), we want one that includes our shiny new function and calls it.&lt;br /&gt;
&lt;br /&gt;
Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //Make sure you include your party handling plot&lt;br /&gt;
#include &amp;quot;hireCustomFollower_h&amp;quot;  // And include the function script - which will in turn include a bunch of stuff&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
                    //Initialising my objects, not super-relevant to the example &lt;br /&gt;
                     &lt;br /&gt;
                    object oHero = GetHero();&lt;br /&gt;
                    object oMiera = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_miera.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oJysavin = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_jysavin.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oBraghon = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_braghon.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oSpider = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_geldual.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
&lt;br /&gt;
                    //Simplest hire call - adds to the party as a wizard.  Class is currently compulsory due to a bug.&lt;br /&gt;
                    hireCustomFollower(oMiera, CLASS_WIZARD);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party and set joining plot flags&lt;br /&gt;
                    hireCustomFollower(oJysavin, CLASS_WARRIOR, PLT_BC_CREATE_PARTY, PARTY_JYSAVIN_JOINED);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party, set plot flags, force a specialisation&lt;br /&gt;
                    hireCustomFollower(oBraghon, CLASS_ROGUE, PLT_BC_CREATE_PARTY, PARTY_BRAGHON_JOINED, ABILITY_TALENT_HIDDEN_ASSASSIN);&lt;br /&gt;
&lt;br /&gt;
                    //More complex example - Follower added as a unique class (Dog), not granted a specialisation or spec point.  &lt;br /&gt;
                    //Note unique classes must have an ALTable passed here or specified in GetCustomFollowerALTable() or they won't work&lt;br /&gt;
                    hireCustomFollower(oSpider, CLASS_DOG, PLT_BC_CREATE_PARTY, PARTY_GELDUAL_JOINED, 0, 0, FALSE, FOLLOWER_STATE_AVAILABLE, &amp;quot;&amp;quot;, 0, 0, FALSE);&lt;br /&gt;
                   &lt;br /&gt;
                    //Show the party picker to let the player choose from their new companions!&lt;br /&gt;
                    SetPartyPickerGUIStatus(2);&lt;br /&gt;
                    ShowPartyPickerGUI();                                                                                                                    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example shows several of the more simple ways of invoking the function.  Check the comments at the start of the function for a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
I would suggest best practice for most followers would be to call as follows:&lt;br /&gt;
&lt;br /&gt;
'''hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION)'''&lt;br /&gt;
&lt;br /&gt;
This will safely set the follower up as the desired class and specialisation (doubly important if there are spec abilities in their ALTable) while setting your plot flag for them being in the party.  hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION, 0, TRUE) will do the same while invoking the Party Picker automatically.&lt;br /&gt;
&lt;br /&gt;
Note that the specialisations are abilities and not classes - you'll find them as ABILITY_HIDDEN_ constants.&lt;br /&gt;
&lt;br /&gt;
If it's all worked, you should find you can now add followers with a lot more flexibility!&lt;br /&gt;
&lt;br /&gt;
[[File:picker_advanced.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Common Follower Problems &amp;amp; FAQ ==&lt;br /&gt;
&lt;br /&gt;
====Why don't my followers gain XP?====&lt;br /&gt;
There is a bug in UT_HireFollower. For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
(Note: Be aware if you use the name UT_HireFollower_Fixed you may end up finding your include file conflicting with someone else who has named it the same in their include.)&lt;br /&gt;
&lt;br /&gt;
Alternately you need to clear a flag in a separate script to the one in which they're hired.&lt;br /&gt;
&lt;br /&gt;
You must use the '''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);''' statement in a script you can be sure will run soon after your hiring script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====When I choose followers from the Party Picker, they spawn into the area but do not join.====&lt;br /&gt;
&lt;br /&gt;
You need to intercept the EVENT_TYPE_PARTYMEMBER_ADDED event and set the follower to FOLLOWER_STATE_ACTIVE.  See Simple Follower Creation earlier in this document.&lt;br /&gt;
&lt;br /&gt;
====My followers don't have skill trees!====&lt;br /&gt;
&lt;br /&gt;
If a follower hasn't been through an initial chargen/autolevel event (via player_core/sys_autolevel_h) then the skill tree doesn't show.  You're probably trying to be clever and get around UT_HireFollower without going all the way (see monster function above ^_^).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have a class====&lt;br /&gt;
&lt;br /&gt;
GetCreatureCoreClass() seems flaky under some conditions.  It's best to explicitly set the class yourself; this is why class is currently a mandatory argument to hireCustomFollower()&lt;br /&gt;
&lt;br /&gt;
====Dog talents don't work====&lt;br /&gt;
Symptoms: dog talents appear on the talents screen but remain greyed out on level up. Warrior talents appear in the quickslots.&lt;br /&gt;
&lt;br /&gt;
Line 78 of packages_base in packages.xls (Dog) should have the LevelUpTable column set to 257 which is the ALDog table.&lt;br /&gt;
&lt;br /&gt;
====Isn't there an easier way to do this?====&lt;br /&gt;
&lt;br /&gt;
Possibly.  There is a way of recruiting a follower by setting a plot flag.  However I don't understand it, and I expect it still doesn't allow custom autolevel templates, full control over specialisations etc.  There's still a fair bit of stuff hardcoded for the core followers, I'm not sure putting a custom follower through the same process as Al, Leli et al will have good results.&lt;br /&gt;
&lt;br /&gt;
The next section answers this question, up to a point.&lt;br /&gt;
&lt;br /&gt;
==== What if there are more than three potential followers? ====&lt;br /&gt;
This example handles larger numbers of followers, and doesn't force the player to use the party picker unless the party is already full.&lt;br /&gt;
&lt;br /&gt;
The prefix zzz, used throughout, can be replaced with whatever [[Prefixes_in_use | prefix]] you are using for your resources.&lt;br /&gt;
&lt;br /&gt;
If you're making a new campaign, to keep life simple, allocate a unique number to each follower. You could either use a creature variable or a script, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Party member id (e.g. 1=Alicia, 2=Godwin...)&lt;br /&gt;
int zzzPartyMemberID(object oPartyMember)&lt;br /&gt;
{&lt;br /&gt;
  string sPartyMember = GetTag(oPartyMember);&lt;br /&gt;
&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_alicia&amp;quot;) return 1;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_godwin&amp;quot;) return 2;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_harold&amp;quot;) return 3;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_lara&amp;quot;  ) return 4;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make two separate plots, e.g. zzzpt_hired for when a follower is first recruited, and zzzpt_party to flag whether they're currently in the party. Use flag values that correspond to the unique follower id, e.g. ZZZPT_HIRED_GODWIN will be 2.&lt;br /&gt;
&lt;br /&gt;
If you're modifying the official campaign, you won't be able to make this simplification - you'll need a set of plot flags for your new party members, similar to the official ones. The logic of what follows is still correct, it just means that instead of having one set of common code that works for everyone, you have to explicitly script each party member individually using their personal plot flags.&lt;br /&gt;
&lt;br /&gt;
Follower conversation is now very simple. In Godwin's dialogue, the hiring line will be conditional - when ZZZPT_HIRED_GODWIN is clear - and it will set ZZZPT_HIRED_GODWIN.  No conversation script is necessary. Instead, in the properties of the plot zzzpt_hired, we add a plot event script, as follows.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// PARTY HIRE PLOT SCRIPT&lt;br /&gt;
//&lt;br /&gt;
// This is called in conversation when a party member is hired for the first time.&lt;br /&gt;
// If the party is full, the party picker is displayed, which forces the PARTYMEMBER_ADDED&lt;br /&gt;
// module event.&lt;br /&gt;
//&lt;br /&gt;
// The flag value is never referenced, because the code is common for all party members.&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;log_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plot_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;zzz_h&amp;quot;                  // A header containing the zzzPartyMemberID function&lt;br /&gt;
#include &amp;quot;plt_zzzpt_hired&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_zzzpt_party&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int StartingConditional()&lt;br /&gt;
{&lt;br /&gt;
    event  eParms             = GetCurrentEvent();&lt;br /&gt;
    int    nType              = GetEventType(eParms);       // GET or SET&lt;br /&gt;
    string strPlot            = GetEventString(eParms, 0);  // Plot GUID&lt;br /&gt;
    int    nFlag              = GetEventInteger(eParms, 1); // Plot flag&lt;br /&gt;
    object oParty             = GetEventCreator(eParms);    // Plot table owner&lt;br /&gt;
    object oFollower          = GetEventObject(eParms, 0);  // Conversation owner (if any)&lt;br /&gt;
    int    nPlotType          = GetEventInteger(eParms, 5); // Plot type&lt;br /&gt;
&lt;br /&gt;
    int    bIsTutorial        = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsTutorial&amp;quot;, nPlotType);&lt;br /&gt;
    int    bIsCodex           = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsCodex&amp;quot;, nPlotType);&lt;br /&gt;
&lt;br /&gt;
    int    nResult            = FALSE;                      // return value for DEFINED GET&lt;br /&gt;
    object oPC                = GetPartyLeader();&lt;br /&gt;
&lt;br /&gt;
    plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info&lt;br /&gt;
&lt;br /&gt;
    if (nType == EVENT_TYPE_SET_PLOT) // actions -&amp;gt; normal flags only&lt;br /&gt;
    {&lt;br /&gt;
        int nValue    = GetEventInteger(eParms, 2); // 0=Clear 1=Set&lt;br /&gt;
        int nOldValue = GetEventInteger(eParms, 3); // Current flag value&lt;br /&gt;
&lt;br /&gt;
        if (nValue)&lt;br /&gt;
          {&lt;br /&gt;
            if (GetArraySize(GetPartyList(oPC)) &amp;lt; 4)&lt;br /&gt;
              {&lt;br /&gt;
                UT_HireFollower(oFollower);&lt;br /&gt;
                SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
                AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
                SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
                WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
              }&lt;br /&gt;
            else&lt;br /&gt;
              {&lt;br /&gt;
                WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
                SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);&lt;br /&gt;
                SendPartyMemberHiredEvent(oFollower, TRUE);&lt;br /&gt;
//                SetPartyPickerGUIStatus(PP_GUI_STATUS_USE);&lt;br /&gt;
//                ShowPartyPickerGUI();&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
     else // EVENT_TYPE_GET_PLOT -&amp;gt; defined conditions only&lt;br /&gt;
     {&lt;br /&gt;
        switch(nFlag)&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    plot_OutputDefinedFlag(eParms, nResult);&lt;br /&gt;
    return nResult;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We still need to handle the party picker events in our module event script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         // PARTY MEMBER ADDED - Allow XP gain. Come here, follow me, flag as party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
         {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
            break;&lt;br /&gt;
         }&lt;br /&gt;
         // PARTY MEMBER DROPPED - flag as not party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_DROPPED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), FALSE);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
When we need to refer to a particular follower explicitly, we can still do so - for example, the flag ZZZPT_PARTY_GODWIN will tell use whether Godwin is currently in the party or not.&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation: An Alternative Approach ==&lt;br /&gt;
&lt;br /&gt;
While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfectly good wheel at hand. The following describes how to adapt the existing machinery for the recruitment and tracking of your own party members.&lt;br /&gt;
&lt;br /&gt;
First create the setup as described above in Simple Follower Creation, except for the scripts and plot tables. In addition, create the GDA extensions for a level-up table and the M2DA which points to those tables, as described in Advanced Follower Creation above.&lt;br /&gt;
&lt;br /&gt;
Now ...&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Create a party plot table ===&lt;br /&gt;
&lt;br /&gt;
Have a look at the gen00pt_party plot table and create a similar table for your own followers. Don't bother with the Defined Flags for the moment, just the Main Flags will do, ie recruited, in-camp and in-party for each follower. (Critical Note: Do not duplicate the plot table, create one from scratch. This is the case for ALL plot tables because of a show-stopping bug which means a new GUID is not assigned on Duplicate of a plot.)&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create a party script ===&lt;br /&gt;
&lt;br /&gt;
Duplicate the gen00pt_party script and rename for your module (conventionally plot tables and their plot scripts have the same name). Delete (or comment out) the Defined Flags section at the end and any lines dealing with logging and tutorials. Change names to those of your party members. If you are using gifting, approval or forced inclusion you may wish to retain those sections of code, but additional machinery will be needed for these facilities to work. For approval you can specify a starting level of approval here for each follower if you want it to be other than zero (as per the existing section dealing with Dog). Note that the custom hire function at the head of the script allows you to specify whether or not to invoke the party picker on recruitment. You may not want to do so for the first couple of followers (but see below). You should already have defined all required constants in a separate file for your module, eg &amp;lt;module prefix&amp;gt;_constants_h. If not, do so now and include it, as well as your plot table, at the head of the script. Delete includes that only refer to the main campaign. (If this is all Greek to you, spend a couple of hours examining the set-up of the Demo, which is packaged with the toolset, and go through the introductory tutorials referenced on the main page of this wiki).&lt;br /&gt;
&lt;br /&gt;
Looking at the new party script, notice that the follower-in-camp function is not defined. This is because for some arcane reason it is defined in party_h, and unhappily references the main campaign's plot table. So we will have to create a new function to replace it, change the other function's flag reference (for the sake of neatness), and change the call in the main body of the script. (You may decide later for other reasons to replicate and customise party_h, but that won't interfere with re-creating this function here.)&lt;br /&gt;
&lt;br /&gt;
Our two functions at the head of the script should be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;void SetFollowerInParty(object oFollower, string sPlot, int nCampFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nCampFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, TRUE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE);&lt;br /&gt;
    command cJump = CommandJumpToObject(GetPartyLeader());&lt;br /&gt;
    WR_AddCommand(oFollower, cJump);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SetFollowerInCamp(object oFollower, string sPlot, int nPartyFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nPartyFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, FALSE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
}&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and the line in the in-camp sections for each follower should now be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;SetFollowerInCamp(o&amp;lt;follower&amp;gt;, strPlot, &amp;lt;follower&amp;gt;_IN_PARTY);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Step 3: Create package GDAs and reference them in you 2DA_base extension ===&lt;br /&gt;
&lt;br /&gt;
Look at the packages_base GDA and create an extension GDA with one line for each follower based on a main campaign follower that is most like your own follower, eg a sword-shield warrior can be a copy of Alistair, a battle mage a copy of Morrigan, etc. You can look at the Excel version of this GDA to more easily see what the fields mean. It is here that you can specify what if any specialisation will be assigned on hire and the level at which this spec point becomes available. (The IDs for each spec are in the 4000-range of ABI_base.)&lt;br /&gt;
&lt;br /&gt;
Most importantly, it is here also that you define the ID of both your level-up table and the AIP table you are about to create.&lt;br /&gt;
&lt;br /&gt;
Now create aip_follower_&amp;lt;follower name&amp;gt; gda tables, again based on a existing tables most like your own followers. No changes should be required to the copies you create.&lt;br /&gt;
&lt;br /&gt;
In the m2da_base_&amp;lt;your module&amp;gt; extension you have already created, add lines for your AIP tables with a package ID referencing the IDs you assigned in your packages extension table.&lt;br /&gt;
&lt;br /&gt;
Carefully check that all IDs in your GDAs are correct and cross-reference properly, and save the GDAs to your override directory.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Module script addition ===&lt;br /&gt;
&lt;br /&gt;
Modify your own module script to point to the new plot table and your own followers. To see an example of the required code for the two new sections look at the relevant section of module_core, which are for EVENT_TYPE_PARTYMEMBER_ADDED and EVENT_TYPE_PARTYMEMBER_DROPPED.&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The recruit flag is set in a conversation (usually, but it could be a script) and that event is then processed by the plot script, which among other things sets both the in-camp and in-party flags, and fires up the party picker by default. If the player then selects the follower in the picker, the in-camp flag is unset (or vice versa if the follower is not selected to join). Subsequently, if the character is selected (or unselected) in the picker, the event is picked up by the module script, which sets the relevant plot flag as true, and that plot event is then sent to the plot scipt which sets the other flag as false. &lt;br /&gt;
&lt;br /&gt;
(Note that if the party picker is turned off for a particular follower's recruit event, that follower will be placed in the active party regardless of the number of members, so ONLY do this for a follower who cannot be recruited when there are already 3 possible followers.)&lt;br /&gt;
&lt;br /&gt;
On recruitment, player_core rebuilds the character according to the specifications laid out in the GDAs, so no further scripting is required.&lt;br /&gt;
&lt;br /&gt;
=== Uses ===&lt;br /&gt;
&lt;br /&gt;
To recruit a party member, set the recruit flag from your plot table in the relevant dialogue. Adding or subtracting followers from the active party is automatically tracked via this machinery, and the plot flags can be interrogated in all your scripts and conversations if you need to know who is currently in the party and who is in camp.&lt;br /&gt;
&lt;br /&gt;
Defined flags can be added as you need them to the script and plot table but there is no point having flags that you will not use, so as with all Defined Flags this is an as-you-go decision, but quite easy to do.&lt;br /&gt;
&lt;br /&gt;
Hiring and firing of temporary party members at the start of a campaign (such as Ser Jory, or Jowan, or Soris, etc) can be handled by UT_HireFollower, and the party picker is not invoked (nor is the Party Camp an available destination).&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If you haven't done so already, create a simple debugging area for your module where you can dump the player, all followers and a couple of conversation dummies, and set up a dialogue in which you can invoke all required flags and conditions and see if they actually work as expected. (This setup can be used to test many other components as well.) Global machinery such as this can be painful to set up and get right (unless you are of an exceptionally methodical cast of mind), but it is worthwhile to ensure they are absolutely bullet-proof before you develop the specifics of your module.&lt;br /&gt;
&lt;br /&gt;
=== The KISS principle ===&lt;br /&gt;
&lt;br /&gt;
This is an &amp;quot;out-of-the-box&amp;quot; solution, and once set up is quite robust. If you want variants not catered for here, do NOT try to modify what you already have working.&lt;br /&gt;
&lt;br /&gt;
'''Use-case:''' You want a follower (example tag: dairren) to be recruited without a set specialisation and one level higher than the PC.&lt;br /&gt;
&lt;br /&gt;
Go to your packages gda and set the spec field to 0. In the character's plot table (you should have at least one for each follower) create a flag which we will call BLAH_BLAH. In the table's plot scipt insert the following very simple event handler:&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;dascript&amp;gt;case BLAH_BLAH:&lt;br /&gt;
         {&lt;br /&gt;
           SetCreatureProperty(oDairren, 38, 1.00); //awards the spec point; field from the properties gda&lt;br /&gt;
           int aLevel = GetLevel(oHero); //some simple arithmetic to find out the XP we need to award&lt;br /&gt;
           int bLevel = (aLevel+1);&lt;br /&gt;
           int aPoints = RW_GetXPNeededForLevel(aLevel);&lt;br /&gt;
           int bPoints = RW_GetXPNeededForLevel(bLevel);&lt;br /&gt;
           int targetPoints = (bPoints - aPoints);&lt;br /&gt;
           RewardXP(oDairren, targetPoints, FALSE, TRUE); //award the XP, and we're done&lt;br /&gt;
           break;&lt;br /&gt;
	 }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The flag can be set in the same conversation as the recruit flag, so long as it comes afterwards. This way you not only maintain the integrity of your core machinery, but keep exceptions/variations for particular characters where they belong -- with that character's plot tables and scripts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
{{Languages}}&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15172</id>
		<title>Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Follower_tutorial&amp;diff=15172"/>
				<updated>2010-12-04T16:59:00Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: addition of Alternative Approach section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Simple Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
Follow these steps to create a follower that&lt;br /&gt;
&lt;br /&gt;
- Levels up with a default package&lt;br /&gt;
&lt;br /&gt;
- Can be chosen from the party picker&lt;br /&gt;
&lt;br /&gt;
- Can gain XP&lt;br /&gt;
&lt;br /&gt;
This guide assumes you know how to create a creature and are comfortable with basic scripting.&lt;br /&gt;
&lt;br /&gt;
You should only use this simple method if you are sure there will be empty space in the active party when your follower is recruited.&lt;br /&gt;
&lt;br /&gt;
A more comprehensive approach when there are more than three potential party members is discussed in the FAQ below. It's worth taking the time to understand the basics first, though. &lt;br /&gt;
&lt;br /&gt;
=== Create the creature ===&lt;br /&gt;
&lt;br /&gt;
Create a creature to act as your follower.  Set its name, appearance, gender, head morph, conversation, inventory etc as you want them to behave in-game.&lt;br /&gt;
&lt;br /&gt;
Set an appropriate '''Tag''' (you'll be using it a lot).  I suggest &amp;quot;party_charname&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Make sure you choose a '''Class'''.  For most followers this should be Rogue, Warrior or Wizard.&lt;br /&gt;
&lt;br /&gt;
[[File:class.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Under Package/Scaling set:&lt;br /&gt;
&lt;br /&gt;
'''General Package Type''' to be '''Party Members'''&lt;br /&gt;
&lt;br /&gt;
'''Package''' to be an appropriate value (probably &amp;quot;Generic - Wizard&amp;quot; or similar)&lt;br /&gt;
&lt;br /&gt;
'''Package AI''' (there should only be one choice)&lt;br /&gt;
&lt;br /&gt;
'''Rank''' to be '''Player'''&lt;br /&gt;
&lt;br /&gt;
[[File:package.jpg]]&lt;br /&gt;
&lt;br /&gt;
Save and export your character as normal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Overlay char_stage ===&lt;br /&gt;
&lt;br /&gt;
In the official campaign, the party picker uses a special area called char_stage. Whether you're extending the official campaign or making a standalone campaign, there is a function that allows you to overlap the offical stage with your own, so that both stages are active simultaneously in game.&lt;br /&gt;
&lt;br /&gt;
In your resource palette, right-click char_stage under the Global folder and select Duplicate to make a copy of the stage with a new resource name, e.g. my_char_stage. In the resource properties, ensure that both Module and Owner Module are set to your module, and the folder of your choice.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:area_palette.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a new waypoint for your follower to appear on the party picker.  This waypoint '''must''' have a tag in the form of &amp;quot;char_&amp;quot; followed by the exact tag of your follower.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:char_stage.jpg]]&lt;br /&gt;
&lt;br /&gt;
In this example the tag of my follower is '''bc_party_miera''' so her waypoint tag must be '''char_bc_party_miera'''&lt;br /&gt;
&lt;br /&gt;
For a standalone module (such as in this example), put your waypoint wherever you please.  The illustrated one is directly on top of Morrigan's.  For an add-in to the main campaign, you should position your wp appropriately relative to the core party members.&lt;br /&gt;
&lt;br /&gt;
Save and export the area.&lt;br /&gt;
&lt;br /&gt;
Add the following to your module event script:&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
case EVENT_TYPE_MODULE_GETCHARSTAGE:&lt;br /&gt;
{&lt;br /&gt;
   // Overlay the existing stage with my stage&lt;br /&gt;
   // &amp;quot;my_char_stage&amp;quot; is the resource name of the overlay area&lt;br /&gt;
   // &amp;quot;partypicker&amp;quot; is the name of the default GDA&lt;br /&gt;
   SetPartyPickerStage(&amp;quot;my_char_stage&amp;quot;, &amp;quot;partypicker&amp;quot;);&lt;br /&gt;
   break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create m2DAs for the Party Picker ===&lt;br /&gt;
&lt;br /&gt;
You will need to create two Excel spreadsheets.&lt;br /&gt;
&lt;br /&gt;
The first should be named (both worksheet and file) '''partypicker_''' with a unique suffix.  In this example, my first spreadsheet is named partypicker_fofbc.xls with a worksheet name of partypicker_fofbc - the suffix being the acronym of my module.&lt;br /&gt;
&lt;br /&gt;
Set up your columns as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:partypickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' for your follower must be '''12 or higher'''.  11 is the highest value used in the base 2DA.  12 is fine for standalone modules, add-ins will probably want to use an arbitrarily high number to avoid potential conflicts.&lt;br /&gt;
&lt;br /&gt;
The '''Label''' should be the follower's name as you wish it to appear on the party picker.&lt;br /&gt;
&lt;br /&gt;
The '''Tag''' must be your follower's tag.&lt;br /&gt;
&lt;br /&gt;
All other values are non-functioning defaults and should be specified as in the image above unless you know explicitly what you're doing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION ANIMATIONS'''&lt;br /&gt;
 &lt;br /&gt;
Add Animation and Remove Animation are actually Id numbers of different animations, taken from anim_base.gda&lt;br /&gt;
&lt;br /&gt;
Enter and Exit version of animations are generally the best ones to use, altough one can try others. NOT ALL ANIMATIONS WILL WORK, since some require special conditions.&lt;br /&gt;
Here are some examples you can use:&lt;br /&gt;
&lt;br /&gt;
819 - talk cursing&lt;br /&gt;
&lt;br /&gt;
629 - reading a book (doesn't work, since it probably requires a book object)&lt;br /&gt;
&lt;br /&gt;
844 - hands behind back (848 and 849 are Enter and Exit versions respectfully)&lt;br /&gt;
&lt;br /&gt;
850 - chest pounding salute&lt;br /&gt;
&lt;br /&gt;
811 - fist pounding&lt;br /&gt;
&lt;br /&gt;
277 - dance&lt;br /&gt;
&lt;br /&gt;
247 - cast area spell&lt;br /&gt;
&lt;br /&gt;
500 - vfx cast&lt;br /&gt;
&lt;br /&gt;
600 - surprised&lt;br /&gt;
&lt;br /&gt;
603 - praying&lt;br /&gt;
&lt;br /&gt;
607 - head bow&lt;br /&gt;
&lt;br /&gt;
609 - standing at attention&lt;br /&gt;
&lt;br /&gt;
651,652 - crouch pray (Enter and exit)&lt;br /&gt;
&lt;br /&gt;
808 - point forward&lt;br /&gt;
&lt;br /&gt;
825 - nodding&lt;br /&gt;
&lt;br /&gt;
840 - hand chop or frustration&lt;br /&gt;
&lt;br /&gt;
905,906 - crouch (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
919,920 - sit on ground (enter, exit)&lt;br /&gt;
&lt;br /&gt;
965 - kneel down loop&lt;br /&gt;
&lt;br /&gt;
972 - wipe nose&lt;br /&gt;
&lt;br /&gt;
976,977 - squat (Enter, Exit)&lt;br /&gt;
&lt;br /&gt;
986 - wipe eyes&lt;br /&gt;
&lt;br /&gt;
998,999 - hands clasped (Enter, exit)&lt;br /&gt;
&lt;br /&gt;
3029 - inspect nails&lt;br /&gt;
&lt;br /&gt;
3031,3032 - playful (enter, exit)&lt;br /&gt;
&lt;br /&gt;
3054,3056 - slouch (enter, exit)&lt;br /&gt;
255 - in-place fly&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''NOTE - ON SELECTION VFX''' &lt;br /&gt;
&lt;br /&gt;
The VFX column is the ID of the vFX effect taken from vFx_base.gda. This one is a bit more tricky, since it also references the BlendTree value from the same file.&lt;br /&gt;
Find the ID of the spell effect and look for the BlendTreeName column (should the the 12th columun) and enter BOTH into the respective columns for your character in the partypicker file.&lt;br /&gt;
&lt;br /&gt;
Some examples:&lt;br /&gt;
&lt;br /&gt;
ID      ---      BLENDTREENAME      ---   EFFECT&lt;br /&gt;
&lt;br /&gt;
6039    ---     fxm_energy_up_p    ---    Lady of the Forest pillar of light&lt;br /&gt;
&lt;br /&gt;
6040    ---     fxm_power_in_p      ---   Branka - power in&lt;br /&gt;
&lt;br /&gt;
3054    ---     fxc_lotf_c          ---   Lady of the Forest - swirling leaves&lt;br /&gt;
&lt;br /&gt;
3009    ---     fxc_succubus_c     ---    Succubus crust&lt;br /&gt;
&lt;br /&gt;
1549    ---     fxa_hly_imp_c       ---   Holy Impact crust&lt;br /&gt;
&lt;br /&gt;
1076    ---     fxa_spi_aur_mht_c   ---   Spirit - Aura Might crust&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second spreadsheet should be named '''party_picker_''' (note middle underscore).  Once again append your unique suffix (in this example party_picker_fofbc.xls with party_picker_fofbc as its worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up your columns and data like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:party_pickerm2da.jpg]]&lt;br /&gt;
&lt;br /&gt;
'''ID''' and '''Tag''' should match what you did in the first spreadsheet.  Specify INVALID COLUMN for the third column.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're familiar with m2DAs, generate them from these files, copy them to your module's override directory, and skip to the next step.  Otherwise, read on:&lt;br /&gt;
&lt;br /&gt;
- Go to '''\Program Files\Dragon Age\tools\ResourceBuild\Processors''' (or wherever you installed Dragon Age)&lt;br /&gt;
&lt;br /&gt;
- Copy '''ExcelProcessor.exe''' from that folder to whichever folder has the excel sheets you just created.&lt;br /&gt;
&lt;br /&gt;
- Drag and drop your xls files onto ExcelProcessor.  This will create .gda files.&lt;br /&gt;
&lt;br /&gt;
- Copy these .gda files to your module's export directory (probably \Documents\Bioware\Dragon Age\AddIns\yourModule\module\override\toolsetexport).  Make sure they are included in your .dazip when the time comes to build your module.&lt;br /&gt;
&lt;br /&gt;
If you are an OpenOffice user and have trouble with ExcelProcessor, you can use [http://social.bioware.com/project/755/ GDApp] to directly create the 2DAs.  It rocks!&lt;br /&gt;
&lt;br /&gt;
=== Capture the EVENT_TYPE_PARTYMEMBER_ADDED Event ===&lt;br /&gt;
&lt;br /&gt;
Amusingly enough, the Party Picker does not actually add followers to the party.  However it raises an event that allows you to do so.  Your module script needs to capture this event and execute some code.&lt;br /&gt;
&lt;br /&gt;
The following example shows what to do with the event.  The full script would work as a module script for an add-in (assuming it didn't need to do anything else), but otherwise you'll have to incorporate the event into your own module script.  &lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);  //Allows the follower to gain XP&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);  //Adds follower to the active party&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE)''' is the key statement to add the follower to the active party.  You must have this.&lt;br /&gt;
&lt;br /&gt;
'''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0)''' is a bug-fix, as followers hired with UT_HireFollower() do not receive XP by default.  This statement fixes that, and I consider it best practice to keep it in this event to ensure it is always set.  You will not wish to do this if you want a follower that should not gain XP to be on the party picker.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that you do not need to intercept the corresponding event for a party member being removed - the party picker handles spawning/despawning, and thus will successfully remove members.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Remember to save and export your module script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you're not sure how to set a module script, go to '''File''' then '''Manage Modules,''' select your module and click '''Properties.'''  The module script is in the General category, as seen below:&lt;br /&gt;
&lt;br /&gt;
[[File:module_script.jpg]]&lt;br /&gt;
&lt;br /&gt;
You can set this to any script you've created.  See [[Scripting tutorial]] and [[Character generation]] for more background and some simple examples of event-handling scripts.  In general, you will want to make sure standalone module scripts pass events through to module_core (as in the [[Character generation]] examples) and add-in scripts do not (as in the example above).&lt;br /&gt;
&lt;br /&gt;
=== Create Your Hiring Script ===&lt;br /&gt;
&lt;br /&gt;
Now all that remains is to actually hire the follower :)&lt;br /&gt;
&lt;br /&gt;
Create a script to handle the hiring (which will most likely be fired from a conversation).  The script is quite simple:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
        object oFollower = GetObjectByTag(&amp;quot;bc_party_miera&amp;quot;); //Use CreateObject() if the creature isn't present in the module yet&lt;br /&gt;
&lt;br /&gt;
        UT_HireFollower(oFollower);   //Hires the follower&lt;br /&gt;
&lt;br /&gt;
        SetPartyPickerGUIStatus(2);&lt;br /&gt;
&lt;br /&gt;
        ShowPartyPickerGUI();  //Shows the Party Picker; necessary for the follower to gain XP&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use your own follower's tag and not the example one :)&lt;br /&gt;
&lt;br /&gt;
This script fires the party picker after hiring the follower.  That is absolutely necessary via this method, as we have put the XP fix onto an event fired by the party picker.  You cannot put the XP fix into this script, it must be called from a later one (the bug is caused by an errant call to an event in player_core, which will be executed AFTER this script).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way to use this script is directly from conversation, putting it as an action on a line of dialogue where the PC invites the follower to join them.  If you're not sure how to associate a script with a dialogue line, see the following image:&lt;br /&gt;
&lt;br /&gt;
[[File:hire_conv.jpg]]&lt;br /&gt;
&lt;br /&gt;
Create your dialogue as normal, select the line you want to fire the script, and click the '''Plots and Scripting''' tab.  Use the '''Script''' file chooser in the Action section to browse to the script you created.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If everything worked, you should see something like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:picker_success.jpg|thumb|200px|center]]&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow these steps to have full control over the creation of your follower, with options such as:&lt;br /&gt;
&lt;br /&gt;
- Unique level-up template&lt;br /&gt;
&lt;br /&gt;
- Class and specialisation chosen via script&lt;br /&gt;
&lt;br /&gt;
- Any starting state&lt;br /&gt;
&lt;br /&gt;
- Level higher than the PC&lt;br /&gt;
&lt;br /&gt;
- Starts with a specialisation point rather than a specific specialisation&lt;br /&gt;
&lt;br /&gt;
- Set plot flags in the call to the hire script&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Prepare Creature, char_stage and Party Picker m2DAs ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Follow the same steps to create your follower creature, char_stage and Party Picker m2DAs as above.&lt;br /&gt;
&lt;br /&gt;
=== Create Party Plot ===&lt;br /&gt;
&lt;br /&gt;
While not necessary, it's very helpful to have plot flags set when a follower is hired or joins/leaves the active party.  This makes conversation interjections and the like very easy.&lt;br /&gt;
&lt;br /&gt;
Create a plot with appropriate flags.  There's no real need to associate journal text with them:&lt;br /&gt;
&lt;br /&gt;
[[File:follower_plot.jpg]]&lt;br /&gt;
&lt;br /&gt;
See FAQ for an alternative approach to plots when there are more than three potential party members.&lt;br /&gt;
&lt;br /&gt;
=== Add Plot Flags to Party Picker Event Intercept ===&lt;br /&gt;
&lt;br /&gt;
We then update our module script to make use of that plot, like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //make sure you include your own plot, not mine&lt;br /&gt;
&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    event ev = GetCurrentEvent();&lt;br /&gt;
    int nEventType = GetEventType(ev);&lt;br /&gt;
    switch(nEventType)&lt;br /&gt;
    {&lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));   //Ensures follower appears at PC's location.&lt;br /&gt;
            &lt;br /&gt;
            if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               //You must explicitly test for your follower's tag.&lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, TRUE);     //Make sure you use your own flags!&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            break;&lt;br /&gt;
        }  &lt;br /&gt;
        &lt;br /&gt;
        case EVENT_TYPE_PARTYMEMBER_DROPPED:                    &lt;br /&gt;
        {&lt;br /&gt;
              object oFollower = GetEventObject(ev, 0); &lt;br /&gt;
              &lt;br /&gt;
              if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) { &lt;br /&gt;
                WR_SetPlotFlag(PLT_BC_CREATE_PARTY, PARTY_MIERA_IN_PARTY, FALSE);     //As above, but set false.&lt;br /&gt;
              }&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create a Level Up Template ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can skip this step if you're content to use one of the generic Rogue, Wizard or Warrior templates, but I don't recommend it.  Making a template that suits your character is easy and will almost always be better for the player than a generic one that spends points poorly.&lt;br /&gt;
&lt;br /&gt;
Go to \Program Files\Dragon Age\tools\Source\2DA (or wherever you installed Dragon Age).&lt;br /&gt;
&lt;br /&gt;
You should see a number of excel sheets of the form '''ALCharacter.xls''' (such as ALAlistair.xls, ALLeliana.xls, ALRogue_Default.xls etc).  Open the one closest to your character (ie Morrigan or Wynne for a wizard, Leliana or Zevran for a rogue).  Save a copy as '''ALYourcharacter.xls''' in whatever directory you're using to create your 2DAs, remembering to rename the worksheet '''ALYourcharacter''' (in this example, ALMiera.xls with ALMiera as its worksheet).&lt;br /&gt;
&lt;br /&gt;
It should look something like this:&lt;br /&gt;
&lt;br /&gt;
[[File:ALtable.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns B''' and '''C''' are the talents/spells available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
'''Columns F''' and '''G''' are the skills available to this character.  Do not change them.&lt;br /&gt;
&lt;br /&gt;
We will edit the remaining columns like so:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Stat Weights ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The stat weights in '''column J''' determine how the follower will spend their attribute points, in a rough ratio.  So if Dexterity is set to 1.5 and Intelligence to 1, you should expect to see 3 points of Dex for every 2 points of Cunning in-game (note Intelligence is the label used in the toolset for Cunning).&lt;br /&gt;
&lt;br /&gt;
Simply change the values in J to reflect how you'd like the character to spend their points.  In this example we're creating a wizard, so we're not going to mess around:&lt;br /&gt;
&lt;br /&gt;
[[File:miera_stat_weights.jpg]]&lt;br /&gt;
&lt;br /&gt;
This character will only raise magic.  I set the value to 5 rather than something like 1 to provide room underneath for the other stats while still overwhelmingly favouring magic, but in practice I only really ever want that one stat. &lt;br /&gt;
&lt;br /&gt;
In a note left on this column in the existing templates, Bioware's Georg Zoeller writes, &amp;quot;This is the weight of each attribute (row id links into properties.xls.id). 1.0 means 'try to keep this attribute level' (spend 1 point per level). 0.5 means 'try to spend 1 point every two levels' and so on.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The default Mage, Rogue and Warrior templates include '''column L''' labeled &amp;quot;AttInit.&amp;quot; Editing these values seems to have no effect on followers set to use these templates.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting Talent and Skill Priorities ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Columns D''' and '''E''' are the talents/spells that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
'''Columns H''' and '''I''' are the skills that the character will buy, in preference order from top to bottom.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To change these, just copy the appropriate two cells from columns B&amp;amp;C or F&amp;amp;G over the ones you want to replace.&lt;br /&gt;
&lt;br /&gt;
For example, here we're copying Morrigan's template.  Morrigan has Spider Shape high in her preferences, which we do not want.&lt;br /&gt;
&lt;br /&gt;
[[File:AlMori_talent_pref.jpg]]&lt;br /&gt;
&lt;br /&gt;
We decide we'd prefer Flame Blast, so we find it in columns B&amp;amp;C and copy both cells:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_copy.jpg]]&lt;br /&gt;
&lt;br /&gt;
Then we select the cells we want to replace in columns D&amp;amp;E and paste over them:&lt;br /&gt;
&lt;br /&gt;
[[File:ALMori_paste.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Continue this process until your priorities list for both skills and talents/spells is exactly as you want it.  Make sure you have at least as many priorities as the core follower you're copying - points that cannot be spent according to these priorities have a habit of vanishing.&lt;br /&gt;
&lt;br /&gt;
If you used any abilities from a specialisation, make sure you remember to set that specialisation with the function we'll introduce later.  The autolevel scripts will add specialisation abilities to a character regardless of whether they have that spec or not.&lt;br /&gt;
&lt;br /&gt;
==== Create a M2DA_base_ m2DA ====&lt;br /&gt;
&lt;br /&gt;
Dragon Age will need to know where to find your autolevel template.  We tell it by extending M2DA_base.gda&lt;br /&gt;
&lt;br /&gt;
Create a spreadsheet with the name and worksheet name in the form '''M2DA_base_''' with your unique suffix (in this example, M2DA_base_fofbc.xls with M2DA_base_fofbc as a worksheet).&lt;br /&gt;
&lt;br /&gt;
Set up its columns and data like so (note I used GDApp because Open Office wasn't cooperating for this one!):&lt;br /&gt;
&lt;br /&gt;
[[File:m2da_base_fofbc.jpg]]&lt;br /&gt;
&lt;br /&gt;
The '''ID''' should be very high to avoid conflicts.  I've arbitrarily chosen 50,000+ here.  Carefully note the ID you've chosen for your character, you will need it later.&lt;br /&gt;
&lt;br /&gt;
Set the '''Label''' and '''Worksheet''' to be the name of your autolevel template worksheet (ALCharactername if you've been following this).&lt;br /&gt;
&lt;br /&gt;
Set the '''PackageIDForAI''' to be 0, it shouldn't be needed for followers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When you're done, use ExcelProcessor to make GDAs of both spreadsheets and copy them to your module's export folder.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
FOR AUTOLEVEL TO WORK AFTER RECRUITING:&lt;br /&gt;
&lt;br /&gt;
Look in packages.xls. &lt;br /&gt;
There is a column called LevelupTable. That links to a corresponding AL* table. For instance,  row 81 is for Leliana. Her LevelupTable value is 258. If you look that up in 2DA_base, you'll see it links to ALLeliana.&lt;br /&gt;
(alternatively, you could try packages_base.gda)&lt;br /&gt;
&lt;br /&gt;
=== Create a New Hire Function Include ===&lt;br /&gt;
&lt;br /&gt;
Many vital steps of follower addition happen inside an event in player_core.  Followers tend to be extremely buggy (no skill tree, for example) if this event does not fire.&lt;br /&gt;
&lt;br /&gt;
However, that event is not very flexible.  In order to control it to our requirements, we need to replicate its functionality inside our own script.  This is probably much safer than messing with player_core directly!&lt;br /&gt;
&lt;br /&gt;
Create a new script file, naming it something like '''hireCustomFollower_h'''.  We will be including this wherever we want to hire a follower.&lt;br /&gt;
&lt;br /&gt;
Paste in the following script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;sys_chargen_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;approval_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_autolevelup_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/*  Jye Nicolson 5-Jan-2010&lt;br /&gt;
This function set duplicates the full functionality chain of UT_HireFollower, with the following exceptions:&lt;br /&gt;
&lt;br /&gt;
-  Followers can gain XP&lt;br /&gt;
-  Autolevel status can be set (default off)&lt;br /&gt;
-  Followers can be set to any starting state (default Available) and will still be properly initalised and added to the party pool&lt;br /&gt;
-  Autolevel tables for non-core followers can be explicitly set.&lt;br /&gt;
-  Class and Specialisation can be chosen via script&lt;br /&gt;
-  Followers without specialisations are granted a spec point by default.&lt;br /&gt;
&lt;br /&gt;
It should only ever be called once each for characters you intend to be full followers.&lt;br /&gt;
Much of the protective code handling summoned creatures etc. in player_core is not present here.&lt;br /&gt;
&lt;br /&gt;
Calling the function:&lt;br /&gt;
&lt;br /&gt;
Simple:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR);&lt;br /&gt;
&lt;br /&gt;
Change the class to CLASS_WIZARD or CLASS_ROGUE as appropriate.  &lt;br /&gt;
This will hire your follower and make them available.  &lt;br /&gt;
They will auto level up with a default package, and receive a free spec point.&lt;br /&gt;
&lt;br /&gt;
Best Practice:&lt;br /&gt;
&lt;br /&gt;
hireCustomFollower(oFollower, CLASS_WARRIOR, PLT_YOUR_PARTY_PLOT, YOUR_FOLLOWER_JOINED_FLAG, ABILITY_TALENT_HIDDEN_CHAMPION);&lt;br /&gt;
&lt;br /&gt;
Where the plot and flag are those for your module (remember to create the plot and include it on the calling script), and ABILITY_TALENT_HIDDEN etc is the desired spec.&lt;br /&gt;
&lt;br /&gt;
You should also have a custom ALTable set up.  &lt;br /&gt;
See wiki for details, and remember to edit it in to GetCustomFollowerALTable below or pass it directly as an argument to hireCustomFollower.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
Full argument list:&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower (&lt;br /&gt;
        object oFollower,   //Pass your follower object, mandatory&lt;br /&gt;
        &lt;br /&gt;
        int nForceClass,    //Pass a Class constant here, usually CLASS_ROGUE, CLASS_WARRIOR, CLASS_WIZARD.  Mandatory due to a bug.&lt;br /&gt;
        &lt;br /&gt;
        string sPlot = &amp;quot;&amp;quot;,   //It's recommended you have a plot flag to be set when the follower joins.  Pass the plot constant here.  Remember to #include in calling script&lt;br /&gt;
        &lt;br /&gt;
        int nPlotFlag = &amp;quot;&amp;quot;,  //And then pass the flag constant.  Will be set to TRUE if available.&lt;br /&gt;
        &lt;br /&gt;
        int nForceSpec = 0,  //This is the ID of the Specialisation you want.  Note they are NOT classes, but abilities.  The full list is:&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_ARCANE_WARRIOR, ABILITY_SPELL_HIDDEN_BLOODMAGE, ABILITY_SPELL_HIDDEN_SHAPESHIFTER, ABILITY_SPELL_HIDDEN_SPIRIT_HEALER&lt;br /&gt;
                             //ABILITY_SPELL_HIDDEN_BARD, ABILITY_TALENT_HIDDEN_ASSASSIN, ABILITY_TALENT_HIDDEN_DUELIST, ABILITY_TALENT_HIDDEN_RANGER&lt;br /&gt;
                             //ABILITY_TALENT_HIDDEN_BERSERKER, ABILITY_TALENT_HIDDEN_CHAMPION, ABILITY_TALENT_HIDDEN_REAVER, ABILITY_TALENT_HIDDEN_TEMPLAR&lt;br /&gt;
                             //I recommended forcing a spec, particularly if your ALTable includes abilities from one.&lt;br /&gt;
        &lt;br /&gt;
        int nALTable = 0,    //This is the ID of an ALTable from 2DA_base.GDA or your module's m2DA_base_*.GDA  I recommended the latter, but you can edit that into GetCustomFollowerALTable below rather than passing it.&lt;br /&gt;
        &lt;br /&gt;
        int bInvokePicker = FALSE,  //Sets whether the party picker should be opened on hiring.  I think it's cleaner to call the picker outside this script, particularly if you have multiple hires at once.&lt;br /&gt;
        &lt;br /&gt;
        int nInitialState = FOLLOWER_STATE_AVAILABLE,  //This sets whether the follower joins the active party or not.  Options are:&lt;br /&gt;
                                                       //FOLLOWER_STATE_ACTIVE (put them in the active party)&lt;br /&gt;
                                                       //FOLLOWER_STATE_LOCKEDACTIVE (force them into the active party and keep them there, remember to change this later.&lt;br /&gt;
                                                       //FOLLOWER_STATE_AVAILABLE (make them available on the party picker (if you've set it up for them), but not in the active party)&lt;br /&gt;
                                                       //Plus some others you're unlikely to need at this time.  Defaults to AVAILABLE because having 4+ active followers is screwy.&lt;br /&gt;
                                                       &lt;br /&gt;
        string sCurrPlot = &amp;quot;&amp;quot;,  //If you set FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE, the script will check to see if you passed this.&lt;br /&gt;
                                //It is recommended that you have a plot flag set for a given follower being in the active party, this makes conversation interjection etc. much easier.&lt;br /&gt;
&lt;br /&gt;
        int nCurrPlotFlag = 0,  //This flag will be set if FOLLOWER_STATE_ACTIVE or FOLLOWER_STATE_LOCKEDACTIVE are true&lt;br /&gt;
                                //AND sCurrPlot has a value AND nCurrPlotFlag is &amp;gt; 0.  &lt;br /&gt;
                                //ie if you added someone to the active party and have a plot flag to cope with it.&lt;br /&gt;
&lt;br /&gt;
        int nAutolevel = 0,     //Sets the Autolevel flag on the character sheet.  0 is off, 1 is on, 2 forces it on and removes it so the player can't turn it off.&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        bFreeSpecPoint = TRUE,  //This grants a specialisation point to the follower if they do not have a specialisation.  &lt;br /&gt;
                                //It's important to set this false for classes that do not have specs, such as CLASS_DOG.&lt;br /&gt;
                                &lt;br /&gt;
        int nTargetLevel = 0,   //If you want a specific level, set this.  Generally not worthwhile unless you set it higher than the player, since they'll just get XP from the party picker anyway.&lt;br /&gt;
        &lt;br /&gt;
        int nMinLevel = 0       //Set this if there's a specific level you don't want the follower to go below.  Probably only useful if the PC might be very low level but not necessarily so. &lt;br /&gt;
        &lt;br /&gt;
        )&lt;br /&gt;
*/       &lt;br /&gt;
/* GetCustomFollowerALTable()  &lt;br /&gt;
This function is where you put your custom table assignments.&lt;br /&gt;
&lt;br /&gt;
You should explicitly test for the tag of your follower (not mine!) and assign a value to nTable from your m2DA extension to M2DA_base &lt;br /&gt;
&lt;br /&gt;
See wiki for details on how to do this, or ignore it to get the default Warrior/Rogue/Wizard AL tables.&lt;br /&gt;
&lt;br /&gt;
NOTE: you MUST explicitly set a table for non-Warrior/Rogue/Wizards, eg dogs.  Use TABLE_AL_DOG for a default Mabari.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// This just cleans up the main function a little&lt;br /&gt;
&lt;br /&gt;
int GetCustomFollowerTargetLevel(object oFollower, object oHero, int nPackage, int nMinLevel = 0) {&lt;br /&gt;
            int nPlayerLevel = GetLevel(oHero);&lt;br /&gt;
            int nTargetLevel = 0;&lt;br /&gt;
&lt;br /&gt;
            if((nPlayerLevel &amp;gt;= 13) || (nPlayerLevel == 1) || (!_UT_GetIsPlotFollower(oFollower))) {&lt;br /&gt;
               nTargetLevel = nPlayerLevel;&lt;br /&gt;
            } else {&lt;br /&gt;
               nTargetLevel = nPlayerLevel + 1;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (nMinLevel == 0) {  //If nMinLevel is not specified, checks package 2DA for a value&lt;br /&gt;
              nMinLevel = GetM2DAInt(TABLE_PACKAGES, &amp;quot;MinLevel&amp;quot;, nPackage);&lt;br /&gt;
             }&lt;br /&gt;
            if(nMinLevel &amp;gt; 0 &amp;amp;&amp;amp; nMinLevel &amp;gt; nTargetLevel) {&lt;br /&gt;
               nTargetLevel = nMinLevel;&lt;br /&gt;
            }          &lt;br /&gt;
            &lt;br /&gt;
            return nTargetLevel;&lt;br /&gt;
    &lt;br /&gt;
}   &lt;br /&gt;
&lt;br /&gt;
// Moving this black box out :)  I don't really understand it, but it should function if you have tactics set up in a package.&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerTactics(object oFollower, int nPackage) {&lt;br /&gt;
         int nTableID = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerTacticsTable&amp;quot;, nPackage);&lt;br /&gt;
         if (nTableID != -1)&lt;br /&gt;
            {&lt;br /&gt;
             int nRows = GetM2DARows(nTableID);&lt;br /&gt;
             int nMaxTactics = GetNumTactics(oFollower);&lt;br /&gt;
&lt;br /&gt;
             int nTacticsEntry = 1;&lt;br /&gt;
             int i;&lt;br /&gt;
             for (i = 1; i &amp;lt;= nRows &amp;amp;&amp;amp; nTacticsEntry &amp;lt;= nMaxTactics; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                        int bAddEntry = FALSE;&lt;br /&gt;
                        int nTargetType = GetM2DAInt(nTableID, &amp;quot;TargetType&amp;quot;, i);&lt;br /&gt;
                        int nCondition = GetM2DAInt(nTableID, &amp;quot;Condition&amp;quot;, i);&lt;br /&gt;
                        int nCommandType = GetM2DAInt(nTableID, &amp;quot;Command&amp;quot;, i);&lt;br /&gt;
                        int nCommandParam = GetM2DAInt(nTableID, &amp;quot;SubCommand&amp;quot;, i);&lt;br /&gt;
&lt;br /&gt;
                        int nUseType = GetM2DAInt(TABLE_COMMAND_TYPES, &amp;quot;UseType&amp;quot;, nCommandType);&lt;br /&gt;
                        if (nUseType == 0)&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = TRUE;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            bAddEntry = HasAbility(oFollower, nCommandParam);&lt;br /&gt;
                        }&lt;br /&gt;
&lt;br /&gt;
                        if (bAddEntry)&lt;br /&gt;
                        {&lt;br /&gt;
                            SetTacticEntry(oFollower, nTacticsEntry, TRUE, nTargetType, nCondition, nCommandType, nCommandParam);&lt;br /&gt;
                            ++nTacticsEntry;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
/* InitCustomFollowerSpec:&lt;br /&gt;
&lt;br /&gt;
This function tries to set the forced Specialisation.  If there is none, it checks the package for one.  &lt;br /&gt;
&lt;br /&gt;
If there isn't either of those, it grants a free spec point if bFreeSpecPoint is true.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void InitCustomFollowerSpec(object oFollower, int nPackage, int nForceSpec, int bFreeSpecPoint) {&lt;br /&gt;
    // Find specialization, and optionally add a spec point if none is found.&lt;br /&gt;
&lt;br /&gt;
        if (nForceSpec == 0) {&lt;br /&gt;
    &lt;br /&gt;
        int nSpecAbility = GetM2DAInt(TABLE_PACKAGES, &amp;quot;switch1_class&amp;quot;, nPackage); // followers can have only 1 advanced class&lt;br /&gt;
         if(nSpecAbility &amp;gt; 0)&lt;br /&gt;
         {&lt;br /&gt;
          AddAbility(oFollower, nSpecAbility);&lt;br /&gt;
         } else {&lt;br /&gt;
             if (bFreeSpecPoint) {&lt;br /&gt;
                 SetCreatureProperty(oFollower, 38, 1.00);&lt;br /&gt;
             }&lt;br /&gt;
         }                    &lt;br /&gt;
        &lt;br /&gt;
        } else {&lt;br /&gt;
         &lt;br /&gt;
             AddAbility(oFollower, nForceSpec);&lt;br /&gt;
            &lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* hireCustomFollower()  (See doco at top of page)&lt;br /&gt;
&lt;br /&gt;
I strongly suggest you reorder the parameters if you're adding many followers with advanced options.&lt;br /&gt;
&lt;br /&gt;
Feel free to leave them alone if you only want to set class, plot, spec or don't mind long declarations.&lt;br /&gt;
&lt;br /&gt;
Note nForceClass is currently compulsory due to flakiness with GetCreatureCoreClass()&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void hireCustomFollower(object oFollower, int nForceClass, string sPlot = &amp;quot;&amp;quot;, int nPlotFlag = 0, int nForceSpec = 0, &lt;br /&gt;
int nALTable = 0, int bInvokePicker = FALSE, int nInitialState = FOLLOWER_STATE_AVAILABLE, string sCurrPlot = &amp;quot;&amp;quot;, &lt;br /&gt;
int nCurrPlotFlag = 0, int nAutolevel = 0, int bFreeSpecPoint = TRUE, int nTargetLevel = 0, int nMinLevel = 0) &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
        object oHero = GetHero();&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN BASIC FOLLOWER JOIN BLOCK   ###################&lt;br /&gt;
&lt;br /&gt;
        This loosely replicates WR_SetFollowerState.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */    &lt;br /&gt;
        &lt;br /&gt;
        if (nForceClass == 0) {&lt;br /&gt;
            nForceClass = GetCreatureCoreClass(oFollower);           //This is not working.  Hence nForceClass mandatory.&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
        SetGroupId(oFollower, GetGroupId(oHero));      //Puts the follower in the pc's Group.&lt;br /&gt;
        SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);  //This makes them act like a player.&lt;br /&gt;
        SetFollowerState(oFollower, nInitialState);  //This sets whether they are available, in the active party etc.&lt;br /&gt;
&lt;br /&gt;
        /* #################  END BASIC FOLLOWER JOIN BLOCK ##################### */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        /* #################  BEGIN PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION #################&lt;br /&gt;
         This replicates the EVENT_TYPE_PARTY_MEMBER_HIRED handler from player_core, stripped down for simplicity and allowing our custom options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        */&lt;br /&gt;
&lt;br /&gt;
        Chargen_EnableTacticsPresets(oFollower);    //I assume this is important.&lt;br /&gt;
        &lt;br /&gt;
        SetLocalInt(oFollower, FOLLOWER_SCALED, 1);  //This should prevent the follower being rescaled by player_core or what have you&lt;br /&gt;
        &lt;br /&gt;
        int nPackage = GetPackage(oFollower);  //Gets the package, which will be used to find a number of 2DA IDs.&lt;br /&gt;
        int nPackageClass = GetM2DAInt(TABLE_PACKAGES, &amp;quot;StartingClass&amp;quot;, nPackage);  //I don't think this is used, even by player_core&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        // set behavior according to package&lt;br /&gt;
        int nBehavior = GetM2DAInt(TABLE_PACKAGES, &amp;quot;FollowerBehavior&amp;quot;, nPackage);&lt;br /&gt;
&lt;br /&gt;
        if(nBehavior &amp;gt;= 0) {&lt;br /&gt;
            SetAIBehavior(oFollower, nBehavior);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        Chargen_InitializeCharacter(oFollower);      //We initialise the follower and choose race/class.&lt;br /&gt;
        &lt;br /&gt;
        Chargen_SelectRace(oFollower,GetCreatureRacialType(oFollower));&lt;br /&gt;
        Chargen_SelectCoreClass(oFollower,nForceClass);        &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
         if (nTargetLevel == 0) {   //This block picks a target level if not specified&lt;br /&gt;
            &lt;br /&gt;
              nTargetLevel = GetCustomFollowerTargetLevel(oFollower, oHero, nPackage, nMinLevel);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         int nXp = RW_GetXPNeededForLevel(Max(nTargetLevel, 1));      //Here is where the XP is calculated and rewarded&lt;br /&gt;
         RewardXP(oFollower, nXp, FALSE, FALSE);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // add hidden approval talents - (JN: I don't know how to set these yet, but when I figure it out this should make it work)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         int nIndex = Approval_GetFollowerIndex(oFollower);&lt;br /&gt;
         Approval_AddFollowerBonusAbility(nIndex, 0);&lt;br /&gt;
        &lt;br /&gt;
          //Handle Specialisation&lt;br /&gt;
          InitCustomFollowerSpec(oFollower, nPackage, nForceSpec, bFreeSpecPoint);&lt;br /&gt;
&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
         // This spends all available attribute and stat points on the&lt;br /&gt;
         // creature according to the levelup table.  (JN:  this replicates AL_DoAutoLevelUp but with our choice of table)&lt;br /&gt;
         // -------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
         if (nALTable == 0) {&lt;br /&gt;
            nALTable = GetCustomFollowerALTable(oFollower);&lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         AL_SpendAttributePoints(oFollower, nALTable, FALSE);&lt;br /&gt;
         AL_SpendSkillPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
         AL_SpendSpecializationPoints(oFollower, nALTable);&lt;br /&gt;
         AL_SpendTalentSpellPoints(oFollower, nALTable, TRUE);&lt;br /&gt;
&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        // Update various UIs&lt;br /&gt;
        // -------------------------------------------------------------------------&lt;br /&gt;
        Chargen_SetNumTactics(oFollower);&lt;br /&gt;
        SetCanLevelUp(oFollower,Chargen_HasPointsToSpend(oFollower));&lt;br /&gt;
&lt;br /&gt;
        // load tactics&lt;br /&gt;
         InitCustomFollowerTactics(oFollower, nPackage);&lt;br /&gt;
&lt;br /&gt;
         /* #################  END PLAYER_CORE EVENT_TYPE_PARTY_MEMBER_HIRED EMULATION ################# */     &lt;br /&gt;
             &lt;br /&gt;
         &lt;br /&gt;
         SetAutoLevelUp(oFollower, nAutolevel);         //This is the autolevel flag on the character sheet.&lt;br /&gt;
         &lt;br /&gt;
         //Set plot flags&lt;br /&gt;
         &lt;br /&gt;
         if (!((sPlot == &amp;quot;&amp;quot;) || (nPlotFlag == 0))) {           //Joined Party&lt;br /&gt;
            WR_SetPlotFlag(sPlot, nPlotFlag, TRUE);   &lt;br /&gt;
         }&lt;br /&gt;
&lt;br /&gt;
         if ((nInitialState == FOLLOWER_STATE_ACTIVE) || (nInitialState == FOLLOWER_STATE_LOCKEDACTIVE)) {&lt;br /&gt;
            if (!((sCurrPlot == &amp;quot;&amp;quot;) || (nCurrPlotFlag == 0))) {&lt;br /&gt;
                WR_SetPlotFlag(sCurrPlot, nCurrPlotFlag, TRUE);   //Currently in Party&lt;br /&gt;
            }&lt;br /&gt;
         }&lt;br /&gt;
                     &lt;br /&gt;
        // Invoke picker if requested.&lt;br /&gt;
&lt;br /&gt;
        if (bInvokePicker) {&lt;br /&gt;
             SetPartyPickerGUIStatus(2);&lt;br /&gt;
             ShowPartyPickerGUI();&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Yeah, I know.  It can't really be any smaller.  Feel free to modify it if you're confident with scripting.&lt;br /&gt;
==== Add Your Custom Autolevel Template to GetCustomFollowerALTable() ====&lt;br /&gt;
While you can pass the ID you made for your autolevel template to that monster function as an argument, it's better to have them all in one place if you have multiple followers.&lt;br /&gt;
&lt;br /&gt;
GetCustomFollowerALTable() is the first function in our include, and you can add an explicit if test for your follower there to assign the correct table id (the one from your M2DA_base_ m2DA).  There is a function very much like it in sys_autolevel_h.nss for the core followers, so we'll copy Bioware's practice.&lt;br /&gt;
&lt;br /&gt;
Let's take a look at the function by itself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
int GetCustomFollowerALTable(object oFollower) {&lt;br /&gt;
    int nTable = _GetTableToUseForAL(oFollower);&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_miera&amp;quot;) {               &lt;br /&gt;
        nTable = 50143;   &lt;br /&gt;
    }   &lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_jysavin&amp;quot;) {&lt;br /&gt;
        nTable = 50144;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_geldual&amp;quot;) {&lt;br /&gt;
        nTable = 50145;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (GetTag(oFollower) == &amp;quot;bc_party_braghon&amp;quot;) {&lt;br /&gt;
        nTable = 50146;   &lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return nTable;    &lt;br /&gt;
    &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So we have a test for each follower tag from my module, matching up to an ID which is assigned to nTable.  All you need to do is change a tag from my follower to yours, and my ID to the correct one from your M2DA_base_* m2DA.  Then you should delete the rest of the example if statements :)&lt;br /&gt;
&lt;br /&gt;
Save and export the script.  Ignore the compiler error about lack of main();&lt;br /&gt;
&lt;br /&gt;
=== Include Function In Your Hire Script and Call It ===&lt;br /&gt;
&lt;br /&gt;
So instead of a hire script that calls UT_HireFollower(), we want one that includes our shiny new function and calls it.&lt;br /&gt;
&lt;br /&gt;
Take a look at the following example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;&lt;br /&gt;
#include &amp;quot;plt_bc_create_party&amp;quot;   //Make sure you include your party handling plot&lt;br /&gt;
#include &amp;quot;hireCustomFollower_h&amp;quot;  // And include the function script - which will in turn include a bunch of stuff&lt;br /&gt;
&lt;br /&gt;
void main() {&lt;br /&gt;
&lt;br /&gt;
                    //Initialising my objects, not super-relevant to the example &lt;br /&gt;
                     &lt;br /&gt;
                    object oHero = GetHero();&lt;br /&gt;
                    object oMiera = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_miera.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oJysavin = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_jysavin.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oBraghon = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_braghon.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
                    object oSpider = CreateObject(OBJECT_TYPE_CREATURE, R&amp;quot;bc_party_geldual.utc&amp;quot;, GetLocation(oHero));&lt;br /&gt;
&lt;br /&gt;
                    //Simplest hire call - adds to the party as a wizard.  Class is currently compulsory due to a bug.&lt;br /&gt;
                    hireCustomFollower(oMiera, CLASS_WIZARD);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party and set joining plot flags&lt;br /&gt;
                    hireCustomFollower(oJysavin, CLASS_WARRIOR, PLT_BC_CREATE_PARTY, PARTY_JYSAVIN_JOINED);&lt;br /&gt;
&lt;br /&gt;
                    //Add to the party, set plot flags, force a specialisation&lt;br /&gt;
                    hireCustomFollower(oBraghon, CLASS_ROGUE, PLT_BC_CREATE_PARTY, PARTY_BRAGHON_JOINED, ABILITY_TALENT_HIDDEN_ASSASSIN);&lt;br /&gt;
&lt;br /&gt;
                    //More complex example - Follower added as a unique class (Dog), not granted a specialisation or spec point.  &lt;br /&gt;
                    //Note unique classes must have an ALTable passed here or specified in GetCustomFollowerALTable() or they won't work&lt;br /&gt;
                    hireCustomFollower(oSpider, CLASS_DOG, PLT_BC_CREATE_PARTY, PARTY_GELDUAL_JOINED, 0, 0, FALSE, FOLLOWER_STATE_AVAILABLE, &amp;quot;&amp;quot;, 0, 0, FALSE);&lt;br /&gt;
                   &lt;br /&gt;
                    //Show the party picker to let the player choose from their new companions!&lt;br /&gt;
                    SetPartyPickerGUIStatus(2);&lt;br /&gt;
                    ShowPartyPickerGUI();                                                                                                                    &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The example shows several of the more simple ways of invoking the function.  Check the comments at the start of the function for a full list of arguments.&lt;br /&gt;
&lt;br /&gt;
I would suggest best practice for most followers would be to call as follows:&lt;br /&gt;
&lt;br /&gt;
'''hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION)'''&lt;br /&gt;
&lt;br /&gt;
This will safely set the follower up as the desired class and specialisation (doubly important if there are spec abilities in their ALTable) while setting your plot flag for them being in the party.  hireCustomFollower(oFollower, CLASS, PLOT, PLOT_FLAG, SPECIALISATION, 0, TRUE) will do the same while invoking the Party Picker automatically.&lt;br /&gt;
&lt;br /&gt;
Note that the specialisations are abilities and not classes - you'll find them as ABILITY_HIDDEN_ constants.&lt;br /&gt;
&lt;br /&gt;
If it's all worked, you should find you can now add followers with a lot more flexibility!&lt;br /&gt;
&lt;br /&gt;
[[File:picker_advanced.jpg|thumb|500px|center]]&lt;br /&gt;
&lt;br /&gt;
== Common Follower Problems &amp;amp; FAQ ==&lt;br /&gt;
&lt;br /&gt;
====Why don't my followers gain XP?====&lt;br /&gt;
There is a bug in UT_HireFollower. For now the best/easiest approach to take might be to make a copy of UT_HireFollower in an include file and rename it something like UT_HireFollower_Fixed, then make the following change:&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, TRUE);&lt;br /&gt;
to&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE, 0, bPreventLevelup);&lt;br /&gt;
(Note: Be aware if you use the name UT_HireFollower_Fixed you may end up finding your include file conflicting with someone else who has named it the same in their include.)&lt;br /&gt;
&lt;br /&gt;
Alternately you need to clear a flag in a separate script to the one in which they're hired.&lt;br /&gt;
&lt;br /&gt;
You must use the '''SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);''' statement in a script you can be sure will run soon after your hiring script.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====When I choose followers from the Party Picker, they spawn into the area but do not join.====&lt;br /&gt;
&lt;br /&gt;
You need to intercept the EVENT_TYPE_PARTYMEMBER_ADDED event and set the follower to FOLLOWER_STATE_ACTIVE.  See Simple Follower Creation earlier in this document.&lt;br /&gt;
&lt;br /&gt;
====My followers don't have skill trees!====&lt;br /&gt;
&lt;br /&gt;
If a follower hasn't been through an initial chargen/autolevel event (via player_core/sys_autolevel_h) then the skill tree doesn't show.  You're probably trying to be clever and get around UT_HireFollower without going all the way (see monster function above ^_^).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====My followers don't have a class====&lt;br /&gt;
&lt;br /&gt;
GetCreatureCoreClass() seems flaky under some conditions.  It's best to explicitly set the class yourself; this is why class is currently a mandatory argument to hireCustomFollower()&lt;br /&gt;
&lt;br /&gt;
====Dog talents don't work====&lt;br /&gt;
Symptoms: dog talents appear on the talents screen but remain greyed out on level up. Warrior talents appear in the quickslots.&lt;br /&gt;
&lt;br /&gt;
Line 78 of packages_base in packages.xls (Dog) should have the LevelUpTable column set to 257 which is the ALDog table.&lt;br /&gt;
&lt;br /&gt;
====Isn't there an easier way to do this?====&lt;br /&gt;
&lt;br /&gt;
Possibly.  There is a way of recruiting a follower by setting a plot flag.  However I don't understand it, and I expect it still doesn't allow custom autolevel templates, full control over specialisations etc.  There's still a fair bit of stuff hardcoded for the core followers, I'm not sure putting a custom follower through the same process as Al, Leli et al will have good results.&lt;br /&gt;
&lt;br /&gt;
The next section answers this question, up to a point.&lt;br /&gt;
&lt;br /&gt;
==== What if there are more than three potential followers? ====&lt;br /&gt;
This example handles larger numbers of followers, and doesn't force the player to use the party picker unless the party is already full.&lt;br /&gt;
&lt;br /&gt;
The prefix zzz, used throughout, can be replaced with whatever [[Prefixes_in_use | prefix]] you are using for your resources.&lt;br /&gt;
&lt;br /&gt;
If you're making a new campaign, to keep life simple, allocate a unique number to each follower. You could either use a creature variable or a script, e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Party member id (e.g. 1=Alicia, 2=Godwin...)&lt;br /&gt;
int zzzPartyMemberID(object oPartyMember)&lt;br /&gt;
{&lt;br /&gt;
  string sPartyMember = GetTag(oPartyMember);&lt;br /&gt;
&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_alicia&amp;quot;) return 1;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_godwin&amp;quot;) return 2;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_harold&amp;quot;) return 3;&lt;br /&gt;
  if (sPartyMember == &amp;quot;zzzcr_lara&amp;quot;  ) return 4;&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make two separate plots, e.g. zzzpt_hired for when a follower is first recruited, and zzzpt_party to flag whether they're currently in the party. Use flag values that correspond to the unique follower id, e.g. ZZZPT_HIRED_GODWIN will be 2.&lt;br /&gt;
&lt;br /&gt;
If you're modifying the official campaign, you won't be able to make this simplification - you'll need a set of plot flags for your new party members, similar to the official ones. The logic of what follows is still correct, it just means that instead of having one set of common code that works for everyone, you have to explicitly script each party member individually using their personal plot flags.&lt;br /&gt;
&lt;br /&gt;
Follower conversation is now very simple. In Godwin's dialogue, the hiring line will be conditional - when ZZZPT_HIRED_GODWIN is clear - and it will set ZZZPT_HIRED_GODWIN.  No conversation script is necessary. Instead, in the properties of the plot zzzpt_hired, we add a plot event script, as follows.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// PARTY HIRE PLOT SCRIPT&lt;br /&gt;
//&lt;br /&gt;
// This is called in conversation when a party member is hired for the first time.&lt;br /&gt;
// If the party is full, the party picker is displayed, which forces the PARTYMEMBER_ADDED&lt;br /&gt;
// module event.&lt;br /&gt;
//&lt;br /&gt;
// The flag value is never referenced, because the code is common for all party members.&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;events_h&amp;quot;&lt;br /&gt;
#include &amp;quot;global_objects_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;sys_rewards_h&amp;quot;&lt;br /&gt;
#include &amp;quot;log_h&amp;quot;&lt;br /&gt;
#include &amp;quot;utility_h&amp;quot;&lt;br /&gt;
#include &amp;quot;wrappers_h&amp;quot;&lt;br /&gt;
#include &amp;quot;plot_h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;zzz_h&amp;quot;                  // A header containing the zzzPartyMemberID function&lt;br /&gt;
#include &amp;quot;plt_zzzpt_hired&amp;quot;&lt;br /&gt;
#include &amp;quot;plt_zzzpt_party&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int StartingConditional()&lt;br /&gt;
{&lt;br /&gt;
    event  eParms             = GetCurrentEvent();&lt;br /&gt;
    int    nType              = GetEventType(eParms);       // GET or SET&lt;br /&gt;
    string strPlot            = GetEventString(eParms, 0);  // Plot GUID&lt;br /&gt;
    int    nFlag              = GetEventInteger(eParms, 1); // Plot flag&lt;br /&gt;
    object oParty             = GetEventCreator(eParms);    // Plot table owner&lt;br /&gt;
    object oFollower          = GetEventObject(eParms, 0);  // Conversation owner (if any)&lt;br /&gt;
    int    nPlotType          = GetEventInteger(eParms, 5); // Plot type&lt;br /&gt;
&lt;br /&gt;
    int    bIsTutorial        = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsTutorial&amp;quot;, nPlotType);&lt;br /&gt;
    int    bIsCodex           = GetM2DAInt(TABLE_PLOT_TYPES, &amp;quot;IsCodex&amp;quot;, nPlotType);&lt;br /&gt;
&lt;br /&gt;
    int    nResult            = FALSE;                      // return value for DEFINED GET&lt;br /&gt;
    object oPC                = GetPartyLeader();&lt;br /&gt;
&lt;br /&gt;
    plot_GlobalPlotHandler(eParms); // any global plot operations, including debug info&lt;br /&gt;
&lt;br /&gt;
    if (nType == EVENT_TYPE_SET_PLOT) // actions -&amp;gt; normal flags only&lt;br /&gt;
    {&lt;br /&gt;
        int nValue    = GetEventInteger(eParms, 2); // 0=Clear 1=Set&lt;br /&gt;
        int nOldValue = GetEventInteger(eParms, 3); // Current flag value&lt;br /&gt;
&lt;br /&gt;
        if (nValue)&lt;br /&gt;
          {&lt;br /&gt;
            if (GetArraySize(GetPartyList(oPC)) &amp;lt; 4)&lt;br /&gt;
              {&lt;br /&gt;
                UT_HireFollower(oFollower);&lt;br /&gt;
                SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
                AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
                SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
                WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
              }&lt;br /&gt;
            else&lt;br /&gt;
              {&lt;br /&gt;
                WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&lt;br /&gt;
                SetEventScript(oFollower, RESOURCE_SCRIPT_PLAYER_CORE);&lt;br /&gt;
                SendPartyMemberHiredEvent(oFollower, TRUE);&lt;br /&gt;
//                SetPartyPickerGUIStatus(PP_GUI_STATUS_USE);&lt;br /&gt;
//                ShowPartyPickerGUI();&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
     }&lt;br /&gt;
     else // EVENT_TYPE_GET_PLOT -&amp;gt; defined conditions only&lt;br /&gt;
     {&lt;br /&gt;
        switch(nFlag)&lt;br /&gt;
        {&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    plot_OutputDefinedFlag(eParms, nResult);&lt;br /&gt;
    return nResult;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We still need to handle the party picker events in our module event script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
         // PARTY MEMBER ADDED - Allow XP gain. Come here, follow me, flag as party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_ADDED:&lt;br /&gt;
         {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            SetLocalInt(oFollower, CREATURE_REWARD_FLAGS, 0);&lt;br /&gt;
            AddCommand(oFollower, CommandJumpToLocation(GetLocation(GetHero())));&lt;br /&gt;
            SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), TRUE);&lt;br /&gt;
            break;&lt;br /&gt;
         }&lt;br /&gt;
         // PARTY MEMBER DROPPED - flag as not party member.&lt;br /&gt;
         case EVENT_TYPE_PARTYMEMBER_DROPPED:&lt;br /&gt;
        {&lt;br /&gt;
            object oFollower = GetEventObject(ev, 0);&lt;br /&gt;
            WR_SetPlotFlag(PLT_ZZZPT_PARTY, zzzPartyMemberID(oFollower), FALSE);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
When we need to refer to a particular follower explicitly, we can still do so - for example, the flag ZZZPT_PARTY_GODWIN will tell use whether Godwin is currently in the party or not.&lt;br /&gt;
&lt;br /&gt;
== Advanced Follower Creation: An Alternative Approach ==&lt;br /&gt;
&lt;br /&gt;
While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfectly good wheel at hand. The following describes how to adapt the existing machinery for the recruitment and tracking of your own party members.&lt;br /&gt;
&lt;br /&gt;
First create the setup as described above in Simple Follower Creation, except for the scripts and plot tables. In addition, create the GDA extensions for a level-up table and the M2DA which points to those tables, as described in Advanced Follower Creation above.&lt;br /&gt;
&lt;br /&gt;
Now ...&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Create a party plot table ===&lt;br /&gt;
&lt;br /&gt;
Have a look at the gen00pt_party plot table and create a similar table for your own followers. Don't bother with the Defined Flags for the moment, just the Main Flags will do, ie recruited, in-camp and in-party for each follower. (Critical Note: Do not duplicate the plot table, create one from scratch. This is the case for ALL plot tables because of a show-stopping bug which means a new GUID is not assigned on Duplicate of a plot.)&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create a party script ===&lt;br /&gt;
&lt;br /&gt;
Duplicate the gen00pt_party script and rename for your module (conventionally plot tables and their plot scripts have the same name). Delete (or comment out) the Defined Flags section at the end and any lines dealing with logging and tutorials. Change names to those of your party members. If you are using gifting, approval or forced inclusion you may wish to retain those sections of code, but additional machinery will be needed for these facilities to work. For approval you can specify a starting level of approval here for each follower if you want it to be other than zero (as per the existing section dealing with Dog). Note that the custom hire function at the head of the script allows you to specify whether or not to invoke the party picker on recruitment. You may not want to do so for the first couple of followers (but see below). You should already have defined all required constants in a separate file for your module, eg &amp;lt;module prefix&amp;gt;_constants_h. If not, do so now and include it, as well as your plot table, at the head of the script. Delete includes that only refer to the main campaign. (If this is all Greek to you, spend a couple of hours examining the set-up of the Demo, which is packaged with the toolset, and go through the introductory tutorials referenced on the main page of this wiki).&lt;br /&gt;
&lt;br /&gt;
Looking at the new party script, notice that the follower-in-camp function is not defined. This is because for some arcane reason it is defined in party_h, and unhappily references the main campaign's plot table. So we will have to create a new function to replace it, change the other function's flag reference (for the sake of neatness), and change the call in the main body of the script. (You may decide later for other reasons to replicate and customise party_h, but that won't interfere with re-creating this function here.)&lt;br /&gt;
&lt;br /&gt;
Our two functions at the head of the script should be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;void SetFollowerInParty(object oFollower, string sPlot, int nCampFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nCampFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, TRUE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE);&lt;br /&gt;
    command cJump = CommandJumpToObject(GetPartyLeader());&lt;br /&gt;
    WR_AddCommand(oFollower, cJump);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SetFollowerInCamp(object oFollower, string sPlot, int nPartyFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nPartyFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, FALSE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
and the line in the in-camp sections for each follower should now be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;SetFollowerInCamp(o&amp;lt;follower&amp;gt;, strPlot, &amp;lt;follower&amp;gt;_IN_PARTY);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Step 3: Create package GDAs and reference them in you 2DA_base extension ===&lt;br /&gt;
&lt;br /&gt;
Look at the packages_base GDA and create an extension GDA with one line for each follower based on a main campaign follower that is most like your own follower, eg a sword-shield warrior can be a copy of Alistair, a battle mage a copy of Morrigan, etc. You can look at the Excel version of this GDA to more easily see what the fields mean. It is here that you can specify what if any specialisation will be assigned on hire and the level at which this spec point becomes available. (The IDs for each spec are in the 4000-range of ABI_base.)&lt;br /&gt;
&lt;br /&gt;
Most importantly, it is here also that you define the ID of both your level-up table and the AIP table you are about to create.&lt;br /&gt;
&lt;br /&gt;
Now create aip_follower_&amp;lt;follower name&amp;gt; gda tables, again based on a existing tables most like your own followers. No changes should be required to the copies you create.&lt;br /&gt;
&lt;br /&gt;
In the m2da_base_&amp;lt;your module&amp;gt; extension you have already created, add lines for your AIP tables with a package ID referencing the IDs you assigned in your packages extension table.&lt;br /&gt;
&lt;br /&gt;
Carefully check that all IDs in your GDAs are correct and cross-reference properly, and save the GDAs to your override directory.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Module script addition ===&lt;br /&gt;
&lt;br /&gt;
Modify your own module script to point to the new plot table and your own followers. To see an example of the required code for the two new sections look at the relevant section of module_core, which are for EVENT_TYPE_PARTYMEMBER_ADDED and EVENT_TYPE_PARTYMEMBER_DROPPED.&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The recruit flag is set in a conversation (usually, but it could be a script) and that event is then processed by the plot script, which among other things sets both the in-camp and in-party flags, and fires up the party picker by default. If the player then selects the follower in the picker, the in-camp flag is unset (or vice versa if the follower is not selected to join). Subsequently, if the character is selected (or unselected) in the picker, the event is picked up by the module script, which sets the relevant plot flag as true, and that plot event is then sent to the plot scipt which sets the other flag as false. &lt;br /&gt;
&lt;br /&gt;
(Note that if the party picker is turned off for a particular follower's recruit event, that follower will be placed in the active party regardless of the number of members, so ONLY do this for a follower who cannot be recruited when there are already 3 possible followers.)&lt;br /&gt;
&lt;br /&gt;
On recruitment, player_core rebuilds the character according to the specifications laid out in the GDAs, so no further scripting is required.&lt;br /&gt;
&lt;br /&gt;
=== Uses ===&lt;br /&gt;
&lt;br /&gt;
To recruit a party member, set the recruit flag from your plot table in the relevant dialogue. Adding or subtracting followers from the active party is automatically tracked via this machinery, and the plot flags can be interrogated in all your scripts and conversations if you need to know who is currently in the party and who is in camp.&lt;br /&gt;
&lt;br /&gt;
Defined flags can be added as you need them to the script and plot table but there is no point having flags that you will not use, so as with all Defined Flags this is an as-you-go decision, but quite easy to do.&lt;br /&gt;
&lt;br /&gt;
Hiring and firing of temporary party members at the start of a campaign (such as Ser Jory, or Jowan, or Soris, etc) can be handled by UT_HireFollower, and the party picker is not invoked (nor is the Party Camp an available destination).&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If you haven't done so already, create a simple debugging area for your module where you can dump the player, all followers and a couple of conversation dummies, and set up a dialogue in which you can invoke all required flags and conditions and see if they actually work as expected. (This setup can be used to test many other components as well.) Global machinery such as this can be painful to set up and get right (unless you are of an exceptionally methodical cast of mind), but it is worthwhile to ensure they are absolutely bullet-proof before you develop the specifics of your module.&lt;br /&gt;
&lt;br /&gt;
=== The KISS principle ===&lt;br /&gt;
&lt;br /&gt;
This is an &amp;quot;out-of-the-box&amp;quot; solution, and once set up is quite robust. If you want variants not catered for here, do NOT try to modify what you already have working.&lt;br /&gt;
&lt;br /&gt;
'''Use-case:''' You want a follower (example tag: dairren) to be recruited without a set specialisation and one level higher than the PC.&lt;br /&gt;
&lt;br /&gt;
Go to your packages gda and set the spec field to 0. In the character's plot table (you should have at least one for each follower) create a flag which we will call BLAH_BLAH. In the table's plot scipt insert the following very simple event handler:&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;dascript&amp;gt;case BLAH_BLAH:&lt;br /&gt;
         {&lt;br /&gt;
           SetCreatureProperty(oDairren, 38, 1.00); //awards the spec point; field from the properties gda&lt;br /&gt;
           int aLevel = GetLevel(oHero); //some simple arithmetic to find out the XP we need to award&lt;br /&gt;
           int bLevel = (aLevel+1);&lt;br /&gt;
           int aPoints = RW_GetXPNeededForLevel(aLevel);&lt;br /&gt;
           int bPoints = RW_GetXPNeededForLevel(bLevel);&lt;br /&gt;
           int targetPoints = (bPoints - aPoints);&lt;br /&gt;
           RewardXP(oDairren, targetPoints, FALSE, TRUE); //award the XP, and we're done&lt;br /&gt;
           break;&lt;br /&gt;
	 }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The flag can be set in the same conversation as the recruit flag, so long as it comes afterwards. This way you not only maintain the integrity of your core machinery, but keep exceptions/variations for particular characters where they belong -- with that character's plot tables and scripts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
{{Languages}}&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=User:Gaxkang55&amp;diff=15171</id>
		<title>User:Gaxkang55</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=User:Gaxkang55&amp;diff=15171"/>
				<updated>2010-12-04T16:53:10Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Advanced Follower Creation: An Alternative Approach ==&lt;br /&gt;
&lt;br /&gt;
While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfectly good wheel at hand. The following describes how to adapt the existing machinery for the recruitment and tracking of your own party members.&lt;br /&gt;
&lt;br /&gt;
First create the setup as described above in Simple Follower Creation, except for the scripts and plot tables. In addition, create the GDA extensions for a level-up table and the M2DA which points to those tables, as described in Advanced Follower Creation above.&lt;br /&gt;
&lt;br /&gt;
Now ...&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Create a party plot table ===&lt;br /&gt;
&lt;br /&gt;
Have a look at the gen00pt_party plot table and create a similar table for your own followers. Don't bother with the Defined Flags for the moment, just the Main Flags will do, ie recruited, in-camp and in-party for each follower. (Critical Note: Do not duplicate the plot table, create one from scratch. This is the case for ALL plot tables because of a show-stopping bug which means a new GUID is not assigned on Duplicate of a plot.)&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create a party script ===&lt;br /&gt;
&lt;br /&gt;
Duplicate the gen00pt_party script and rename for your module (conventionally plot tables and their plot scripts have the same name). Delete (or comment out) the Defined Flags section at the end and any lines dealing with logging and tutorials. Change names to those of your party members. If you are using gifting, approval or forced inclusion you may wish to retain those sections of code, but additional machinery will be needed for these facilities to work. For approval you can specify a starting level of approval here for each follower if you want it to be other than zero (as per the existing section dealing with Dog). Note that the custom hire function at the head of the script allows you to specify whether or not to invoke the party picker on recruitment. You may not want to do so for the first couple of followers (but see below). You should already have defined all required constants in a separate file for your module, eg &amp;lt;module prefix&amp;gt;_constants_h. If not, do so now and include it, as well as your plot table, at the head of the script. Delete includes that only refer to the main campaign. (If this is all Greek to you, spend a couple of hours examining the set-up of the Demo, which is packaged with the toolset, and go through the introductory tutorials referenced on the main page of this wiki).&lt;br /&gt;
&lt;br /&gt;
Looking at the new party script, notice that the follower-in-camp function is not defined. This is because for some arcane reason it is defined in party_h, and unhappily references the main campaign's plot table. So we will have to create a new function to replace it, change the other function's flag reference (for the sake of neatness), and change the call in the main body of the script. (You may decide later for other reasons to replicate and customise party_h, but that won't interfere with re-creating this function here.)&lt;br /&gt;
&lt;br /&gt;
Our two functions at the head of the script should be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;void SetFollowerInParty(object oFollower, string sPlot, int nCampFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nCampFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, TRUE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE);&lt;br /&gt;
    command cJump = CommandJumpToObject(GetPartyLeader());&lt;br /&gt;
    WR_AddCommand(oFollower, cJump);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SetFollowerInCamp(object oFollower, string sPlot, int nPartyFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nPartyFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, FALSE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
and the line in the in-camp sections for each follower should now be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;SetFollowerInCamp(o&amp;lt;follower&amp;gt;, strPlot, &amp;lt;follower&amp;gt;_IN_PARTY);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Step 3: Create package GDAs and reference them in you 2DA_base extension ===&lt;br /&gt;
&lt;br /&gt;
Look at the packages_base GDA and create an extension GDA with one line for each follower based on a main campaign follower that is most like your own follower, eg a sword-shield warrior can be a copy of Alistair, a battle mage a copy of Morrigan, etc. You can look at the Excel version of this GDA to more easily see what the fields mean. It is here that you can specify what if any specialisation will be assigned on hire and the level at which this spec point becomes available. (The IDs for each spec are in the 4000-range of ABI_base.)&lt;br /&gt;
&lt;br /&gt;
Most importantly, it is here also that you define the ID of both your level-up table and the AIP table you are about to create.&lt;br /&gt;
&lt;br /&gt;
Now create aip_follower_&amp;lt;follower name&amp;gt; gda tables, again based on a existing tables most like your own followers. No changes should be required to the copies you create.&lt;br /&gt;
&lt;br /&gt;
In the m2da_base_&amp;lt;your module&amp;gt; extension you have already created, add lines for your AIP tables with a package ID referencing the IDs you assigned in your packages extension table.&lt;br /&gt;
&lt;br /&gt;
Carefully check that all IDs in your GDAs are correct and cross-reference properly, and save the GDAs to your override directory.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Module script addition ===&lt;br /&gt;
&lt;br /&gt;
Modify your own module script to point to the new plot table and your own followers. To see an example of the required code for the two new sections look at the relevant section of module_core, which are for EVENT_TYPE_PARTYMEMBER_ADDED and EVENT_TYPE_PARTYMEMBER_DROPPED.&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The recruit flag is set in a conversation (usually, but it could be a script) and that event is then processed by the plot script, which among other things sets both the in-camp and in-party flags, and fires up the party picker by default. If the player then selects the follower in the picker, the in-camp flag is unset (or vice versa if the follower is not selected to join). Subsequently, if the character is selected (or unselected) in the picker, the event is picked up by the module script, which sets the relevant plot flag as true, and that plot event is then sent to the plot scipt which sets the other flag as false. &lt;br /&gt;
&lt;br /&gt;
(Note that if the party picker is turned off for a particular follower's recruit event, that follower will be placed in the active party regardless of the number of members, so ONLY do this for a follower who cannot be recruited when there are already 3 possible followers.)&lt;br /&gt;
&lt;br /&gt;
On recruitment, player_core rebuilds the character according to the specifications laid out in the GDAs, so no further scripting is required.&lt;br /&gt;
&lt;br /&gt;
=== Uses ===&lt;br /&gt;
&lt;br /&gt;
To recruit a party member, set the recruit flag from your plot table in the relevant dialogue. Adding or subtracting followers from the active party is automatically tracked via this machinery, and the plot flags can be interrogated in all your scripts and conversations if you need to know who is currently in the party and who is in camp.&lt;br /&gt;
&lt;br /&gt;
Defined flags can be added as you need them to the script and plot table but there is no point having flags that you will not use, so as with all Defined Flags this is an as-you-go decision, but quite easy to do.&lt;br /&gt;
&lt;br /&gt;
Hiring and firing of temporary party members at the start of a campaign (such as Ser Jory, or Jowan, or Soris, etc) can be handled by UT_HireFollower, and the party picker is not invoked (nor is the Party Camp an available destination).&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If you haven't done so already, create a simple debugging area for your module where you can dump the player, all followers and a couple of conversation dummies, and set up a dialogue in which you can invoke all required flags and conditions and see if they actually work as expected. (This setup can be used to test many other components as well.) Global machinery such as this can be painful to set up and get right (unless you are of an exceptionally methodical cast of mind), but it is worthwhile to ensure they are absolutely bullet-proof before you develop the specifics of your module.&lt;br /&gt;
&lt;br /&gt;
=== The KISS principle ===&lt;br /&gt;
&lt;br /&gt;
This is an &amp;quot;out-of-the-box&amp;quot; solution, and once set up is quite robust. If you want variants not catered for here, do NOT try to modify what you already have working.&lt;br /&gt;
&lt;br /&gt;
'''Use-case:''' You want a follower (example tag: dairren) to be recruited without a set specialisation and one level higher than the PC.&lt;br /&gt;
&lt;br /&gt;
Go to your packages gda and set the spec field to 0. In the character's plot table (you should have at least one for each follower) create a flag which we will call BLAH_BLAH. In the table's plot scipt insert the following very simple event handler:&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;dascript&amp;gt;case BLAH_BLAH:&lt;br /&gt;
         {&lt;br /&gt;
           SetCreatureProperty(oDairren, 38, 1.00); //awards the spec point; field from the properties gda&lt;br /&gt;
           int aLevel = GetLevel(oHero); //some simple arithmetic to find out the XP we need to award&lt;br /&gt;
           int bLevel = (aLevel+1);&lt;br /&gt;
           int aPoints = RW_GetXPNeededForLevel(aLevel);&lt;br /&gt;
           int bPoints = RW_GetXPNeededForLevel(bLevel);&lt;br /&gt;
           int targetPoints = (bPoints - aPoints);&lt;br /&gt;
           RewardXP(oDairren, targetPoints, FALSE, TRUE); //award the XP, and we're done&lt;br /&gt;
           break;&lt;br /&gt;
	 }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The flag can be set in the same conversation as the recruit flag, so long as it comes afterwards. This way you not only maintain the integrity of your core machinery, but keep exceptions/variations for particular characters where they belong -- with that character's plot tables and scripts.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=User:Gaxkang55&amp;diff=15170</id>
		<title>User:Gaxkang55</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=User:Gaxkang55&amp;diff=15170"/>
				<updated>2010-12-04T16:36:42Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: Created page with '== Advanced Follower Creation: An Alternative Approach ==  While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfe...'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Advanced Follower Creation: An Alternative Approach ==&lt;br /&gt;
&lt;br /&gt;
While these things are to a large extent a matter of taste, I see no reason to reinvent the wheel when there is a perfectly good wheel at hand. The following describes how to adapt the existing machinery for the recruitment and tracking of your own party members.&lt;br /&gt;
&lt;br /&gt;
First create the setup as described above in Simple Follower Creation, except for the scripts and plot tables. In addition, create the GDA extensions for a level-up table and the M2DA which points to those tables, as described in Advanced Follower Creation above.&lt;br /&gt;
&lt;br /&gt;
Now ...&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Create a party plot table ===&lt;br /&gt;
&lt;br /&gt;
Have a look at the gen00pt_party plot table and create a similar table for your own followers. Don't bother with the Defined Flags for the moment, just the Main Flags will do, ie recruited, in-camp and in-party for each follower. (Critical Note: Do not duplicate the plot table, create one from scratch. This is the case for ALL plot tables because of a show-stopping bug which means a new GUID is not assigned on Duplicate of a plot.)&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Create a party script ===&lt;br /&gt;
&lt;br /&gt;
Duplicate the gen00pt_party script and rename for your module (conventionally plot tables and their plot scripts have the same name). Delete (or comment out) the Defined Flags section at the end and any lines dealing with logging and tutorials. Change names to those of your party members. If you are using gifting, approval or forced inclusion you may wish to retain those sections of code, but additional machinery will be needed for these facilities to work. For approval you can specify a starting level of approval here for each follower if you want it to be other than zero (as per the existing section dealing with Dog). Note that the custom hire function at the head of the script allows you to specify whether or not to invoke the party picker on recruitment. You may not want to do so for the first couple of followers (but see below). You should already have defined all required constants in a separate file for your module, eg &amp;lt;module prefix&amp;gt;_constants_h. If not, do so now and include it, as well as your plot table, at the head of the script. Delete includes that only refer to the main campaign. (If this is all Greek to you, spend a couple of hours examining the set-up of the Demo, which is packeged with the toolset, and go through the introductory tutorials referenced on the main page of this wiki).&lt;br /&gt;
&lt;br /&gt;
Looking at the new party script, notice that the follower-in-camp function is not defined. This is because for some arcane reason it is defined in party_h, and unhappily references the main campaign's plot table. So we will have to create a new function to replace it, change the other function's flag reference (for the sake of neatness), and change the call in the main body of the script. (You may decide later for other reasons to replicate and customise party_h, but that won't interfere with re-creating this function here.)&lt;br /&gt;
&lt;br /&gt;
Our two functions at the head of the script should be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;void SetFollowerInParty(object oFollower, string sPlot, int nCampFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nCampFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, TRUE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_ACTIVE, TRUE);&lt;br /&gt;
    command cJump = CommandJumpToObject(GetPartyLeader());&lt;br /&gt;
    WR_AddCommand(oFollower, cJump);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void SetFollowerInCamp(object oFollower, string sPlot, int nPartyFlag)&lt;br /&gt;
{&lt;br /&gt;
    WR_SetPlotFlag(sPlot, nPartyFlag, FALSE);&lt;br /&gt;
    WR_SetObjectActive(oFollower, FALSE);&lt;br /&gt;
    WR_SetFollowerState(oFollower, FOLLOWER_STATE_AVAILABLE, FALSE);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
and the line in the in-camp sections for each follower should now be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dascript&amp;gt;SetFollowerInCamp(o&amp;lt;follower&amp;gt;, strPlot, &amp;lt;follower&amp;gt;_IN_PARTY);&amp;lt;/dascript&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
=== Step 3: Create package GDAs and reference them in you 2DA_base extension ===&lt;br /&gt;
&lt;br /&gt;
Look at the packages_base GDA and create an extension GDA with one line for each follower based on a main campaign follower that is most like your own follower, eg a sword-shield warrior can be a copy of Alistair, a battle mage a copy of Morrigan, etc. You can look at the Excel version of this GDA to more easily see what the fields mean. It is here that you can specify what if any specialisation will be assigned on hire and the level at which this spec point becomes available. (The IDs for each spec are in the 4000-range of ABI_base.)&lt;br /&gt;
&lt;br /&gt;
Most importantly, it is here also that you define the ID of both your level-up table and the AIP table you are about to create.&lt;br /&gt;
&lt;br /&gt;
Now create aip_follower_&amp;lt;follower name&amp;gt; gda tables, again based on a existing tables most like your own followers. No changes should be required to the copies you create.&lt;br /&gt;
&lt;br /&gt;
In the m2da_base_&amp;lt;your module&amp;gt; extension you have already created, add lines for your AIP tables with a package ID referencing the IDs you assigned in your packages extension table.&lt;br /&gt;
&lt;br /&gt;
Carefully check that all IDs in your GDAs are correct and cross-reference properly, and save the GDAs to your override directory.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Module script addition ===&lt;br /&gt;
&lt;br /&gt;
Modify your own module script to point to the new plot table and your own followers. To see an example of the required code for the two new sections look at the relevant section of module_core, which are for EVENT_TYPE_PARTYMEMBER_ADDED and EVENT_TYPE_PARTYMEMBER_DROPPED.&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
&lt;br /&gt;
The recruit flag is set in a conversation (usually, but it could be a script) and that event is then processed by the plot script, which among other things sets both the in-camp and in-party flags, and fires up the party picker by default. If the player then selects the follower in the picker, the in-camp flag is unset (or vice versa if the follower is not selected to join). Subsequently, if the character is selected or unselected in the picker, the event is picked up by the module script, which sets the relevant plot flag as true, and that plot event is then sent to the plot scipt which sets the other flag as false. &lt;br /&gt;
&lt;br /&gt;
(Note that if the party picker is turned off for a particular follower's recruit event, that follower will be placed in the active party regardless of the number of members, so ONLY do this for a follower who cannot be recruited when there are already 3 possible followers.)&lt;br /&gt;
&lt;br /&gt;
On recruitment, player_core rebuilds the character according to the specifications laid out in the GDAs, so no further scripting is required.&lt;br /&gt;
&lt;br /&gt;
=== Uses ===&lt;br /&gt;
&lt;br /&gt;
To recruit a party member, set the recruit flag from your plot table in the relevant dialogue. Adding or subtracting followers from the active party is automatically tracked via this machinery, and the plot flags can be interrogated in all your scripts and conversations if you need to know who is currently in the party and who is in camp.&lt;br /&gt;
&lt;br /&gt;
Defined flags can be added as you need them to the script and plot table but there is no point having flags that you will not use, so as with all Defined Flags this is an as-you-go decision, but quite easy to do.&lt;br /&gt;
&lt;br /&gt;
Hiring and firing of temporary party members at the start of a campaign (such as Ser Jory, or Jowan, or Soris, etc) can be handled by UT_HireFollower, and the party picker is not invoked (nor is the Party Camp an available destination).&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
&lt;br /&gt;
If you haven't done so already, create a simple debugging area for your module where you can dump the player, all followers and a couple of conversation dummies, and set up a dialogue in which you can invoke all required flags and conditions and see if they actually work as expected. (This setup can be used to test many other components as well.) Global machinery such as this can be painful to set up and get right (unless you are of an exceptionally methodical cast of mind), but it is worthwhile to ensure they are absolutely bullet-proof before you develop the specifics of your module.&lt;br /&gt;
&lt;br /&gt;
=== The KISS principle ===&lt;br /&gt;
&lt;br /&gt;
This is an &amp;quot;out-of-the-box&amp;quot; solution, and once set up is quite robust. If you want variants not catered for here, do NOT try to modify what you already have working.&lt;br /&gt;
&lt;br /&gt;
'''Use-case:''' You want a follower (example tag: dairren) to be recruited without a set specialization and one level higher than the PC.&lt;br /&gt;
&lt;br /&gt;
Go to your packages gda and set the spec field to 0. In the character's plot table (you should have at least one for each follower) create a flag which we will call BLAH_BLAH. In the table's plot scipt insert the following very simple event handler:&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;dascript&amp;gt;case BLAH_BLAH:&lt;br /&gt;
         {&lt;br /&gt;
           SetCreatureProperty(oDairren, 38, 1.00); //awards the spec point; field from the properties gda&lt;br /&gt;
           int aLevel = GetLevel(oHero); //some simple arithmetic to find out the XP we need to award&lt;br /&gt;
           int bLevel = (aLevel+1);&lt;br /&gt;
           int aPoints = RW_GetXPNeededForLevel(aLevel);&lt;br /&gt;
           int bPoints = RW_GetXPNeededForLevel(bLevel);&lt;br /&gt;
           int targetPoints = (bPoints - aPoints);&lt;br /&gt;
           RewardXP(oDairren, targetPoints, FALSE, TRUE); //award the XP, and we're done&lt;br /&gt;
           break;&lt;br /&gt;
	 }&amp;lt;/dascript&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The flag can be set in the same conversation as the recruit flag, so long as it comes afterwards. This way you not only maintain the integrity of your core machinery, but keep exceptions/variations for particular characters where they belong -- with that character's plot tables and scripts.&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	<entry>
		<id>https://www.datoolset.net/mw/index.php?title=Talk:Follower_tutorial&amp;diff=14041</id>
		<title>Talk:Follower tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.datoolset.net/mw/index.php?title=Talk:Follower_tutorial&amp;diff=14041"/>
				<updated>2010-10-21T09:38:17Z</updated>
		
		<summary type="html">&lt;p&gt;Gaxkang55: /* Dog equipment slots */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;great tutorial. my only problem is: my companion, Erik has different skills and doesn't seem to follow his autolevel template. --[[User:Mono0x32440|Mono0x32440]] 17:46, 25 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Follower's Portrait ==&lt;br /&gt;
&lt;br /&gt;
I cannot figure out how to change the default grey backgrounded portrait for the new followers. It would be nice to have pose and background options.&lt;br /&gt;
&lt;br /&gt;
== Dog equipment slots ==&lt;br /&gt;
&lt;br /&gt;
Mention should be made of the fact that a dog follower needs to have the appropriate equipment slot mask. I will make the addition to the text if no-one has any objections/suggestions in a couple of days. --[[User:Gaxkang55|Gaxkang55]] 09:38, 21 October 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Gaxkang55</name></author>	</entry>

	</feed>