Jump to content

Tutorial for building NMM installer scripts.


ShinraStrife

Recommended Posts

I'm making this tutorial due to an increasing number of people asking me to build a NMM installer for them. (if a mod wants to sticky this please do)

Updated on 6/8/2016 - Added documentation on how to package INI edits with your mod (adding/changing entries in the user's INI's without having read/write access to their Documents folder)


Tools and knowledge needed:

Notepad++ - Regular notepad is awful for development. Notepad++ will color the syntax of known file types and make it much easier to edit the XML files.

Basic knowledge of XML - I recommend giving this a quick look over before going any further for people new to markup languages. You don't need to know HTML or JavaScript so you can skip all of that.

I highly recommend you type out the XML code that I provide instead of copying and pasting. Anyone who has learned a programming language before will tell you that you learn much easier this way.

If you don't want to (or don't have the time to) learn XML then you can use this program to help you create the installer. I haven't tested or used this program, nor am I the creator of it, so I can't vouch that it's working as intended. If there's something wrong with the tool please post it in the bugs/comments section of the tool's mod page and not in this thread.


Setting up the file structures:

Now that we have a basic understanding of XML and Notepad++ we can begin making our script. The first thing you want to do is move your mod's data into an organized file structure that will be easy to put into the script, and will be easy to navigate for people who do not use NMM but want to manually install your mod.

For example my mod adds some meshes and textures along with a few ESP files:

http://s30.postimg.org/kv72eo8ld/Screenshot_199.png

The esp files are named MyMod_MainPlugin.esp, MyMod_MainPluginAlternate.esp, and MyMod_OptionalPlugin.esp

MyMod_MainPlugin.esp is our mods default plugin, MyMod_MainPluginAlternate.esp is an alternate version of our plugin, and MyMod_OptionalPlugin.esp is an extra option that isn't required for the plugin to run but if users want to enable it they are free to do so.

First we make a FOMod folder with nothing in it. (NMM will look for the installer script there)

The meshes and textures folders will be put into a folder called "00 MeshesAndTextures"

The plugins also go in their own folders:

http://s30.postimg.org/qxep55x1d/Screenshot_202.png

Note that I have numbered the folders so they stay in the order they should be referenced by the script, instead of being sorted by alphabetical order.



Making info.xml:


info.xml is the file that stores information about our mod. (The name of the mod, the author, the file version, and the location of our mod on the internet)

We're going to put a new file called info.xml in our FOMod folder.

Open info.xml in Notepad++

This goes in the first line:

<?xml version="1.0" encoding="UTF-16"?> 

All this does is provide technical information to NMM about the version of XML and the encoding used. You shouldn't change anything in this line.


Next we add a set of tags called fomod:

<fomod>

</fomod> 

Inside these tags we add our next set of tags called Name inside of the fomod tags:

<Name>My Awesome Mod</Name> 

Next we add the author tags underneath our name tags:

<Author>John Cena</Author> 

Now the Version tags. You will want to edit both the MachineVersion value and the value in-between the opening and closing tag:

<Version MachineVersion="1.5">1.5</Version> 

Last, we add the URL where we uploaded our mod inside of the Website tags:

<Website>http://www.nexusmods.com/fallout4/mods/133759347</Website> 

Your info.xml file should now look something like this:

<?xml version="1.0" encoding="UTF-16"?>
<fomod>
<Name>My Awesome Mod</Name>
<Author>John Cena</Author>
<Version MachineVersion="1.5">1.5</Version>
<Website>http://www.nexusmods.com/fallout4/mods/133759347</Website>
</fomod> 

There are more tags that we could add to this file, but since NMM takes the information about your mod from your mod page when users download it with the NMM button, there's really no need for it. We just made this file so users have some basic information about where they downloaded your file if they did it manually.

That's it for our info.xml We can now start working on the actual installer script.


Making ModuleConfig.xml:

Create a new empty xml file in the same folder as our info.xml file. (FOMod)

We first add the config tags:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://qconsulting.ca/fo3/ModConfig5.0.xsd">

</config> 

The values inside xmlns:xsi and xsi:noNamespaceSchemaLocation shouldn't be changed. NMM need these values to be able to read the rest of the file.


Inside of our config tags we add 2 more tags, moduleName and ModuleImage:

<moduleName>My Awesome Mod v1.5</moduleName>
<moduleImage path="FOMod\header.jpeg"/> 

moduleName is the text displayed in the top section of the installer.

I have moduleImage referencing an image file named header.jpeg also inside our FOMod folder next to our info.xml and ModuleConfig.xml files.

You will want the image you put here to reflect your mod, like an icon or something (the image is too small to show screenshots properly so try to avoid using them)

We now add 3 more tags, an installSteps tag, inside of that we add an installStep tag, and inside of installStep we add an optionalFileGroups tag:

<installSteps order="Explicit">
    <installStep name="Base Options">
        <optionalFileGroups>
        
        </optionalFileGroups>
    </installStep>
</installSteps>  

For the installSteps tag, the order value should always be set to "Explicit"
For the installStep tag you can set the name value to whatever you want. I used "Base Options"

Basically each installStep inside of the installSteps tag is another page of options displayed to the user in NMM. We only want one page of options, so we only have one installStep tag.

The optionalFileGroups tag is where we put groups of options. In this tutorial I'm going to add 2 groups; One for the main plugin, and one for optional plugins.


Now we add a group tag and a plugins tag inside of our optionalFileGroups tag:

<group name="Main Options" type="SelectExactlyOne">
    <plugins order="Explicit">
        
    </plugins>
</group> 

In the group tag you can change name's value to whatever you wish.
You should leave type set to "SelectExactlyOne". This tells NMM that the user can only select one of the plugins that we put inside our plugins tag.

In the plugins tag there is a value called order. I have it set to "Explicit" This tells NMM that we don't want it to sort our plugins in alphabetical order, instead it should sort them in the order we put them inside of our plugins tags. If you want your plugins in this group sorted alphabetically you can delete order="Explicit" from the tag.


Next we add these tags to our plugins tag:

<plugin name="Default">
    <description>
        <![CDATA[Pick this option for the default experience of my mod.]]>
    </description>
    <image path="FOMod\Default.png"/>
    <files>
        <folder source="00 MeshesAndTextures" destination="" priority="0"/>
        <folder source="01 MainPlugin" destination="" priority="0"/>
    </files>
    <typeDescriptor>
        <type name="Optional"/>
    </typeDescriptor>
</plugin> 

In the plugins tag you have a name value. The plugin we are currently adding is the default plugin for our mod, so I have name set to "Default"

Next, inside the description tags you have a CDATA tag. If you don't know what CDATA is, don't sweat it. Its just a type of text formatting.
To edit your plugin's description you will want to edit inside of the CDATA tag what is in green:
<![CDATA[Pick this option for the default experience of my mod.]]>

Note that you shouldn't put the description in quotation marks.

Next is the image for this plugin.

You don't need to have this tag so if there is no image for your mod you can delete the tag. If you do have an image you want to use you would put the path to the image in the path value. I put all my plugins images in the FOMod folder to make it organized, and my images name is Default.png so I put "FOMod\Default.png" as the path value.

The next set of tags is declaring where NMM should get the files for this plugin from. You can have just one folder tag or a bunch of folder tags inside of the files tag. I have 2 folder tags (one for the meshes and textures, and one for the main plugin) I have left the destination value empty. You don't really need to fill in the destination value if you have the folder structure setup like the way I did it in the section above, however if you wanted NMM to install the source folder to a specific folder inside of the users Fallout 4\Data folder you would set that with the destination.

Note: The source and destination can be different. This is an example;

<folder source="Textures/WoodenSigns" destination="textures/mymod/signs/woodensigns" priority="0"/>


Last, I have the priority values set to "0". To be honest I'm not sure what the priority value is used for as I have never had to change it. It is probably used for letting NMM decide which folders can be overwritten during the mod setup but I have never had to use it, and if another mod overwrite your mod's files the priority value won't factor in at all because NMM will ask the user if it is okay to overwrite the file in question anyways and if the user okays it then the file is overwritten reguardless.

Note: NMM does not allow files to be installed outside of the Fallout 4\Data folder. This is for security reasons.

Last is the typeDescriptor tags. I have these set to "Optional". You can set them to "Required" if you have a required plugin inside a group that is set to SelectAny, but if you don't set them to Optional while inside a group set to "SelectExactlyOne" NMM will throw errors while installing saying that you can't unselect the plugins you have set to "Required"

There are more features that you can put in your plugin tags such as flags that you can use to change what options the user sees later on depending on what options they select. If you want to learn about these features you can read about them below at the end of the tutorial.


We then put another plugin in our plugins tags:

<plugin name="Alternate Version">
    <description>
        <![CDATA[Pick this option for the alternate experience of my mod.]]>
    </description>
    <image path="FOMod\Alternate.png"/>
    <files>
        <folder source="00 MeshesAndTextures" destination="" priority="0"/>
        <folder source="02 MainPluginAlternate" destination="" priority="0"/>
    </files>
    <typeDescriptor>
        <type name="Optional"/>
    </typeDescriptor>
</plugin> 

I have the plugins name set to "Alternate Version", the description set to "Pick this option for the alternate experience of my mod.", the image path set to "FOMod\Alternate.png" and have the second folder set to get its files from "02 MainPluginAlternate", I left the first file the same as the first plugin, as the alternate version of my mod will use the same meshes and textures as the default version.

We now add another group tag to our optionalFileGroups tab and a plugins tab inside of it:

<group name="Options" type="SelectAny">
    <plugins order="Explicit">

    </plugins>
</group> 

The only value that has changed compared to the group we added before is the type value. It is set to "SelectAny", so NMM will allow the user to select more than one plugin in this group or none at all if that's what they prefer.


Now we add our last plugin to the plugins tag:

<plugin name="Optional Plugin">
    <description>
        <![CDATA[This is an optional plugin, so you dont have to select it.]]>
    </description>
    <image path="FOMod\Optional.png"/>
    <files>
        <folder source="03 OptionalPlugin" destination="" priority="0"/>
    </files>
    <typeDescriptor>
        <type name="Optional"/>
    </typeDescriptor>
</plugin> 

The structure is exactly the same as the first 2 plugins we put in the "Main Options" group.

Your ModuleConfig.xml should now look something like this.

Now, we test out our new mod installer script:

http://s28.postimg.org/7bkejjfyl/Screenshot_24.png

It works!

I have uploaded the complete example mod made in this tutorial to my Dropbox. (note that the plugins are empty and don't actually do anything. they are there for examples sake)


We have covered the basics of NMM installers but there are more features we could add such as:
-Keeping track of what plugins are installed at each step so more options can be shown based on the users previous selection.
-Checking existing mods for incompatibility purposes.

I will now cover these features in-depth below.


More features for ModuleConfig.xml:

If you want to keep track of what options the user is selecting so you can show them options for specific features they chose then you would do that with conditions and visibility tags.

Lets say you wanted to present a second page with an optional plugin only if the user selects the "Alternate Version" plugin we defined earlier.

We will first add these tags in between the image and files tags:

<conditionFlags>
	<flag name="bAlternate">On</flag>
</conditionFlags>

Basically what we did here is let NMM know that if the user selects the alternate version of our mod to create a flag named "bAlternate" and set it to "On". Flags in any programming language are usually booleans, which are values that can be set to only True/False (or On/Off), NMM installer scripts are no different and we will use this flag to remember that the user selected the alternate version of your main plugin.

The alternate plugin should now look like this:

<plugin name="Alternate Version">
    <description>
        <![CDATA[Pick this option for the alternate experience of my mod.]]>
    </description>
    <image path="FOMod\Alternate.png"/>
    <conditionFlags>
        <flag name="bAlternate">On</flag>
    </conditionFlags>
    <files>
        <folder source="00 MeshesAndTextures" destination="" priority="0"/>
        <folder source="02 MainPluginAlternate" destination="" priority="0"/>
    </files>
    <typeDescriptor>
        <type name="Optional"/>
    </typeDescriptor>
</plugin>

Now we will add a new install step with the alternate version's optional plugin.

Add this code in between your closing installStep and installSteps tags (</installStep> and </installSteps>):

<installStep name="Alternate Version Options">
	<visible>
		<flagDependency value="On" flag="bAlternate"/>
	</visible>
	<optionalFileGroups>
		<group name="Alternate Version Options" type="SelectAny">
			<plugins order="Explicit">
				
			</plugins>
		</group>
	</optionalFileGroups>
</installStep>

The only real changes from this install step and the one we made earlier is a new set of tags above the optionalFileGroups tag.

The visible tag lets NMM know that it shouldn't show this installStep unless the conditions we define inside these tags are met.

The flagDependency tag is the condition that we want NMM to check for. Inside this tag we have the value set to On and the flag set to bAlternate, so this install step won't be shown to the user unless the bAlternate flag that we attached to our Alternate plugin is set to "On".

You can put any number of plugins or groups inside this install step, the same way you did before. We have setup our installStep to not show any of it if the user hasn't selected the Alternate Plugin.


Now we look at checking for existing plugins. This is a great feature if your mod conflicts with other mods and you need to give users the option to choose a compatibility patch.


These tags would replace your type descriptor tags for whatever plugin you are using as a compatibility patch:

<typeDescriptor>
    <dependencyType>
        <defaultType name="Optional"/>
        <patterns>
            <pattern>
                <dependencies operator="Or">
                    <fileDependency file="PluginWeAreCheckingFor.esp" state="Active"/>
                    <fileDependency file="PluginWeAreCheckingFor.esp" state="Inactive"/>
                </dependencies>
                <type name="Recommended"/>
            </pattern>
        </patterns>
    </dependencyType>
</typeDescriptor>

This new typeDescriptor structure looks very different from the ones used in the plugins you have made earlier but its actually quite simple.

We have a dependencyType tag that lets NMM know this plugin will be dependent on conditions we will define inside these tags.

Now we assign the defaultType for the plugin. The type should be set to "Optional" because this type will be what NMM uses if the conditions are not met (like the mod we are looking for isn't installed)

Now we add a patterns tag and inside of it a pattern tag. You can have more than one pattern tag but for simplicity sake we will use just one for this tutorial.

Now we set the dependency that NMM should be looking for inside of the dependencies tag.

It has an operator value that we have set to "Or", so NMM will check for 2 dependencies inside the dependencies tag. If one or the other aren't met the type tag underneath the dependencies tag will be ignored, and the defaultType tag will be used.

We have 2 fileDependency tags. Both are checking for the same file. One is for if the mod has been activated and one is for if the mod has been downloaded but is inactive. Either way we will know the user has the file "PluginWeAreCheckingFor.esp" inside their "Fallout 4\Data" folder.

Note: The file we want to check for doesn't have to be an esp file. it can be any file another mod adds to the game that wasn't included with vanilla Fallout 4 such as a new mesh, texture, ba2 archive, or whatever else you can check for.

The type underneath the dependencies tag will be used if the file we stated above are found, which is set to "Recommended", therefore NMM will show the user that it is recommended they enable this option.

That's pretty much it for the more advanced options when making NMM installers.



Packaging INI edits with your mod:

If your mod requires a specific setting in a users INI files then you will need to follow the instructions on this page:

http://www.creationkit.com/index.php?title=INI_files#Mod_Defined

NMM, as far as I know, can't make changes to a user's INI files, so this has to be done using the method in the link above. This method was written for Skyrim, but Fallout 4 and Skyrim are fundamentally the same, and the method will work for Fallout 4 mods.

 



If you have any questions or comments, leave em below.

Edited by ShinraStrife
Link to comment
Share on other sites

  • Replies 55
  • Created
  • Last Reply

Top Posters In This Topic

Thank you for this. Much appreciated. I searched high and low for some documentation like this.

 

There are probably other tutorials out there but since a lot of new modders are coming in for Fallout 4 (due to mods supposedly going to be allowed for consoles) I thought I'd make one and put it in the FO4 forums so people don't have to search for it.

Link to comment
Share on other sites

thanks, this will help me with my project.

 

i have some general questions about the NMM:

- can the NMM start an executable from the mod archive? (i plan to deliver a NSIS installer with my Mod, just for the ini edit)

- can the NMM ModuleConfig.xml method modify the content of .ini files?

 

- is it possible to determine the INI file that is to be modified by the script.cs method?

 

It seems that only the default fallout.ini can be modified by the script.cs method, or did i miss something?

I tried the example file from the link below, but the NMM crashes when it tries to modify the fallout.ini. Is this a know bug? Or maybe something in the NMM had changed since this tutorial (from the link) was released?

( https://zumbs.wordpress.com/2009/11/08/fomm-and-fomods-for-dummies-3/ )

Edited by Fl0W
Link to comment
Share on other sites

 

It seems that only the default fallout.ini can be modified by the script.cs method, or did i miss something?

I tried the example file from the link below, but the NMM crashes when it tries to modify the fallout.ini. Is this a know bug? Or maybe something in the NMM had changed since this tutorial (from the link) was released?

( https://zumbs.wordpress.com/2009/11/08/fomm-and-fomods-for-dummies-3/ )

 

That tutorial was written when FOMM was still popular. NMM, as far as I know, does not allow automated executables or automated INI edits. This is probably for security measures. It would be far too easy for a troll to pack a malicious exe or an INI edit that ruins the users installation.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...