-
Notifications
You must be signed in to change notification settings - Fork 27
Creating Startup Files and Adding Custom Conditionals for ME2 Mods
THIS TUTORIAL IS DEPRECATED. While the methods described below will still work, there are easier alternatives. Startup files can now be generated as part of a DLC Starter Kit. Conditionals can now be added more easily than the method discussed below due to script editor improvements.
In Mass Effect 2, it is not possible to override conditionals via DLC mods. This means that to change vanilla conditionals they must be edited in their original locations (PlotManager.pcc
for the base game, and the Startup or DLCSharedPlot.pcc
files for DLC modules).
New custom conditionals can be added to DLC mods via a custom Startup file. This is a complex process that involves some hex editing. This tutorial will explain how to create an empty Startup file for your mod, along with new conditionals.
We will be using an existing DLC Startup file as a base. Startup_PRE_Gamestop_int.pcc
is an excellent candidate because it is very small, but includes completely empty entries for conditionals, as well as plot information like state transitions, etc.
Figure 1
In Figure 1, above, you will see PlotManagerAuto
in blue – this is for plot transitions, codexes, etc. It will not be covered by this tutorial, but the Plot Editor in ME3Explorer can be used to edit and add items that your mod may then use.
Red identifies PlotManager
, which is where conditionals will be placed. This is the focus of this tutorial.
Green identifies SFXGame
entries – in this case scripts for the Terminus weapons and armour that the base DLC provides as a pre-order bonus. These can be amended for use in mods, or new entries can be added, but doing so is beyond the scope of this tutorial. Removing the unused scripts will be covered.
Copy Startup_PRE_Gamestop_int.pcc
to your DLC mod, and rename it following the conventions of your own DLC mod’s name. So if your DLC mod’s folder name is DLC_MOD_EXAMPLE
, you’d name your startup file STARTUP_MOD_EXAMPLE_INT.pcc
.
We now need to rename all PRE_Gamestop
instances within the package file to MOD_EXAMPLE
.
Open the file. Go to the Names tab (red). Search for the old name (blue). This will find the first instance of the name in the package (green). Right-click and choose Edit Name (purple). This will open a pop-up which will let you change the name. Amend it so that it matches the naming conventions for your mod, then search for the next instance. There should be 4 that need changing.
Figure 2
Go back to the Tree View tab, and you will see the changes. It should now look like this (new names highlighted in blue).
Figure 3
We now need to remove the original Startup content – any old conditionals, plot elements and scripts, etc. As noted,
Expand Export 17 – SFXGameDLC_MOD_EXAMPLE
. There will be six entries. Right-click the first entry, then choose Trash entry and children. Repeat for all six entries under Export 17.
Figure 4
A package called ME3ExplorerTrashPackage
will appear at the top of the file. This is fine. ME3Explorer does not remove trashed items, but fixes them in a state where they will not be used or loaded.
The items we have trashed are still referenced in the Object Referencer. This can also be confirmed if you check for bad references – available under the debugging menu. We must go to Export 14 – Object Referencer
(in blue, below) In the right-hand pane, expand ReferencedObjects
(red, below).
Figure 5
Scroll all the way down to the bottom of the array to find the trashed packages (green), and then remove them from the array (red). See Figure 6, below.
Figure 6
Okay, we now have a totally empty startup file!
The DLC mod has to tell the game to load the Startup file. Essentially, as the name suggests, the file will be loaded on startup and stay loaded throughout play. To do this we need to add it to some .ini files.
The ME3Tweaks Mod Manager Starter Kit tool will have created a number of files in the DLC mod folder, including BIOEngine.ini. Open this using an appropriate text editor, such as Notepad++.
Figure 7
The default file will not have the final section (green). You will need to manually add this to the file, then save and close.
Next we will need a BIOGame.ini
file. This will not have been created by default, but can be easily created in Notepad++. Copy the text in Figure 8, and save as BIOGame.ini
.
Figure 8
NOTE: if you intend to make use of SFXGame scripts, you will need to add additional lines to both of these files. This is beyond the scope of this tutorial.
Now, hopefully, the game will load our Startup file. But it’s empty!
To do this we will be cloning a conditional from an existing file. For this tutorial we will using the Startup file from Kasumi’s DLC – Startup_Kasumi_int.pcc
. You can use any conditional, but it should be the first one in the list. Open this file in addition to your own Startup file. We will be dragging and dropping between them.
Find the first conditional in Kasumi’s Startup file, and drag and drop it over onto your own as shown in Figure 9. You want to drag Export 5 from the Kasumi file and drop it on top of Export 1 in the Example Mod file.
Figure 9
Choose to Clone the tree (you can also choose Clone All References – in this very specific instance, either works fine).
Figure 10
The new conditional will appear. It will be misnamed, and not linked to anything correctly, but it’s there!
Firstly, we need to name our conditional. It must be a unique number. Vanilla conditionals end below 3000, but various mods use various numbers, and it’s important to try and avoid these if possible. Once you have settled on a unique number you will need to add the name to the package, and then change the name of the conditional. All conditional numbers are preceded by a capital “F”. For the purposes of this tutorial we will name our conditional F5200
.
Figure 11
Do this in the following order.
- Tools→Add name (red). Add name
F5200
. - In the right-hand pane, choose the metadata pane, then add
F5200
into the Object Name field (blue). - Save all changes (yellow).
You may be able to skip this section by using Package Editor's experimental "Relink tree and update functions" feature. Be sure to back up your file BEFORE attempting this. You can find it by ticking "Enable experiments (Warning: dangerous)" under the "Debugging" menu. To use it: highlight the Class (or an individual Function), then select:
Experiments -> Other people's box of Legos -> Relink children tree and update local functions
Okay, this is the most complicated bit. We need to do some hex editing to link up the conditional. For this we need to be familiar with two things.
- the
INSERT
key on your keyboard. This will toggle the cursor from Insert Mode (where you type and push the text ahead further onwards) and Overtype Mode (where you are overwriting the highlighted character).
Figure 12
- The Hex Converter, which is available from the Utilities section of ME3Explorer. We will be entering integers (signed or unsigned doesn’t matter in this instance, but the difference is that signed integers can be negative values), and using the Hex Little Endian results. Simply enter the integer and press Enter. The resulting Hex code will always be in a string of 8 hex characters (or 4 pairs, each known as a byte). These characters can be integers 0 – 9 or letters between A and F.
Figure 13
Select the parent export for all the conditionals – in this case, Export 1 – bioautoconditionals
. In the right-hand pane, select the Binary Interpreter tab. This is highlighted in green in Figure 14.
Figure 14
There are several things that we must amend. Selecting items on the right will cause the relevant Hex bytes to be highlighted in yellow on the left. This can be seen with the item highlighted in blue – ChildListStart. On the left, 4 hex bytes are highlighted in yellow (also underlined in blue). Further down, Local Functions is shown in red, with the 4 corresponding bytes underlined in red. We must change both of these.
This must correspond to the export number for the last conditional in your list of custom conditionals. Currently we have only one conditional – F5200
, which is export 19 (shown in purple) – so we need ChildStartList
to refer to integer 19. If we were to add F5201
, F5202
and F5203
, then F5203
would be the last conditional, and ChildStartList
should refer to the export number for F5203
.
NOTE: The conditional names do not need to be in order. Looking at vanilla conditionals, you will see they are often out of order. What is important is that each conditional is linked to another in a one-way chain. The final link in that chain links into
ChildStartList
. If you follow the procedures described in this tutorial, this will always be the most recent conditional you have added to the file.
In the Hex Converter – again shown in purple – we will enter 19 into the Signed Integer box, hit Enter, and get the Little Endian value – 13 00 00 00
.
If needed, toggle the Insert Key so that Overtype Mode is active. Change the current value (00 00 00 00
) to the new value – 13 00 00 00
. In this instance, you just need to overwrite the first byte. Save Hex Changes (orange).
This should be equal to the number of new conditionals in the Startup file. Currently it is set to 0 and we want it to be set to 1. Hex for numbers 0 – 9 is very simple. Entering an integer of 1 into the Hex Converter will show Little Endian of 01 00 00 00
.
So again ensuring we are in Overtype Mode, we will change the appropriate hex from 00 00 00 00
to 01 00 00 00
, and save the changes again.
This will result in an error. Do not panic. This is because we have added a Local Function
, but it doesn’t exist yet in the hex code. We need to add it, which we will do in a minute.
See below, Figure 15 shows the amended ChildStartList
(blue) and Local Function
(red). It also shows that it is now possible to expand Local Function
to see the conditionals, but, of course, they aren’t there, and this leads to an error (green).
Figure 15
The hex code needed to add the conditional has three parts.
(i) Number relating to the Conditional’s name. We need to go to the Names tab (red) in the package editor, scroll to the end, and find the name we added – F5200
– and look at the number to its left (blue). In this case, the number is 575. Entering 575 into the Hex Editor provides Little Endian of 3F 02 00 00
.
Figure 16
(ii) The second element is always 00 00 00 00
. I don’t know why. I don’t know what it refers to. I just know that it works. Do not question the hex code.
(iii) The export number for the conditional. The conditional is Export 19 and we already calculated this when updating the ChildStartList
. The needed hex is 13 00 00 00
.
Putting these together gives us the following hex string.
3F 02 00 00 00 00 00 00 13 00 00 00
.
Go back to the Binary Interpreter for the conditionals tree (Export 1).
Toggle the Insert Key so that it is in Insert Mode. We want to place the cursor after the 4 bytes related to Local Functions, and before the bytes relating to the next item in the binary interpreter. This is directly after the red underlined code in Figure 15.
Then type in the hex above. Carefully.
Save changes.
The error should disappear and it should look like this (the new hex code is underlined in red):
Figure 17
Great! We have now added conditional 5200
to our mod. We can reference this and it should work. But it’s still set to check some random condition from the Kasumi mod and we need to change that.
Select the new conditional (Figure 18, red), and then choose the Script Viewer tab (blue). The current conditional (copied from Kasumi’s DLC) will be shown (green).
Figure 18
This conditional is editable as it would be in any text editor, including using copy/paste shortcuts. Looking at other conditionals, and the Introduction to Plot Management tutorial are excellent ways to learn more about the conditionals and their syntax, but here is a crash course on some commonly used functions.
gv.GetBool(NUMBER)
is used to reference plot bools. Used with TRUE
or FALSE
arguments.
gv.GetInt(NUMBER)
is used to reference integers. Used to check if they are lesser than, greater than or equal to numerical values.
==
means equal to.
>=
is equal or greater than.
<=
is equal or less than.
&&
means and.
||
means or.
Brackets do not need to be used if there are only two arguments. If using more than two arguments, brackets must be used following the pattern shown below. An OR
statement resets the brackets requirement (again as shown below).
Here is a complex conditional:
((gv.GetBool(1000) == TRUE && gv.GetBool(2000) == FALSE) && gv.GetInt(300) >= 2) && gv.GetInt(400) == 5 || gv.GetBool(1234) == FALSE && gv.GetInt(321) <= 4;
This conditional will return true if:
(1) Bool 1000 is true and Bool 2000 is false and Integer 300 is equal or greater than 2 and Integer 400 equals 5
OR
(2) Bool 1234 is false and Integer 321 is equal or less than 4.
If the conditional follows the correct syntax, text at the bottom will note it has been LOG: Parsed! And you can then Compile (EXPERIMENTAL!)
Figure 19
Surely this is the same as adding the first one? No, not exactly, though the process will be the same from here on out. There are a few differences when it comes to adding new conditionals to the chain.
Firstly, instead of dragging and dropping, we will simply clone the existing conditional. Right-click on Conditional F5200
and choose Clone Tree.
Figure 20
Notice that the cloned conditional is named F5200_0
. The “_0” is because there is already something else with the same name. We need to rename the conditional to a unique number and get reset the Object Index from 1 back to 0. (The Object Index is always one higher than the number after the underscore).
To do this, follow the process described in Step 5 to rename the conditional to a unique number (we will use F5201
– Figure 21, in red).
Figure 21
Next, reset the Object Index to 0 (shown in blue). Save all changes (purple).
Next, expand F5201
’s tree – shown in green in Figure 21. As you can see, each of the entries has an underscore followed by a 0. In turn, select each of them, and on the metadata tab, change the Object Index from 1 to 0, and save the changes.
Next we have an additional step on a tab not previously used. Go to the Bytecode tab. Select the very top entry – Next item in loading chain: 0
. Now, the first conditional should have 0 as the next item in the loading chain. But each subsequent conditional should link to the previous conditional. So F5201
should note the export number for F5200
. If we add F5202
, it should link to F5201
, etc.
So, as we can see in Figure 21, F5200
’s export number is 19. Putting this into the Hex Converter gives us Little Endian Hex of 13 00 00 00
.
Selecting Next item in loading chain
in the top pane of the Bytecode tab highlights the relevant hex in the bottom pane. As previously, we need to toggle the insert key to Overtype Mode, and change the hex so that it refers to the correct export.
In this case we need to change the hex in the red box in Figure 22 from 00 00 00 00
to 13 00 00 00
. Then save hex changes (green).
Figure 22
Now, we need to repeat steps 6a, 6b and 6c in order to link up the new conditional in the binary interpreter tab for bioautoconditionals
.
Here is how it will look after entering the correct hex and updating everything:
Figure 23
The new conditional is now functional and can be edited per Step 7.
Follow instructions in Step 8 to add further conditionals.