Last week, I began working on modding support for Academia. I have to pause development at least this week in lieu of bug fixing. I have vastly underestimated the amount of initial work that I have to do to make it work. For this post, I would like to add to the very few resources of this topic and hopefully help others prepare their Unity game better.

From the very beginning, we have decided to include modding support. It’s important to make this decision before making the game as it will affect the implementation details. In our case, we used StreamingAssets to load our images and text data in the game. What this means is we load the assets as if they are external files. The assets are not packed in Unity’s own format when the game is built. The files of these assets remain as is and are contained in the StreamingAssets folder. The reason for doing this is we want to be able to load files in other folders that would be specified by modders.

As a lesson, your game should be able to load assets in other folders, not just in StreamingAssets. I had this assumption that mod files from Steam Workshop could be downloaded to the StreamingAssets folder and I can load it from there. Nope! Steam downloads the mod files from Steam Workshop into folders that are maintained in the Steam library folder. The mod folder is usually in {Steam Library}/{Steam Game ID}/{Workshop ID}. Because of this, your game should be able to accept a different folder and load assets in that specified folder. For example:

// Instead of this: private Texture2D Load(string assetPath) { string fullPath = Path.Combine(Application.streamingAssetsPath, assetPath); ... } // Use something like this private Texture2D Load(string baseFolder, string assetPath) { string fullPath = Path.Combine(baseFolder, assetPath); ... } // Use it like this to load assets from Application.streamingAssetsPath Texture2D texture = Load(Application.streamingAssetsPath, "SomeSprite.png");

In other words, your asset management system should be flexible enough to load other folders.

Another difficulty I had is the implementation of the Steam Workshop API itself. We are using Steamworks.NET to interface with Steam. While the Steam Workshop API is readily available with it, it’s not that easy to understand. You still have to wrap the API calls to make it manageable for your use. This could take days to make. To save time, I bought an asset, instead. While I didn’t like its predefined prefabs (which is how you use the asset), I did use its wrapper class for querying workshop items and downloading them.

The next challenge I had is the mod installation management. I wanted players to be able to install and stack multiple mods. This meant that I needed to have some kind of internal mods database and provide a UI for it. Implementation of this thing took the whole week.

Aside from this, a system for testing/uploading/updating mods would also be needed. I plan to add this system as a tab to this screen. Loading assets from any folder would be valuable here. I imagine that the mod developer can specify the full path to his/her mod folder. Then he/she can subscribe to this local folder so he/she can test his/her creation. There will also be buttons for uploading/updating the mod. This is why I had to stop because it may take up the whole week again and I still have lots of bugs to fix.

There you have it. These are the considerations that I had thought while implementing the mod support. Hope these will help you on yours.