I’m currently working on a game that I want people to be able to mod. I’ve searched for various options for how to do this well and I’m currently considering using asset bundles and then just packaging a Unity project with a set of customized tools that let people build content using Unity (though limited to what we want to allow) and then have the editor tool package that as an asset bundle.
I’d use LUA via http://www.moonsharp.org/ to handle scripting, and as asset bundles don’t contain executed scripts, this should alleviate any issue with a mod doing anything really nasty.
I’m curious about people’s thoughts on this approach? My thoughts were that this would allow me to utilize Unity’s animation and asset framework as well as their custom editor tools to let me just make Unity into the modding tool, rather than use Unity to build said tool into the game itself.
[quote=“ecutruin, post:1, topic: 614755, username:ecutruin”]
Are there any major pitfalls I’m not aware of?
[/quote]Debugging… Imagine modder debugging script he wrote. Also he would need tons of manuals on what he can do and what he can’t, how he can do it, what methods are available for him(her)…
One of my pitfalls with LUA is that I needed to manually specify each and every method to be exported into LUA which was awful at best. I might’ve done something wrong, but I couldn’t get LUA to get context of C# I needed without manually exposing it. I don’t know if it’s me, how LUA works or LUA realization I took was at fault - but you might encounter issue like that.
You can use C# System.Reflection instead of LUA if you want. There are a lot of tutorials if you search for “C# compile code runtime”. This allows compiling C# classes, methods, etc runtime too while not requiring any additional interpreting modules and/or dlls.
I indeed planned on using Moonsharp in the hard sandbox mode and opening additional functions that I see fit. I would of course, document the API and even provide examples. We’d use the very same API and tools to build the core game experience.
As far as debugging specifically goes, a lot of the core engine would not be written in LUA. My aim with modding is to allow people to create content for the experience we created. Creating a new experience all together is not the goal. However, I’m sure someone being creative with what they are given could do so.
When I asked about pitfalls, I’m more curious about pitfalls with using assetbundles as the medium in which mods are handled. Could I say provide an asset bundle with the core game assets with the game itself, then in the tools, let you utilize said assets to reference them for your mod, or would I have to provide the assets raw, in the assets folder?
I’m not sure what kind of limitations assetbundles have in regards to their usage, so I’m not sure if they are the right fit for what I am trying to accomplish.
Yes, you can. You just need to load it runtime on start. Just don’t forget loading it takes a little bit of time after load gets called. You still need some scene with something that calls asset bundle loading.
As long as they’re in loaded asset pack and you get them by reference from some object included in scene or use Resources.Load no problem. Just don’t forget that unreferenced objects that are not in resources folder during compile might not get included.
Unity has problems with importing things this way. Some things can be imported(like sounds through WWW), but 3D models can’t (requires external importer). So it’s reverse: some assets (models or animations or such) can only be loaded through asset packs without using 3rd party asset packages/import scripts and some can’t be loaded at all(shaders in Unity 5+). Let me just say: I’ve seen some games do workarounds to import assets from outside of asset bundles, and solutions weren’t exactly pretty.
Using asset packs has only one cons: You need to have Unity installed to create it (might not make some modders happy if they want to add something specific, but whatever, Unity is mostly free now for those purposes).
Um… No. I just watch topics with 0 replies depending on mood and sometimes it happens very frequently.
This sounds like you’re assuming I’d want to load the assets through a non-direct Unity means. I was referring to loading them from an asset bundle. I’m wondering if I can supply an asset bundle with the game and then let a mod author select said asset bundle in Unity to be able to place its assets in his mod areas.
Basically, keep everything in Unity. I’d have to write a LUA editor for Unity, to make it nicer to implement packaging the LUA into the asset bundle, but w/e…that’s what we’d use to make the game as well.
All in all, what I'm thinking of doing is creating a set of Unity extensions that use Unity's system to create content (custom editors and such), which will package the assets into an asset bundle, which can then be loaded as a mod for the game. Of course, the main assets of the game would ALSO be built using this same set of tools.
The main game would then have the remaining code and such to actually make use of the assets and let the player interact with them in the way we desire. I am wondering about shader coding. Can shaders actually be stored into asset bundles normally? Or will we be limited to only references to shaders (in which case, said shader would have to be supplied as a non-asset bundle asset).
Its questions like these that I'm curious about. What all is able to be stored into asset bundles and what all can be loaded from them. How can these asset bundles be used as well. Can they be used when editing? Or are they only available to the game during its run-time?
[quote=“ecutruin, post:5, topic: 614755, username:ecutruin”]
. Can shaders actually be stored into asset bundles normally?
[/quote]Yes, they can. Unity 5 (or was it 4.5+?) stated that you can’t compile shaders runtime now. Asset bundles include precompiled shaders, not raw text (unless changing .shader file type to something else).
Everything you can import into Unity can be included into asset bundles (models, images, sounds, libraries(dlls), shaders, scripts, byte arrays, scenes, prefabs, fonts, etc). Just make sure no scene/prefab references somewhere outside of what’s loaded currently(into another asset bundle for example) or you might get null reference instead.
It’s possible to create asset bundle from part of your currently loaded assets in editor by assigning which asset should be in which bundle like stated here http://docs.unity3d.com/Manual/BuildingAssetBundles.html. It’s usually created like that anyway. This way during Editor all assets are available without any problems; during runtime you need, however, use AssetBundle.LoadAsset or AssetBundle.LoadAssetAsync to load objects from another bundle.
Thanks for your reply, but you’ve not really answered the question. I know I can build assets in the editor and use them in the game, but can I re-use them as an asset bundle in the editor. I would prefer to not give mod authors my full assets outside of an assset bundle, in order for them to mod.
So, when they download the Unity project to mod, it would contain the tools we write (compiled into DLL) and they would have to point to the game’s asset bundle to use it to create content. This possible?
Yes, you can. You can reuse it in any way in any Unity project. It’s just package and any Unity project(including Editor extensions) can load assets from it. It’s just you won’t be able to drag’n’drop from external asset bundle onto scene in project(unless you make Editor extension for that), but need to load it from bundle and instantiate in script.
Thanks! So, to let people use my game’s asset bundle in the editor to make mods, I’ll just need my mod extension to instantiate the assets so that they can lay them out on their custom environments in the editor. No problem, that’ll work well for what I want to do.
Wouldn’t they be saved when the new mod’s asset bundle is created? So, if I instance say an animated character from my asset bundle and place it in the scene and they add a new animation… when I save it back…it’ll save it back, right?
Uhm… Asset bundle can store scene, sure. But how are you going to ‘overwrite’ scene in main asset bundle you provided and be sure it won’t break?
Into original Asset Bundle - nope. Afaik, Unity can’t repack asset bundle. Main problem is that you want to load original scene, allow modders to change and save it. That’s advanced modding that’s not really supported by unity out-of-box.
So you would need to specify which asset bundle you want to load scene now. But that would create problems if several mods modify several objects on one scene in different ways. How do you merge those scenes? If you just use latest scene, that’s easy. Otherwise… Not. Before saving scene you would need to detect which objects did change and which did not, then runtime detect which objects we need to modify compared to base scene and which we do not (as you can’t load with overwriting objects of scene - it will just duplicate them) and making sure we load, but remove duplicate copies…
Or maybe not store data in scenes? I see two ways with that (maybe there’s more, it’s just what I came with on-spot):
First simple way - don’t use scenes at all. No simple drag’n’drop will hurt, yes, but everything can be managed from code. If you’re not using unity scenes at all - it’s much easier as everything is instantiated in code and you don’t need to think about “saving/loading scene” - it’s hardcoded already.
Another way is to store scenes as your own format converted into byte array. This way you can convert all objects on “scene” to byte array and store that (maybe use serialization/desrialization to store in separate file on disk) and write small arrays of what’s modified and which asset bundle to take which resource from (like Bethesda’s master file(esm), resource file(bsa as I remember) and mod files (esp) but in your case it’s master file(base byte/object array), resource file(asset bundle), mod file(modifications on byte/object array)). It’s tricky, but with Unity Editor extensions you can load a “scene” from byte array and monitor its changes then write them into byte array with new dependencies on asset bundles.
Also saving/loading all data might be same(or almost same) as saving/loading game runtime so you might skip double work (at least partially).
Also additional information to think:
Why do you think Bethesda games ask you “This relies on content no longer available. Continue?”. Why X Rebirth games almost always break when you remove mods?
I was not thinking of saving back to the original asset bundle, no.
I think the idea of not actually using the scene is the way I’d want to do things. I’d probably loop through each object and store their position into a byte file, which is stored into the asset bundle (along with any new prefabs and/or animations created). I’d also have some basic mod info stored like version, API version (for my LUA API), etc. This would let the game itself refused to load out-dated mods.
I suppose I could tie mod info to individual objects as well (using a custom compile to asset bundle system, building the extra byte data as part of the prefab). This would let me, on loading of a world, remove references to content which no longer exists from the world.