Technical Help Needed Integrating UMA into DFU

Discuss coding questions, pull requests, and implementation details.
User avatar
MasonFace
Posts: 486
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Technical Help Needed Integrating UMA into DFU

Post by MasonFace » Thu Mar 12, 2020 3:13 pm

I'm hoping to get some insight from some experienced mod developers regarding some implementation details.

My Goal:

I'm attempting to create a mod that will use the UMA framework to dynamically generate humanoid characters in DFU. I intend to create a pool of UMA dynamic character avatars that are configured as needed to replace appropriate characters, starting with townsfolk using the Mobile Person Asset class.

My Attempts:

I've cloned the latest version of DFTFU and have imported UMA into the project. I've created a mod with all the UMA prefabs and scripts needed to create a dynamic avatar. I created a script to initialize the mod, then load and instantiate the necessary singleton prefabs, then instantiated a dynamic avatar (what UMA calls the dynamically generated character mesh). Finally, I packaged the .dfmod and move it to Streaming Assets/Mods folder and... it works! I haven't used it to replace Mobile Person Assets yet; I've only just instantiated an avatar with its transform.position in the Privateer's Hold entrance cave area for testing purposes.

The Problem:

The problem is that it only works when playing inside Unity. This leads me to believe that this is a compiler issue with MCS.

Here's the problem: while UMA is open source and can be modified, there are 15 main scripts and the few that I've looked at are fairly complex. If I understand correctly, MCS has issues with the following:
  • Enums
  • Generic Methods and Classes
  • Struct Initializers
Is this an exhaustive list? Anything else I should be on the lookout for?

Is there a way to debug the MCS compiler to narrow down precisely where it's running into trouble, or am I better off looking for these issues (enums, generics, etc.) line-by-line in each script?

Looking ahead, if the UMA framework turns out to be too complex, or is too reliant on enums and/or generic methods to be considered reasonable to rewrite, is there a way to compile certain scripts ahead of time without having to integrate them directly into DFU core?

Thanks for your time!

User avatar
TheLacus
Posts: 1159
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by TheLacus » Thu Mar 12, 2020 4:00 pm

Errors thrown by the compiler are logged, but it might be a tedious process to fix all issues. There is an editor utility under Daggerfall Tools that you may find helpful to test the portable compiler inside the editor without lunching the game.

I never tried it myself, but it should be possible to create a .dll for Unity and load it at runtime. The Mod System only supports raw .cs files compiled at runtime, but you might be able to load a dll from the assetbundle and retrieve the compiled assembly. Of course there are security considerations because the content of this plugin can't be exported with the Export Text button in game.
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

User avatar
MasonFace
Posts: 486
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by MasonFace » Thu Mar 12, 2020 6:29 pm

Thank you for your insight, TheLacus!

When I get home from work, I'll check the log and see what issues I can find.

While on break at work, I looked through the UMA GitHub project and hunted down as many enums as I could find.

I found 8 enums across the 15 scripts. I think the preferable approach would be for me to try to convert these enums into structs of constants like you did, before I try anything more radical.

But just out of curiosity, can you elaborate on what you meant regarding the security considerations when going with the .dll approach?

Edit: Follow up question: The .dll approach would only work work for Windows users, correct?

User avatar
TheLacus
Posts: 1159
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by TheLacus » Thu Mar 12, 2020 8:20 pm

C# scripts can be exported from mods as text files, while there is no easy way to check that a dll doesn't contain malicious code, you would have to use a disassembler. Everyone is responsible for what they download from the internet, but this is something to consider from a design point of view.

I don't think there is any issue with Mac or Linux, it should be handled by Mono. In fact we are already doing something more advanced by compiling text files at runtime to an assembly in memory. Loading a precompiled assembly should be a matter of calling Assembly.Load(textAsset.bytes).
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

User avatar
MasonFace
Posts: 486
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by MasonFace » Thu Mar 12, 2020 8:52 pm

The more I read about it, the more appealing the .dll approach seems to me. I may try to create a very simple managed plug-in DLL containing a C# script with an enum and see if it works in the stand-alone DFU. If it works, then there's a great chance that UMA will too. If that assumption turns out to be true, it will save me a lot of time by not having to re-write chunks of UMA scripts to be MCS friendly.

Thank you again for your time, TheLacus.

User avatar
MasonFace
Posts: 486
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by MasonFace » Sat Mar 14, 2020 11:33 am

TheLacus,

I'm following the instruction on how to create a .dll but I'm running into problems.


My Goal:
I'm just simply trying to recreate Lypyl's "Hello World" example project as an assembly.

My Attempt:
I installed the necessary plugins for Visual Studio 2019 to build a C# class library.
I created a new project using the template for "Class Library (.NET Framework)" using the following settings:
  • Project Name: TestDLL
  • Location: L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\
  • Solution: "Add to Solution"
  • Framework: .NET Framework 2.0
I added UnityEngine.dll as a reference to TestDLL.

I then erased all the code that was initialized in the template and copied in the code from the HelloWorld.cs script.

In my namespace declaration, all instances of DaggerfallWorkShop namespaces are underlined with the red squiggly, indicating a problem.
TestDLL.png
TestDLL.png (137.78 KiB) Viewed 471 times
The Problem:
I can't get the C# class library to compile. I have no problem adding UnityEngine.dll as a reference, but when I try to build the solution, it outputs the following errors:

Spoiler!
Severity Code Description Project File Line Suppression State
Error CS0246 The type or namespace name 'DaggerfallWorkshop' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 3 Active
Error CS0246 The type or namespace name 'DaggerfallWorkshop' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 4 Active
Error CS0246 The type or namespace name 'DaggerfallWorkshop' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 5 Active
Error CS0246 The type or namespace name 'DaggerfallWorkshop' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 6 Active
Error CS0246 The type or namespace name 'DaggerfallMessageBox' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 12 Active
Error CS0246 The type or namespace name 'InvokeAttribute' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 58 Active
Error CS0246 The type or namespace name 'Invoke' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 58 Active
Error CS0103 The name 'StateManager' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 58 Active
Error CS0246 The type or namespace name 'InitParams' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 59 Active
Error CS0246 The type or namespace name 'InvokeAttribute' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 74 Active
Error CS0246 The type or namespace name 'Invoke' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 74 Active
Error CS0103 The name 'StateManager' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 74 Active
Error CS0246 The type or namespace name 'InitParams' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 75 Active
Error CS0246 The type or namespace name 'InvokeAttribute' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 83 Active
Error CS0246 The type or namespace name 'Invoke' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 83 Active
Error CS0103 The name 'StateManager' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 83 Active
Error CS0246 The type or namespace name 'InitParams' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 84 Active
Error CS0103 The name 'GameManager' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 41 Active
Error CS0103 The name 'StateManager' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 41 Active
Error CS0103 The name 'ModManager' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 68 Active
Error CS0246 The type or namespace name 'DaggerfallMessageBox' could not be found (are you missing a using directive or an assembly reference?) TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 96 Active
Error CS0103 The name 'DaggerfallWorkshop' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 96 Active
Error CS0103 The name 'DaggerfallUI' does not exist in the current context TestDLL L:\daggerfall-unity-master\Assets\Game\Mods\3D Characters\Scripts\Test Script\TestDLL\HelloWorld.cs 103 Active
Warning CS0649 Field 'ModInfo.Dependencies' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\Game\Addons\ModSupport\ModTypes.cs 57 Active
Warning CS0649 Field 'ModDependency.Name' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\Game\Addons\ModSupport\ModTypes.cs 108 Active
Warning CS0649 Field 'ModDependency.IsOptional' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\Game\Addons\ModSupport\ModTypes.cs 114 Active
Warning CS0649 Field 'ModDependency.IsPeer' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\Game\Addons\ModSupport\ModTypes.cs 120 Active
Warning CS0649 Field 'ModDependency.Version' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\Game\Addons\ModSupport\ModTypes.cs 128 Active
Warning CS0067 The event 'PlayerEnterExit.OnFailedTransition' is never used Assembly-CSharp L:\daggerfall-unity-master\Assets\Scripts\Game\PlayerEnterExit.cs 1432 Active
Warning CS0649 Field 'BookMappingEntry.Name' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\Scripts\Utility\AssetInjection\BookReplacement.cs 31 Active
Warning CS0649 Field 'BookMappingEntry.Title' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\Scripts\Utility\AssetInjection\BookReplacement.cs 37 Active
Warning CS0649 Field 'BookMappingEntry.ID' is never assigned to, and will always have its default value 0 Assembly-CSharp L:\daggerfall-unity-master\Assets\Scripts\Utility\AssetInjection\BookReplacement.cs 43 Active
Warning CS0649 Field 'BookMappingEntry.IsUnique' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\Scripts\Utility\AssetInjection\BookReplacement.cs 49 Active
Warning CS0649 Field 'BookMappingEntry.WhenVarSet' is never assigned to, and will always have its default value Assembly-CSharp L:\daggerfall-unity-master\Assets\Scripts\Utility\AssetInjection\BookReplacement.cs 55 Active
Warning CS0649 Field 'SpriterPOVweapon.filter' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriterPOVweapon.cs 83 Active
Warning CS0649 Field 'SpriterPOVweapon.selfShadowing' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriterPOVweapon.cs 87 Active
Warning CS0649 Field 'SpriteWrite.LODEnabled' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriteWrite.cs 68 Active
Warning CS0649 Field 'SpriteWrite.LODLevel' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriteWrite.cs 69 Active
Warning CS0649 Field 'SpriteWrite.viewAnglesVert' is never assigned to, and will always have its default value Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriteWrite.cs 124 Active
Warning CS0649 Field 'SpriteWrite.filter' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriteWrite.cs 130 Active
Warning CS0649 Field 'SpriteWrite.selfShadowing' is never assigned to, and will always have its default value false Assembly-CSharp L:\daggerfall-unity-master\Assets\SpriteWrite\Resources\Scripts\SpriteWrite.cs 132 Active
Warning CS0649 Field 'SlotDataAsset._rendererAsset' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\UMA\Core\StandardAssets\UMA\Scripts\SlotDataAsset.cs 18 Active
Warning CS0649 Field 'UMARendererAsset._RendererName' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\UMA\Core\StandardAssets\UMA\Scripts\UMARendererAsset.cs 32 Active
Warning CS0649 Field 'UMARendererAsset._ClothProperties' is never assigned to, and will always have its default value null Assembly-CSharp L:\daggerfall-unity-master\Assets\UMA\Core\StandardAssets\UMA\Scripts\UMARendererAsset.cs 51 Active
Warning CS0414 The field 'CreateTextureAtlas.texArrayFormat' is assigned but its value is never used Assembly-CSharp-Editor L:\daggerfall-unity-master\Assets\SpriteWrite\Editor\CreateTextureAtlas.cs 15 Active
Warning There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "mcs", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. Assembly-CSharp-firstpass
Warning There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "mcs", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. Assembly-CSharp
Warning There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "mcs", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. Assembly-CSharp-Editor
Warning The primary reference "UnityEngine" could not be resolved because it has an indirect dependency on the framework assembly "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v2.0". To resolve this problem, either remove the reference "UnityEngine" or retarget your application to a framework version which contains "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089". TestDLL
It seems that it isn't able to communicate with the Daggerfall Unity scripts. How do I give it access to these namespaces without those scripts being a referenced .dll ?

User avatar
TheLacus
Posts: 1159
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by TheLacus » Sat Mar 14, 2020 12:36 pm

Try to add "\DaggerfallUnity_Data\Managed\Assembly-CSharp.dll" from the game installation. You might also need to add other plugins, like FullSerializer - Unity.dll.
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

User avatar
MasonFace
Posts: 486
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by MasonFace » Sat Mar 14, 2020 1:44 pm

Thanks! That took care of most of it.

After that, it complained that it needed UnityEngine.CoreModule, so I added that reference. Then it complained that " 'MonoBehaviour' exists in both 'UnityEngine.CoreModule, Version =0.0.00, . . ." so I just removed UnityEngine.dll from the references and it seems to have created the .dll!

----------------------------------------

Okay, so now I've got "TestDLL.dll" added to my .dfmod package and I'm trying to load and read the "TestDLL.dll" assembly from the mod once the game has started.

From what I gather from your previous post:
Loading a precompiled assembly should be a matter of calling Assembly.Load(textAsset.bytes).
I should create a variable of type TextAsset, then use mod.GetAsset<TextAsset>("TestDLL") to load it into that variable, then use System.Reflection.Assembly.Load(textAsset.bytes). Am I on the right track?

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DaggerfallWorkshop.Game;
using DaggerfallWorkshop.Game.Entity;
using DaggerfallWorkshop.Game.Utility.ModSupport;
using DaggerfallWorkshop.Utility;
using DaggerfallConnect.Utility;
using MobilePersonCubeMod;
using System.Reflection;

namespace UMAcharacters
{
    public class UMAtest : MonoBehaviour {

        static Mod mod;
        static TextAsset TestDllTA;

        [Invoke(DaggerfallWorkshop.Game.StateManager.StateTypes.Start, 0)]

        public static void Init(InitParams initParams)
        {
            mod = initParams.Mod;
            var go = new GameObject(mod.Title);
            

            TestDllTA = mod.GetAsset<TextAsset>("TestDLL");
            Assembly TestDLL = Assembly.Load(TestDllTA.bytes);


        }

        private void Awake()
        {
            var settings = mod.GetSettings();

            mod.IsReady = true;
        }

    }
}
So at this point, I presume "TestDLL" should be loaded into the mod. How do I execute it from here?

If I just simply create the mod with the TestScript.cs and TestDLL.dll and press play, Unity console reports:
Spoiler!
Exception has been thrown by the target of an invocation.
UnityEngine.Debug:LogError(Object)
DaggerfallWorkshop.Game.Utility.ModSupport.ModManager:InvokeModLoaders(StateTypes) (at Assets/Game/Addons/ModSupport/ModManager.cs:712)
DaggerfallWorkshop.Game.Utility.ModSupport.ModManager:StateManager_OnStateChange(StateTypes) (at Assets/Game/Addons/ModSupport/ModManager.cs:1206)
DaggerfallWorkshop.Game.StateManager:TriggerStateChange(StateTypes) (at Assets/Scripts/Game/StateManager.cs:153)
DaggerfallWorkshop.Game.StateManager:ChangeState(StateTypes) (at Assets/Scripts/Game/StateManager.cs:91)
DaggerfallWorkshop.Game.StateManager:.ctor(StateTypes) (at Assets/Scripts/Game/StateManager.cs:57)
DaggerfallWorkshop.Game.GameManager:get_StateManager() (at Assets/Scripts/Game/GameManager.cs:112)
DaggerfallWorkshop.Game.Entity.PlayerEntity:Update(DaggerfallEntityBehaviour) (at Assets/Scripts/Game/Entities/PlayerEntity.cs:365)
DaggerfallWorkshop.Game.Entity.DaggerfallEntityBehaviour:Update() (at Assets/Scripts/Game/Entities/DaggerfallEntityBehaviour.cs:80)
Not sure if I'm approaching this correctly... :oops:

User avatar
TheLacus
Posts: 1159
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by TheLacus » Sat Mar 14, 2020 3:26 pm

Try to rename TestDLL.dll to TestDLL.bytes. If it doesn't solve the issue use a try-catch around Assembly.Load to hopefully log something useful.

Then you can use reflection to access the assembly.

Code: Select all

Type foo = assembly.GetType("foo_namespace.foo");
MethodInfo mInfo = foo.GetMethod("StaticPublicMethodName");
object returnValue = mInfo.Invoke(null /*or class instance if not static*/, new object[]{"arg1", "arg2"});
This is how void Init(InitParams initParams) is called. It acts as an entry point that receives context data from the game and then runs on its own.

Code: Select all

for (int j = 0; j < setupOptions.Count; j++)
{
    SetupOptions options = setupOptions[j];
    MethodInfo mi = options.mi;
    if (mi == null)
        continue;
    InitParams initParams = new InitParams(options.mod, ModManager.Instance.GetModIndex(options.mod.Title), LoadedModCount);
    mi.Invoke(null, new object[] { initParams });
}
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

User avatar
TheLacus
Posts: 1159
Joined: Wed Sep 14, 2016 6:22 pm
Contact:

Re: Technical Help Needed Integrating UMA into DFU

Post by TheLacus » Sat Mar 14, 2020 6:18 pm

I created a class library in Visual Studio using Class Library (.NET Framework) with .NET Framework 3.5. Then i compiled it in Release mode, added .bytes extension and run the the Mod Builer.

This is the content of the single file inside the plugin:

Code: Select all

namespace test_plugin
{
    public class Class1
    {
        public static int GetValue(int n)
        {
            return 5 * n;
        }
    }
}
and this is a raw .cs file bundled directly with the mod:

Code: Select all

using System.Reflection;
using UnityEngine;
using DaggerfallWorkshop.Game;
using DaggerfallWorkshop.Game.Utility.ModSupport;

namespace TestMod
{
    public class Test : MonoBehaviour
    {
        static Mod mod;

        [Invoke(StateManager.StateTypes.Start)]
        public static void Init(InitParams initParams)
        {
            mod = initParams.Mod;    

            var go = new GameObject(mod.Title);
            go.AddComponent<Test>();

            mod.IsReady = true;
        }

        void Start()
        {
            var assembly = Assembly.Load(mod.GetAsset<TextAsset>("test-plugin.dll").bytes);
            MethodInfo getValue = assembly.GetType("test_plugin.Class1").GetMethod("GetValue");
            Debug.LogFormat("Value is {0}.", getValue.Invoke(null, new object[] { 4 }));
        }
    }
}
The error message Fallback handler could not load library is logged, immediately followed by Value is 20. I also added references to Unity and DaggerfallWorkshop and succesfully called members on them. I'm not sure about the error message right now, but i think the issue you are having is due to the extension. If you add .bytes Unity will keep the content as is without trying to parse it as an utf8 string, so this should be the key to succesfully load the assembly. šŸ˜‰
Mod System documentation - Learn how to create mods for Daggerfall Unity.
Modder Discussion - General help and discussion for the mod system.
Github Issues - Submit a bug report for the game, including the mod system.

Post Reply