Modding Tutorials

Discuss modding questions and implementation details.
Post Reply
User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Modding Tutorials

Post by TheLacus »

Interkarma wrote:I'll get those builds update today, after I merge your latest PR. :)
Thank you :)
jman0war wrote:No joy on trees in game.
I pulled down a fresh copy from GitHub.
Have my files in the StreamingAssets\Textures directory.
Image
Started a new char, travel out to the mountains where these 510 trees grow, tried Worthgarian and DragonTail, but i only see the vanilla flats.
Are you sure just placing the files into that folder would be enough?
Like, how does the game know to replace vanilla PNG with the ones in the Texture dir?
Shouldn't i have to like, assign these textures to some object?
Uh, sorry for the misunderstanding. Right now you can replace billboards in interiors, dungeons and fixed exterior locations such as towns or dungeon exteriors. Model and texture injection for the procedurally generated terrain is not yet implemented.

I can confirm, however, that you need only the textures like you did in the screenshot. The modding wireframe will search for them through their name and implement them in-game, taking care of the gameobject and everything else automatically.

EDIT
screen.jpg
screen.jpg (335.14 KiB) Viewed 16158 times

User avatar
jman0war
Posts: 315
Joined: Fri Jan 22, 2016 2:41 am
Contact:

Re: Modding Tutorials

Post by jman0war »

TheLacus wrote: Right now you can replace billboards in interiors, dungeons and fixed exterior locations such as towns or dungeon exteriors. Model and texture injection for the procedurally generated terrain is not yet implemented.
Ok so to see the trees in game with the goal of quality control, should i aim to say, replace other billboards with the trees?
Like, i presume crops or animals, barrels and other things that we see in towns and farms?
Or are they also considered procedurally generated terrain?

I wouldn't think they are as you often see a visual break between 'terrain' and the farm.
Find my Vibrant Terrain Flats mod at Nexusmods: https://www.nexusmods.com/daggerfalluni ... ?tab=files

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

Re: Modding Tutorials

Post by TheLacus »

jman0war wrote:Like, i presume crops or animals, barrels and other things that we see in towns and farms?
Or are they also considered procedurally generated terrain?

I wouldn't think they are as you often see a visual break between 'terrain' and the farm.
This is correct.
jman0war wrote: Ok so to see the trees in game with the goal of quality control, should i aim to say, replace other billboards with the trees?
No i'm only saying that you should look near towns and not in the middle of the field. If you can't see your texture even near towns there is something wrong. I urge you to check that the names you assigned correspond to the climate you are testing in game, maybe try making a few copies for each archive with the same tree texture. ;)

I've just done a test and it works fine here.
screen1.jpg
screen1.jpg (319.5 KiB) Viewed 16149 times
Anyway, we are in the wrong topic.

User avatar
Nystul
Posts: 1501
Joined: Mon Mar 23, 2015 8:31 am

Re: Modding Tutorials

Post by Nystul »

I am posting this here, not sure if it really fits in here, but it is related to mod development...

what is your best practice when developing mods to use git for your mod's codebase in conjunction with dfunity?

I would like to have my mods in a personal mod repository on git and have it somehow "incorporated" into the tree of dfunity's file tree structure (after cloning it from git). Or is it better to completely seperate the two repositories when developing and copy the dfmod files manually - but this feels tedious somehow...

What is a good workflow to develop the mod and test it with dfunity?

Especially can I debug my mods from within the dfunity scene and how do I do it? My mods are pretty complex and I can't do without debugging!

User avatar
LypyL
Posts: 512
Joined: Sun Mar 22, 2015 3:48 am

Re: Modding Tutorials

Post by LypyL »

what is your best practice when developing mods to use git for your mod's codebase in conjunction with dfunity?
Good question. I would personally use a second repo.
What is a good workflow to develop the mod and test it with dfunity?

Especially can I debug my mods from within the dfunity scene and how do I do it? My mods are pretty complex and I can't do without debugging!
Well the way I do it currently is to just develop the mod so it runs in Unity like normal, and then just make a loading / setup function that gets called when you're ready. It's theoretically possible to use the VS or Monodevelop debuggers with the loaded mods, but I haven't tried it.

User avatar
Nystul
Posts: 1501
Joined: Mon Mar 23, 2015 8:31 am

Re: Modding Tutorials

Post by Nystul »

ok the solution (also for debugging with visual studio) I came up with:
  • second repository for my mods in a folder outside of the daggerfall-unity repository
  • each mod directory is "imported" into Assets\Game\Addons via a symbolic link (this directory is not part of the daggerfall-unity repository)
    (also works under windows via mklink command - use absolute paths as parameters)
    this is for convenience so the mod source files are in the tree of daggerfall-unity and can be easily opened later when debugging since they automatically become part of the visual studio solution when selecting Unity menu option Assets/Open C# Project
  • mod setup class that contains both the InitStart(InitParams initParams) function for mod invocation (for the ModManager) as well as an Awake() function in case we need to debug.
    It looks like this (I used the underscore in file and class name to make it easily distinguishable from other scripts of the mod) - see the comments in code how you can debug then:

    Code: Select all

    namespace namespaceCustomMod
    {
        public class _startupMod : MonoBehaviour
        {
            [Invoke(StateManager.StateTypes.Start)]
            public static void InitStart(InitParams initParams)
            {
                initMod();
            }
    
            /*  
            *   used for debugging
            *   howto debug:
            *       -) add a dummy GameObject to DaggerfallUnityGame scene
            *       -) attach this script (_startupMod) as component
            *       -) deactivate mod in mod list (since dummy gameobject will start up mod)
            *       -) attach debugger and set breakpoint to one of the mod's cs files and debug
            */
            void Awake()
            {
                initMod();
            }
    
            public static void initMod()
            {
                Debug.Log("init of custom mod");
                ...
            }
        }
    }
    
so you need to temporarily modify DaggerfallUnityGame scene but only for debugging and you should revert it afterwards.
but this is the best way I found to develop/test/release in cycle

howto debug:
  • add a dummy GameObject to DaggerfallUnityGame scene
  • attach this script (_startupMod) as component
  • deactivate mod in mod list (since dummy gameobject will start up mod)
  • attach debugger and set breakpoint as usual (to one of the mod's cs files) and debug

User avatar
Uncanny_Valley
Posts: 221
Joined: Mon Mar 23, 2015 5:47 pm

Re: Modding Tutorials

Post by Uncanny_Valley »

Hi.

I been trying to convert my "Flying Birds" into a standalone mod, but I'm running into what seems like several problems. :(

After trying to remove as much as possible, right now I'm just trying to spawn an empty prefab... and even that doesn't work! It shows up in the mod menu correctly, but when I have the mod enabled the following errors happens:

Loading a game inside an interior location:
  • No error messages
  • The house doesn't load.
  • The empty Birdspawner prefabs loads correctly.
Loading a game in an exterior location:
  • I get the following error. (1 + 6 times)

    Code: Select all

    MissingReferenceException: The object of type 'AssetBundle' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    DaggerfallWorkshop.Utility.AssetInjection.MeshReplacement.ImportCustomGameobject (UInt32 modelID, UnityEngine.Transform parent, Matrix4x4 matrix) (at Assets/Scripts/Utility/AssetInjection/MeshReplacement.cs:80)
    DaggerfallWorkshop.Utility.RMBLayout.AddModels (DaggerfallWorkshop.DaggerfallUnity dfUnity, DaggerfallConnect.DFBlock& blockData, System.Collections.Generic.List`1& doorsOut, System.Collections.Generic.List`1& buildingsOut, DaggerfallWorkshop.Utility.ModelCombiner combiner, UnityEngine.Transform parent) (at Assets/Scripts/Utility/RMBLayout.cs:683)
    DaggerfallWorkshop.Utility.RMBLayout.CreateBaseGameObject (DaggerfallConnect.DFBlock& blockData, Int32 layoutX, Int32 layoutY, DaggerfallWorkshop.DaggerfallRMBBlock cloneFrom) (at Assets/Scripts/Utility/RMBLayout.cs:145)
    DaggerfallWorkshop.Utility.GameObjectHelper.CreateRMBBlockGameObject (DFBlock blockData, Int32 layoutX, Int32 layoutY, Boolean addGroundPlane, DaggerfallWorkshop.DaggerfallRMBBlock cloneFrom, DaggerfallWorkshop.DaggerfallBillboardBatch natureBillboardBatch, DaggerfallWorkshop.DaggerfallBillboardBatch lightsBillboardBatch, DaggerfallWorkshop.DaggerfallBillboardBatch animalsBillboardBatch, DaggerfallWorkshop.Utility.TextureAtlasBuilder miscBillboardAtlas, DaggerfallWorkshop.DaggerfallBillboardBatch miscBillboardBatch, ClimateNatureSets climateNature, ClimateSeason climateSeason) (at Assets/Scripts/Utility/GameObjectHelper.cs:397)
    DaggerfallWorkshop.StreamingWorld+<UpdateLocation>c__Iterator1.MoveNext () (at Assets/Scripts/Terrain/StreamingWorld.cs:657)
    UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) (at C:/buildslave/unity/build/Runtime/Export/Coroutines.cs:17)
    UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    DaggerfallWorkshop.StreamingWorld:InitPlayerTerrain() (at Assets/Scripts/Terrain/StreamingWorld.cs:513)
    DaggerfallWorkshop.StreamingWorld:Update() (at Assets/Scripts/Terrain/StreamingWorld.cs:214)
    
  • The terrain loads, but no buildings
  • The empty Birdspawner prefabs loads correctly.
Staring a new game
  • After finishing up the character creation, nothing happens
  • Keep getting the following error message each frame

    Code: Select all

    MissingReferenceException: The object of type 'AssetBundle' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    DaggerfallWorkshop.Utility.AssetInjection.VideoReplacement.ImportCustomVideo (System.String name, UnityEngine.MovieTexture& video) (at Assets/Scripts/Utility/AssetInjection/VideoReplacement.cs:41)
    DaggerfallWorkshop.Game.UserInterfaceWindows.DaggerfallVidPlayerWindow.Setup () (at Assets/Scripts/Game/UserInterfaceWindows/DaggerfallVidPlayerWindow.cs:71)
    DaggerfallWorkshop.Game.UserInterfaceWindows.DaggerfallBaseWindow.Update () (at Assets/Scripts/Game/UserInterfaceWindows/DaggerfallBaseWindow.cs:100)
    DaggerfallWorkshop.Game.UserInterfaceWindows.DaggerfallVidPlayerWindow.Update () (at Assets/Scripts/Game/UserInterfaceWindows/DaggerfallVidPlayerWindow.cs:101)
    DaggerfallWorkshop.Game.DaggerfallUI.Update () (at Assets/Scripts/Game/DaggerfallUI.cs:252)
    
  • The empty Birdspawner doesn't prefabs loads correctly.

I use the follwing code to load my mod.

Code: Select all

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

namespace DaggerfallWorkshop.Game
{
    //this class initializes the mod.
    public class BirdsInDaggerFallModLoader
    {
        public static Mod mod;
        public static GameObject BirdSpawner;

        [Invoke]
        public static void InitAtStartState(InitParams initParams)
        {
            mod = initParams.Mod;

            Debug.Log("Started setup of : " + mod.Title);

            ModManager.Instance.GetComponent<MonoBehaviour>().StartCoroutine(mod.LoadAllAssetsFromBundleAsync(true));

            mod.IsReady = true;
        }

        [Invoke(StateManager.StateTypes.Game)]
        public static void InitAtGameState(InitParams initParams)
        {
            if (BirdSpawner != null)
                return;
            BirdSpawner = mod.GetAsset<GameObject>("BirdSpawner.prefab", true);

            Debug.Log("Loaded BirdSpawner");

            //Add the BirdSpawnComponent
            //BirdSpawner.AddComponent<BirdSpawner>();
 
        }
    }
}
Is there something I'm doing wrong?

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

Re: Modding Tutorials

Post by TheLacus »

An oversight on my side. When you run this

Code: Select all

ModManager.Instance.GetComponent<MonoBehaviour>().StartCoroutine(mod.LoadAllAssetsFromBundleAsync(true));
the assetbundle get unloaded so this method fails later on:

Code: Select all

MissingReferenceException: The object of type 'AssetBundle' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
DaggerfallWorkshop.Utility.AssetInjection.MeshReplacement.ImportCustomGameobject (UInt32 modelID, UnityEngine.Transform parent, Matrix4x4 matrix) (at Assets/Scripts/Utility/AssetInjection/MeshReplacement.cs:80)
I need to get to check if the assetbundle is still loaded before proceding. Anyway, you can verify this using LoadAllAssetsFromBundleAsync(false).

User avatar
tgp02
Posts: 5
Joined: Wed Feb 08, 2017 3:41 pm

Re: Modding Tutorials

Post by tgp02 »

Unfortunately, I can't get anything done due to compiler errors. Mainly due to error CS0619 and error CS0266.

User avatar
Interkarma
Posts: 7234
Joined: Sun Mar 22, 2015 1:51 am

Re: Modding Tutorials

Post by Interkarma »

With your compiler errors, the main things to check are:
  • Using Unity 5.5.0f3.
  • Using latest code from GitHub repo.
  • Using the full .NET Framework from Edit > Project Settings > Player > API Compatibility Level > ".NET 2.0" - not ".NET 2.0 Subset". (This should already be set if full project was cloned from Git).
  • Check opening correct path. After cloning from GitHub, select the parent folder "daggerfall-unity" containing the Assets and ProjectSettings folder (i.e. don't go inside that folder, just select the parent "daggerfall-unity" folder).
If all else fails, delete the project and clone again. I've created a short YouTube video to help with cloning project if you haven't seen it already. The only major difference is the project is on Unity 5.5 now.

Good luck! :)


Post Reply