Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Open Source] ModTool - Mod Support for Unity

Discussion in 'Assets and Asset Store' started by HelloMeow, Nov 21, 2016.

  1. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    ModTool makes it easy to add mod support to your game. It enables modders to use the Unity Editor to create scenes, prefabs and code and export them as mods for your game.

    To make sure the modder's scripts or Assemblies will be compatible with the game, ModTool has a simple but powerful code validator, that lets you configure any number of requirements.

    ModTool creates a custom unitypackage for each project, which includes everything to create and export mods.

    Features:
    • Let modders use the Unity editor to create scenes, prefabs and code for your game
    • Scripts and assemblies are fully supported
    • Code validation
    • Supports Windows, OS X, Linux and Android
    • Mod conflict detection
    • Automatic Mod discovery
    • Asynchronous discovery and loading of mods
    See the documentation for more information about features, limitations and how to use ModTool.




     
    Last edited: Jun 7, 2022
  2. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Added a demo, a video, some screenshots and ModTool is now submitted to the asset store and is pending review.
     
  3. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
  4. LennartJohansen

    LennartJohansen

    Joined:
    Dec 1, 2014
    Posts:
    2,394
    Looks interesting, is the code from the mods/asset bundles loaded using reflection?
     
  5. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Yep. Before export, all assets are modified so they reference Unity's script assemblies directly. This makes it possible to use scripts with asset bundles.
     
  6. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    Hi there,

    I'm curious about the code validation feature, how practical and reliable would you say it is to prevents mods from doing unsafe operations from a computer security perspective (mostly IO and IPC stuff, sockets, files etc) ?
     
  7. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    You can restrict the use of entire namespaces, specific Types or even Type members like methods. Which ones you want to restrict is up to you.

    This is checked before a mod is made available in the game. If it fails to meet any of the restrictions, it won't be made available. It is also checked before exporting the mod, both to inform the mod's developer and to prevent the mod from being exported in the first place.

    Other than that it's not sandboxed. I'm sure there are ways around it, but not from within the mod itself.
     
    _met44 likes this.
  8. _met44

    _met44

    Joined:
    Jun 1, 2013
    Posts:
    633
    Hmm that sounds like what I'm looking for.

    Some players have already made a modding system using Mono.Cecil to modify game DLLs and it brings a nice modding support but it can't be officially supported it because its not safe... How players modify the local game files is really their own choice and risk if they use thirst party software, but for us to provide an official modding solution it has to be safe and not put people computer at risk.
     
  9. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    I have identified and fixed a number of issues and added some minor new features.

    Version 1.0.2:

    -Added loadProgress property and LoadProgress event for Mod and ModScene (requested feature)
    -Added null check and warning for uninitialized ModBehaviours

    -Fix for rare circumstance where exporting would stop
    -Save any unsaved scenes before exporting instead of only pre-existing unsaved scenes
    -Prevent play mode when exporting
    -Ignore unmanaged assemblies
    -Fix for issue with scene names where path includes the scene name more than once
    -Update mods collection after any potential modification to the collection
     
    Last edited: Feb 7, 2017
  10. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Any chance of iOS support?
     
  11. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Unfortunately there is no way for me to build or test for that platform, and I am not familiar with any platform specific differences. I could add the platform, but I can't guarantee it would function properly, and I wouldn't be able to provide support for it.
     
  12. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Ok, we would be willing to work with you to get this working potentially, we have devices we can test on. If this is something you would be willing to work with us on please let me know.
     
  13. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    I would be up for it, but after doing some more research I am afraid that it is not possible. Loading assemblies is not supported by Unity on iOS, and Apple does not allow it. See the iOS developer agreement section 3.3.2.
     
  14. mimminito

    mimminito

    Joined:
    Feb 10, 2010
    Posts:
    780
    Ah right, thanks for the update.
     
  15. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Version 1.1.0 is now available! It includes some bug fixes, new features and support for .net 4.6 in Unity 2017.

    Version 1.1.0:
    -Added ModManager.Refresh and ModManager.RefreshInterval to enable refreshing and auto refreshing of mods
    -Added ModInfo.version and a version field for the mod exporter
    -Removed Component constraint from GetComponent methods, so interfaces can be used as well
    -Mods no longer have to be enabled to be loaded. Mod.isEnabled can be used as a convenient way to keep track of which mods the user wants to use
    -Added support for ScriptableObject assets
    -Added Mod.GetAsset methods for loading any asset type (support for including and exporting any asset type is planned)
    -Renamed ModContent.Prefabs to Assets
    -Renamed Mod.prefabPaths to assetPaths
    -Added .Net 4.6 compatibility
    -Fixed bug where code in coroutines wasn't verified
    -Fixed bug where types from other Unity assemblies would be ignored by verification
     
  16. jman12351

    jman12351

    Joined:
    Jul 9, 2015
    Posts:
    1
    I'd send this to the Prehistoric Kingdom devs, but 1. they'd probably have to completely rewrite the game's code, and 2. they've banned all discussion of mod support, unless I'm wrong about the first one. Please tell me I'm wrong.
     
  17. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Version 1.2.0 is now available! The exporter has been remade from scratch to be faster and more robust with better error handling.

    Version 1.2.0:
    -Added ModInfo.unityVersion to include which Unity version was used to export a mod
    -Improved the mod exporter to be faster and more robust
    -Added ModExporter.ExportStarting, an event that occurs before the export process starts
     
  18. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Hi,

    Because I don't have as much time to work on it anymore and I want to share it with the community, ModTool is now open source!

    https://github.com/Hello-Meow/ModTool

    It will still be available on the Asset Store. Version 1.3.0 has been submitted, so it should become available soon.

    Version 1.3.0:
    -Use ModToolSettings and CodeSettings directly instead of ProductSettings for the exporter
    -Use Unity's builtin serialization instead of XML for ModInfo
    -Refactored some messy parts
     
    laurentlavigne likes this.
  19. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    It just works - so cool!
     
  20. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Let's say the core game has a few scripts that I want to access from the mods, for example ways to do navmesh movement, AI, ways to display grid in-game, something I can't to give to the modding community. How do I do that?
    I tried adding Plugins/CoreExample.cs in the project where I create the exporter but this isn't accessible to the scripts inside the modding project that I imported the exported in.
     
  21. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    To do this you can compile the necessary scripts to a dll and add the dll's name to Api Assemblies in ModTool's settings. This adds the dll to the exporter package, so both the game and mods can use them.

    Here is a guide how to compile scripts: https://docs.unity3d.com/Manual/UsingDLL.html

    And here is more information about the Api Assemblies settings: https://github.com/Hello-Meow/ModTool/wiki/Getting-Started
     
  22. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Oh joy, those dll... last time I tried that I threw my keyboard through the window... Is there a way to automate that stuff or just include default assemblies ?
    [edit] or since unity automatically builds the .dll, drop those? this way we can target .dll with the use of 2017.3 assembly definition files
     
    Last edited: Jun 29, 2018
  23. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Bug: Verifying Project failed: Mods for ModTool Release can only be exported with Unity 5.3.1p1
    When exporting the mod
    Here is what I do:
    1. launch two unity 2017.3.1p1
    2. in one editor load modtools, create a core script in a folder "Core" and add an assembly definition file AssemblyeName to that folder
    3. copy the AssemblyeName.dll from ..\Library\ScriptAssemblies to the Core folder (for some reason the unity compiler doesn't complain)
    4. add the AssemblyeName to the api section of modtool settings
    5. create exporter
    6. in the second editor import the exporter
    7. create a script, AssemblyeName.Class.StaticMethods are now available in all scripts, good
    8. ModTool/Verify ... nothing happens, I guess that means good
    9. ModTool/Export Mod = error in the console
    [EDIT: after rebuilding the exporter, it works. It requires rebuild of the core game, the one with the mods list, and for build to work the AssemblyName.dll must be deleted from the project. Automating all that would be fantastic ;)]
     
    Last edited: Jun 29, 2018
  24. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Yeah that's a bug. Thanks for letting me know.

    ModToolSettings wasn't getting updated at all after the asset was created, so an old unity version would stick around when changing Unity versions, including in the asset store package. That's pretty bad.

    The fix has been pushed to github.
     
    laurentlavigne likes this.
  25. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Thanks. How do I compile all that to dll?

    Good News : I upgraded the test project to 2018.1 and to my surprise the 2017.3.1 mods still work.

    Weird: if two mods share the same scene name or I presume script and asset name, the last one loaded overwrites. What's the recommended way to handle name collision? By that I mean once the game is out in the wild and some mods are complementary, how do I prevent name collision without enforcing naming - because enforcing anything on steam is ... missing impossible
     
    Last edited: Jun 30, 2018
  26. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    To compile the solution just open the .sln in Visual Studio and compile. The dlls are copied to the included example projects post build.

    Conflicts are detected and if one mod is loaded, any conflicting mods can't be loaded. You can see if a mod has any conflicting mods with Mod.conflictingMods. This provides a list of any conflicting mods for that mod.

    It's only code and scenes that can collide. For this reason scenes and code get a prefix when a mod is exported. The prefix is the mod's name. This should prevent most collisions. Only if you have multiple ModSearchDirectories that have mods with the same name a collision should occur. I'm not sure how this would pan out with Steam Workshop though.
     
    laurentlavigne likes this.
  27. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    When you prefix the code name, do you also prefix the class names?
     
  28. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    No, just the assembly name. That's what Unity looks for when loading the assets that reference a dll.
     
    laurentlavigne likes this.
  29. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    In this case, how would i help mod makers avoid class clash?
     
  30. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    That doesn't happen when types are in different assemblies with different assembly names.
     
    laurentlavigne likes this.
  31. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Ahhhh assembly = namespace or something, that's cool.
    It looks like you thought about everything. What game are you using it in?
     
  32. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    An assembly basically is a compiled .net project. It has some meta data including the assembly name, which is used for referencing external assemblies. So types that share the same name and namespace can still be told apart when they're in different assemblies with different names.

    I am using it for a game, but the main goal for ModTool was to add mod support that would be as general as possible.
     
    laurentlavigne likes this.
  33. TheShock

    TheShock

    Joined:
    Aug 5, 2014
    Posts:
    35
    Hi! What about resources from source game? What if my game have special shader, material, or even prefab, that should be used in mod - how can mod had access to them without duplicating?
     
  34. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Hi,

    This is a feature I want to add. I don't know exactly how it's going to work. Maybe it could utilize Unity's new addressable assets system, or maybe this could be done with asset bundles.

    At the very least there should be a way to select shared assets that are added to the exporter package, but don't in turn are exported by the mod exporter.
     
  35. TheShock

    TheShock

    Joined:
    Aug 5, 2014
    Posts:
    35
    Thanks a lot for your answer! Do you have some assumptions about time, when it can appear in your plugin?
     
  36. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Not exactly. This has been on the todo list for a while, so sooner rather than later.
     
    laurentlavigne likes this.
  37. Kirsche

    Kirsche

    Joined:
    Apr 14, 2015
    Posts:
    121
    Garry experimented with this and came up with a solution: https://forum.facepunch.com/f/unity/btenr/Asset-Bundle-Tests/1/

    Cool project btw! :D
     
    laurentlavigne likes this.
  38. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    laurentlavigne likes this.
  39. TheGamerX20

    TheGamerX20

    Joined:
    Dec 12, 2016
    Posts:
    8
    Hello!

    I've noticed that in Unity 2018.2.0f2 the loaded mods don't load Scripts(or maybe it does but it doesn't work) in the UnityEditor, just gives me a Message saying "The associated script can not be loaded. Please fix any compiler errors and assign a valid script."

    However if I build the game it works perfectly fine..
    any solutions?

    Thanks!
     

    Attached Files:

  40. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Thanks for letting me know. I've got no idea what could be causing this. I'm going to look into it.
     
    TheGamerX20 likes this.
  41. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    It looks like Unity can no longer find scripts from Assemblies that are loaded at runtime when loading asset bundles in the editor.

    The Assembly is loaded and the scripts can be used with AddComponent. It just doesn't find them when loading an asset bundle for some reason. When the assembly is imported into the project instead of loading it at runtime, it works as expected.

    I'm not sure what to do about this. This feature wasn't officially supported, but it has worked for all versions up to 2018. I'm going to submit a bug report and hope they'll fix it.
     
    TheGamerX20 likes this.
  42. TheGamerX20

    TheGamerX20

    Joined:
    Dec 12, 2016
    Posts:
    8
    Dang..
    Thanks a lot! ^_^
     
  43. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,225
    Let's increase chances of this being fixed. post your bug report here and we'll copy pasta
     
    TheGamerX20 likes this.
  44. SolidJuho

    SolidJuho

    Joined:
    Oct 23, 2016
    Posts:
    11
    Hello,
    I would ask for guidance for proper way to use API Assemblies, as documentation is kind of lacking it.

    These are my current settings at the image, and here is my dll script.

    DLL Script:
    I removed as there was nothing wrong with it.

    Basically, I want modders to be able to add ModProperties components to items, so my handler can add right components in the game.
    As VRTK Components does not have .dll, just namespaces, i had to create this workaround.


    Handler script:
    I removed as problem wasnt about this script.

    I am still unable use using CD_ModTools or add ModProperties components in mod projects.
     
    Last edited: Sep 27, 2018
  45. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    I submitted the bug report last week and they could reproduce it, but I haven't seen it on the issue tracker yet.

    Mod.GetComponentsInScenes will only return components from a scene when the scene is loaded. The scene probably isn't loaded yet in OnModLoaded.

    In ApiAssemblies you only have to add the Assembly Name that is configured in the Assembly's project settings. Does the assembly get added to the exporter package?
     
  46. SolidJuho

    SolidJuho

    Joined:
    Oct 23, 2016
    Posts:
    11
    Thank you for the quick response.
    That is probably true, Thank you for that GetComponents in scene tip, it's going to save lot of my headache.

    And no, It's not currently exported with the package, which was my main problem.
    But I would guess it was totally up to my bad for totally forgetting that I had to create an assembly file and not .dll file.
     
  47. SolidJuho

    SolidJuho

    Joined:
    Oct 23, 2016
    Posts:
    11
    Hey, Even though I have now created an assembly file and make added it to export settings, It's still not being included in the exported package.
    Is there step that I am missing?
     

    Attached Files:

  48. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    A dll file is an assembly. So if CaveDigger_ModTools.dll is the dll file you want to add to the package, you should add that to API Assemblies.

    It looks for the Assembly Name, not the file name. If it is not being added, maybe the Assembly Name is different from the file name. This could be the case if you have changed the file name or project name at any point. You can change the Assembly Name in the visual studio project's settings.
     
  49. SolidJuho

    SolidJuho

    Joined:
    Oct 23, 2016
    Posts:
    11
    Hi,
    I just recreated my dll file making sure that Assembly names are correct with export settings, but it's still not being exported.
     
  50. HelloMeow

    HelloMeow

    Joined:
    May 11, 2014
    Posts:
    280
    Can you send the dll my way? Maybe I can take a look at it.