Disclaimer: The game doesn't actually work exactly like this. This is how it logically works. As in, if you had to describe the decision process the game goes through, this is it. Realistically, working this way would be a waste of resources and processing time (why load up every file, when you already know a different one is going to "win"?). It's just much easier to understand if you think of it like this. A good description of how it would actually work is http://www.gamesas.com/topic/1345724-important-bsas-and-you/page__view__findpost__p__20282031.
Ok, I've gone through and anolyzed Skyrim's process for loading resources (all the meshes, textures, etc in the Data folder). For the most part, it works fine, just like it did in Oblivion. There are some improvements (two BSAs with the same resource will no longer cause a crash), but there's also a major drawback now.
Contents:
- Resource Load Order
- Registered BSAs
- Loose Files
- Plugin BSAs
- Registered BSAs
- What This Means For You
- Mod Makers
- Mod Users
- Mod Managers
- Bethesda
- If All Else Fails
- Mod Makers
- Other Questions
- Replacing Scripts
- Directory Thrasing
- Are You Sure?
- What are all these terms you use?
- Replacing Scripts
- A Quick Workaround
- Tools
- DDSopt
- SKSE
- DDSopt
1. Resource Load Order
Skyrim loads its resources from the Data folder. Makes sense. These resources can also be packed up into a nice neat little archive, called a BSA. These are gamesas's custom archive files, and internally they mirror the layout of the Data folder. They're nice, because they keep the Data folder uncluttered, and it makes it really easy to remove every file from one mod.
Ok, but what happens when the same resource exists in more than one place? For example http://img401.imageshack.us/img401/9967/dummyn.jpg, which is the texture for the map you see all the time in castles, with the little flags and stuff sticking out of them. This file exists in Skyrim - Textures.bsa. That's the original file. If you download a texture replacer, you'll get it as a loose file probably, and if you download HD Skyrimmap from Steam Workshop, you'll get that file in a BSA. So which file actually gets used? Well, which ever one is loaded last. The game loads resources in three stages, with the last files loaded being what you see in game:
Update: Further investigation reveals that only Registered BSAs and Loose Files are loaded when the game first loads. That means anything in a Plugin BSA won't take effect yet - but you'll only notice that if you're trying to replace a Main Menu asset, like http://skyrim.nexusmods.com/downloads/file.php?id=7801. Once you start a game, either by loading a saved game or starting a new one, then the Plugin BSAs are loaded. So in the example of Brumbek's Main Menu Logo replacer, if it's loaded via a Plugin BSA (like it is when installed via Steam Workshop), you won't see the spinning logo until you load a game, then exit back to the Main Menu.
Registered BSAs:
First, the game reads your Skyrim.ini file. There's a section that tells the game which BSAs to load. I looks like this for most people:
[Archive]sResourceArchiveList=Skyrim - Misc.bsa, Skyrim - Shaders.bsa, Skyrim - Textures.bsa, Skyrim - Interface.bsa, Skyrim - Animations.bsa, Skyrim - Meshes.bsa, Skyrim - Sounds.bsasResourceArchiveList2=Skyrim - Voices.bsa, Skyrim - Voicesixtra.bsaThe game will load the BSAs in order as listed, BSAs in sResourceArchiveList first, and sResourceArchiveList2 second. So if you manually register a texture replacer BSA (like the HD Texture packs), but put it at the beginning of the list - they won't load! Because the Skrim - Textures.bsa will override them of course. If you put it after, or at the end of the list on the second entry, then they will load.
Easy enough.
Note: In Oblivion, there was a 255 max character limit for this entry. I didn't test it this time around, but I think it's a safe bet to say that limit still exists, otherwise there wouldn't be two entries for BSAs. This character limit is why registering BSAs is a bad practice - get enough in there, and you won't be able to put any more in it.
Update: Tannin42 has confirmed that this is the limit for each entry. That means we've got a maximum number of BSAs that can be registered between these two entries.
Note 2: These are the only two entries that work, also. I tried adding a sResourceArchiveList3, etc, but they don't load BSAs, so we only have two 255 max character entries to work with.
Loose Files:
This one's simple. If the file exists in the Data folder, it loads after any of the registered BSAs, so it'll always win. This is how most texture replacers work, and this is what mod managers like Wrye Bash or NMM are made for. Managing the Loose Files so you don't have to track them yourself. It's easy to keep track of which file came from which installer when you only have 3 mods. But when you get up to 150 mods, each with their own resources, a lot of them overlapping, a mod manager just takes the headache out of it.
Note: In Oblivion, Loose Files would only win if their modification date was "newer" than the BSA that also contained the file. This is not true anymore, Loose Files always override a registered BSA, but never override a BSA loaded via Plugin.
Plugin ESPs
When the game loads an active ESP, it also looks for a BSA of the same name (for the most part, some additional variation allows one plugin to load multiple BSAs, but that's not important for this discussion). So dummy.esp will make the game load dummy.bsa. This is true even if the ESP does absolutely nothing (for example, the official HD Texture packs do this, in Oblivion, the Shivering Isles assets were loaded like this). Cool! We found an easy way to make our replacement texture only load when we want! Just deactivate the plugin and they don't load, activate it and they do!
Yes, but...
This first point is an old one. Due to the way the game indexes plugins and stores the data in your save game, you can only have 256 active mod files. That's because objects are referenced by what's called a FormID, which is a 32-bit (4-byte) unique number, usually written as a 8-digit hexadecimal number. The first two hex digits are used to identify which mod the data came from. Two hex digits can represent a maximum of 256 unique numbers (0-255). Now, Skyrim.esm and Update.esm will always fill up two of those. Another one that's not obvious is your saved game itself - this one is always assigned the ID of hexadecimal FF, or 255. That leaves room for 253 other plugins. And here we get to our point: dummy plugins that don't do anything at all, but exist solely to make the game load a BSA? Yep, those take up one of our plugin slots. This might not seem like a big deal, but once you start trying to play with 300+ mods, you'll be faced with the hard decision of deactivating some mods. Luckily, dummy plugins you can just unpack the BSA and use the resources as Loose Files, then you don't need the plugin anymore. Other plugins can be merged via Wrye Bash into the Bashed Patch, further cutting down your mod count. And hopefully an equivalent of TES4Gecko will come out eventually, which will be able to merge mods into a single plugin. This last one however has an impact on your saved games, so it's for the more advanced user only.
And now for the second point. This here is something new, and it's why I've written this post for you guys.
What happens when two Plugin-loaded BSAs have the same file in it? For example, I did my testing with HD Skryimmap above, plus another BSA I created with the same texture, but I scribbled graffiti on it so I could tell which one was loading: Vanilla (Skryim - Textures.bsa), HD Skyrimmap (hd_skyrimmap.bsa), or mine (dummy.bsa). Well, the results are Bad News.
When the game is loading up the BSAs associated with plugins, it doesn't do it in a way that would make sense for modding. If it loaded them similar to plugins, where modification time determines Load Order, that would make sense. That would mean that a plugin with a BSA that was modified on 2/1/2012 would load after a BSA modified on 1/1/2012, meaning that the "newer" BSA would win, and you'd see its resources in game. Nope! Sorry, doesn't work that way. Ok, how about tying the BSAs in with Load Order? That would make sense, even if it takes away control from the user on which resources they want to see (it couples Load Order with Install Order). In this scenario, if hd_skyrimmap.esp loaded after dummy.esp, the hd_skyrimmap.bsa resources would load later, and win. Nope! Also, not the case.
Well, how does it work then? Kinda silly, and not helpful at all for modding. BSAs (only the ones associated with active plugins), are loaded in alpha-numeric, case-insensitive order! What!? Why!? Well, if you know about filesystems, it makes sense: when a program asks the filesystem for a list of files in a specific directory, the usual response is a list of files in alpha-numeric order. On Windows (read: the filesystems that Windows uses), filenames are case-insensitive as well. So Skyrim will ALWAYS load hd_skyrimmap.bsa AFTER dummy.bsa, meaning I can never get my dummy ESP's BSA to override and win. Well, I could rename it to zDummy.bsa and zDummy.esp (in fact, I did, for testing). That makes my dummy textures load, and they're used in game.
Ok, but that's NOT a good way to change load order, because renaming plugins causes all sorts of other problems. Remember how we talked about FormIDs before? Well that unique number assigned to each plugin in your saved game is assigned to the plugin name. So if you change the name, the game will throw out any data associated with it, since it's associated with the plugin called "dummy.esp", NOT with the plugin called "zDummy.esp". This is how you end up losing all of your items you stored in a chest in a player created home when you update the plugin. Because the author changed the name from myhome_v1.esp to myhome_v2.esp. Also, other plugins that either patch yours, or build on it, reference your plugin by filename as well! So now by changing the name, you've ensured that any plugin that needs yours as a master won't work anymore.
Another small strangeness associated with Plugin BSAs - they aren't loaded until you load either a saved game, or start a new game. That means if you're still at the Main Menu for the first time, any replacers loaded this way haven't taken effect yet! Woah! Not a big deal, unless you're trying to replace the Main Menu Logo...http://skyrim.nexusmods.com/downloads/file.php?id=7801. That mod works fine when installed as Loose Files, or if the BSA is registered in your Skyrim.ini, but it only works as a Plugin BSA after loading a saved game.
Note: Makes sense really from a design standpoint - it means the game doesn't have to search through all of your BSAs when it first starts up. That cuts down on the initial startup time.
2. What This Means For You
Mod Users:
Did you understand all of that? Great! That means I'm not a horrible writer after all. Didn't understand it? Don't care? Didn't read it? That's fine, my advice is the same no matter what:
Update: shadeMe has released a SKSE plugin that provides an alternate method of controlling BSA Load Order. Check out Section 4 "A Quick Workaround" for more information.
If you don't want to go the SKSE route, unpack all BSAs associated with mods. Don't register them in Skyrim.ini, I've already talked about the 255 character limit for those entries, and you'll run out of space quick if you have a lot of mods. With each mod, unpack its BSA, then zip those Loose Files up along with any documentation and plugins into an archive. Then you can install and manage that archive with your favorite mod manager. If you want, you can also examine the ESP. If it's an empty ESP just there to load the BSA, toss it, you don't need it anymore. If you don't know how to check for empty ESPs using TESSnip or a similar utility, another way to do so is right click on the mod in Wrye Bash and select 'Mark Mergeable...'. If the plugin is empty, Wrye Bash will say so in the results of that scan.
And if you need a good tool for unpacking BSAs, check out http://obge.paradice-insight.us/wiki/DDSopt.
Mod Makers:
Don't package replacement files into BSAs. I know, it's hard to do that with the CK, since it gives you no control over which files it packages. Not to mention the fact that you can only upload files to Steam Workshop as an ESP/BSA pair. Don't take this as Steam hating, but right now Steam Workshop is too messed up. This issue with BSAs is one problem. Another issue (that will hopefully get fixed), is that Steam Workshop will redownload a mod if the modification date changes. That means if you change the Load Order of a mod, Steam Workshop downloads it again! Waste of bandwidth, plus it messes up your Load Order all over again.
Don't package any files into a BSA if you can avoid it. It'll be easier in the long run. This is, of course, modder's preference. But, even NEW resources loading as a BSA - they can't be overriden by Loose Files anymore. This means if you discover a problem with a mesh in your mod, you can't just release the replacement mesh and have it override the BSA mesh. You have to repackage the whole BSA again. Not a big deal for smaller mods, but when your BSA is 500 MB, that's a pain to upload, and a pain to download for just one mesh fix.
Don't change plugin names unless you have good reason to. There are times when changing plugin names makes sense. It's NOT a good idea to change the name just because the version changed, or you added stuff, or you want the associated BSA to load last.
If Steam Workshop is a must for you, encourage your users to unpack the BSA, and leave the plugin deactivated. That only works for dummy ESPs though. If your plugin actually does something other than load the BSA, now they'd need to unpack and delete the BSA. But...now Steam Workshop will want to download it again, so they'll have to unsubscribe, which means if you update the mod, they won't get updates. Ugh!
Mod Managers:
Come up with a good workaround to all this mess. My plan for Wrye Bash is multi-staged:
- When installing mods via BAIN, (optionally) unpack any BSA in the package, and install just Loose Files instead. This will require more processing on BAIN's part, since BAIN needs detailed knowledge on the contents of the BSAs now. That means when scanning a package, it'll have to extract any BSAs, then parse them for a file listing, plus CRC information.
- If a BSA that isn't registered in Skyrim.ini is found, offer to unpack it into a BAIN package, then delete the BSA. Additionally, after doing so, if the ESP that loads the plugin is an empty one (has no records), offer to delete the plugin as well.
- I'll be working with ianpatt on this one, and it'll probably take quite some time. Interface with Steam Workshop via its API to access mods on the Steam Workshop. This way we can bypass the Steam interface altogether, download mods to a temp directory, unpack their BSAs, and make a good BAIN package out of it. Updates will still work this way, since Wrye Bash will be able to check with Steam and download new updates, then apply them in the same way to the custom BAIN pacakge.
Hopefully Dark0ne and the NMM mantainers can come up with a solution as well, so their users can play a modded Skyrim the way it's meant to be played as well.
Bethesda:
Please, please fix the issue with Plugin BSAs Load Order! Probably the best method for modders is make them load chronologically by file modification time, basically like how Load Order is determined for plugins. I'd plead to NOT make them load based on their plugin's Load Order, because then you're tying Install Order (what resources you see) in with Load Order (what changes to the game are made). We enjoy having our Install Order and Load Order decoupled, please keep it that way!
Also, it's still important to be able to override these Plugin BSAs with Loose Files if we want to!
And another issue that's come up: replacement scripts in Plugin BSAs don't actually replace the original script. If it's loaded as a Loose File or from a Registered BSA, it'll replace the script, but not from a Plugin BSA. Obviously with Steam Workshop using BSAs, that's something that we'd love to have fixed as well.
If All Else Fails:
Well, I suppose we could write a SKSE or SD plugin that hacks the BSA loading code, and implements a saner version ourselves. Still, it'd be WAY easier to just have gamesas fix this.
3. Other Questions
Replacing Scripts
There's been a couple reports that trying to replace a Vanilla Script file with one in a Plugin BSA isn't working. New scripts seem to work fine, it's just if you're trying to replace one of the original scripts. A good example of why you might want to do this: Vamprism overhauls. You'd want to replace the script(s) that control Vamprism, and if you release this mod as a BSA, those replacement scripts will be in your BSA. So far the results of testing indicate that the replacement script will be used if it's either a Loose File or in a Registered BSA, but not a Plugin BSA.
Some more investigation still needs to be done:
- Verify that this only affects Vanilla scripts, and if so, is it all of them, or just some of them?
- Is there some way to get the replacement scripts to load, even when used in BSAs?
Directory Thrashing
What is it? http://wiki.tesnexus.com/index.php/Oblivion.exe_file_and_directory_thrashing. Basically, simply having too many ESP, ESM, and BSA files (even inactive) in the data directory would cause Oblivion to go crazy, bringing your game to a crawl as disk I/O went through the roof. It's why Wrye Bash has the Auto-Ghost feature.
Does it affect Skyrim? I don't know, I didn't really feel like making 400+ plugins to test this out. Not to mention that there was never a reliable number anyone could pin down that triggered it. But, if it does affect Skryim, there's another good reason to not use BSAs at all. Loose Files didn't trigger it for Oblivion, which is why a lot of modders didn't use them (BSAs).
Are You Sure?
Yes. I did all of my testing with a fresh install of Skyrim, updated to the current 1.4 patch. I then installed http://steamcommunity.com/sharedfiles/filedetails/?id=7540 from Steam Workshop, which modifies the map texture file I mentioned. Then I unpacked that BSA, edited the textures in Paint.NET (spray'd graffiti on them), and packed those into another BSA, called dummy.bsa, and made a dummy (blank) ESP to load it, dummy.esp. I then went on to test every conceivable (to me) combination - redating BSAs, rearranging plugin Load Order, registering the BSAs in various points in the lists in Skyrim.ini, even renaming files to make them sort differently alphabetically at one point. Another point brought up - I completely exited the game each time between changes. That makes sure the texture is in fact loaded from the files, instead of already existing in the RAM (in which case, the game wouldn't load it, it's already loaded). I wrote it all down as I went to make sure I didn't leave anything out. I'm very sure this is what's going on (not that it's much different from previous games).
Additionally, after Brumbek's issue with the Main Menu Logo replacer came up, I did some further testing with http://technet.microsoft.com/en-us/sysinternals/bb896645 running to log what file accessing Skryim was doing. It's helped nail down some specifics.
What are all these terms you use?
I used a bunch of terminology here, most of it old, but there's a couple new terms I made up for this explanation.
- Plugin - any .esp or .esm file.
- ESM - Elder Scrolls Master. Usually saved as a .esm file, which has the same format as a .esp file, only one bit (as in, one bit of a byte) is different.
- ESP - Elder Scrolls Plugin. Most mods are ESPs, but some are ESMs. Their format is the same, but the game handles them slightly differently in some specific cases.
- ESS - Elder Scrolls Save. Your saved games. This is loaded after all the ESPs and ESMs are loaded, so that its changes (like what items are in which containers) can override what the plugins say.
- BSA - Bethesda Softworks Archive. Sort of like a .zip file, but specific to gamesas's games, and optimized (sort of) for their specific usage.
- Load Order - The order that your mods (ESPs and ESMs) are loaded. When conflicts occur, the last loaded conflict "wins".
- Install Order - The order that files are installed into your Data folder. When multiple packages install the same file, the last installed package "wins".
- BSA Load Order - The order that the game engine loads BSAs. When conflicts in data files occur, the last loaded BSA "wins".
- Plugin BSA - A BSA that the engine loads because an ESP/ESM with the same name is active.
- Registered BSA - A BSA that the engine loads because it's listed in Skyrim.ini.
- Loose File(s) - A resource file in the Data folder that's "loose", as in not packaged into a BSA.
- FormID - A unique ID assigned to each "record" of a plugin. Each object in the game is defined by a record, and each record has a FormID. A FormID is 32-bits, with the first 8 bits defining which ESM or ESP the record belongs to.
- SKSE - Skyrim Script Extender. A nice utility that everyone should be using. It aims to extend the functions available to scripts written for Skyrim. It's also useful as DLL loader, if one wants to inject some code into Skyrim's game engine.
- SD - Script Dragon. Another DLL loader, but with a different goal in mind than SKSE. Both can work along side each other.
4. A Quick Workaround
Thanks to shadeMe (author of the CSE and other great tools), we have a fix for the 255 character limit on Skyrim.ini string entries. It's in the form of a http://skse.silverlock.org/ plugin. I'll walk you through setting it up and using it to get around these BSA loading issues.
1. Install SKSE
Visit http://skse.silverlock.org/ and download the latest stable version of SKSE. Inside the download there should be a few files: an EXE, a couple DLLs, a readme, and the source code for SKSE. If information in the readme contradicts what I say here, follow the readme - it'll be more up to date than what I have here. Just extract the EXE (skse_loader.exe) and the DLLs into your Skyrim root folder (this means the same folder that has TESV.exe and SkyrimLauncher.exe). When you launch the game, instead of using the Steam interface, first just make sure Steam is already running, and use the EXE provided by SKSE to launch the game.
2. Install Nitpick
Download: http://dl.dropbox.com/u/2584752/Nitpick.dll - For Skryim version 1.4.21 only
Download: http://skyrim.nexusmods.com/downloads/file.php?id=9591 - All Skyrim versions.
Source: https://github.com/shadeMe/Nitpick | https://github.com/lojack5/Nitpick
This is the DLL provided by shadeMe. Put the DLL here:
skyrim\Data\SKSE\Plugins\Nitpick.dllYou can create the folders if they don't exist.
3. Setup your BSAs
This is the trickiest part. If you Register a BSA, and it later gets loaded by a Plugin, the Load Order of that BSA effectively gets reset, and it's the same as if that BSA was never loaded via Registering it. This means any BSA you want to register in Skyrim.ini must not be loaded via a Plugin later on. You have two options here:
- If the ESP used to load the BSA is empty, you can simply deactivate the ESP or delete it.
- If the ESP used to load the BSA is not empty (for example, the Open Cities ESP), then you will need to make sure the ESP will no longer load the BSA. The best way to do this is to rename the BSA. Be sure you're not subscribed to the mod in Steam Workshop anymore, otherwise it will download the BSA again.
3. Edit your Skyrim.ini
Open the Skryim.ini in your My Games\Skyrim folder, and find this section:
[Archive]sResourceArchiveList=Skyrim - Misc.bsa, Skyrim - Shaders.bsa, Skyrim - Textures.bsa, Skyrim - Interface.bsa, Skyrim - Animations.bsa, Skyrim - Meshes.bsa, Skyrim - Sounds.bsasResourceArchiveList2=Skyrim - Voices.bsa, Skyrim - Voicesixtra.bsaHere, you want to add in the BSAs you want to load. Remember that BSAs are loaded in the order they are listed, so the textures and meshes you want to have higher priority should be listed later.
With the Nitpick SKSE plugin provided by shadeMe, the limit on these entries has been extended to around 32KB - basically, you'd have to be insane to be able to ever reach this many characters.
4. Pro's and Cons
Pro's:
- Since all of your BSAs are loaded via the Skyrim.ini now, Loose Files will again override your BSAs. That means for example, that you can use the HD Texture packs in conjunction with other user released HD Texture packs.
- Ordering of BSAs is easy to understand - they're loaded in the order listed in Skyrim.ini
- To get the most benifits, all BSAs should be Registered BSAs. Right now, that means manual editing of Skyrim.ini, and manually editing it each time you want to change the BSA Load Order. In the future, Mod Managers will be able to make this process simple for you (I have plans for Wrye Bash to do it, but I can't speak for NMM).
- You need to rename the BSAs. This is required so the game doesn't load them as Plugin BSAs. This of course, brings the problem of Steam Workshop downloading the mod again once it detects that the file is missing. Again, this can be alleviated in the future with another SKSE plugin that would trick the game into thinking the BSAs aren't there.
- It relies on a specific game version. This means once a new patch is released, this plugin will have to be updated with the new location in the EXE to edit. I'll be working on some methods so this won't require a new plugin, but at most an INI edit for the plugin. This of course will mean that it's very possible the plugin will be updated before SKSE can support the new game version.
Tools
DDSopt
Use this for unpacking BSAs. You can also use it to create new BSAs as well as optimize textures. Ethatron recommends this in place of BSAopt, since it's all inclusive and uses the same code as BSAopt. You can still use BSAopt if you like, but if you ever find the need to use DDSopt then there's no point in keeping both of them.
http://www.skyrimnexus.com/downloads/file.php?id=5755 | http://obge.paradice-insight.us/wiki/DDSopt
Skyrim Script Extender
You'll need this if you want to use http://skyrim.nexusmods.com/downloads/file.php?id=9591. It's also used for other great mods, and with the CK out, it'll only get more important. The only disadvantage is that after each game update, SKSE must also get updated to work with the new EXE.
http://skse.silverlock.org