numidium3rd wrote: ↑Sat Mar 11, 2023 5:32 pm
I have a mod called Hot Key HUD that's been working in DFU 0.14.5 for a while but now when I build a pre-compiled .dfmod while on the latest DFU master branch it fails with the following error message:
DFTFU 1.9.1: Failed to load mod data for `Hot Key HUD`. Exception: Object reference not set to an instance of an object
This error doesn't appear when I run the mod in Unity and everything works as expected. I can't debug exactly what is going wrong because the error only happens in release and the Player.log doesn't give a full stack trace. I
do know that this message is printed from a try/catch block in the LoadGame method of SaveLoadManager when mod data is being de-serialized. Was there a recent change in the way mod data gets de-serialized on load?
For reference, here is the code my mod uses for NewSaveData, GetSaveData, and RestoreSaveData:
https://github.com/numidium/dfu-mods/bl ... HUD.cs#L84
I've recently added some save-data stuff to my WIP mod. Just keep in mind before reading further, the project is currently being worked on in DFU 0.14.4, mostly because 0.14.5 came a few months after the mod was first started, and just been too lazy to switch over until I'm ready to ship it out. Also I have not actually tried building the mod since I added the save-data stuff, so I've only been testing the "virtual" version, so my "advice" may not be that useful in your case, just disclaimer there.
Anyway, maybe you can try something like this? Basically switching the "mod.SaveDataInterface =" from instead of being under Init, have it under Awake() or Start(), atleast this is how it currently looks in my code, but have no idea if there is really any difference:
Code: Select all
public static LockedLootContainersMain Instance;
public static LLCSaveData ModSaveData = new LLCSaveData();
static Mod mod;
// Global Variables
public static GameObject ChestObjRef { get; set; }
public static GameObject MainCamera { get; set; }
public static int PlayerLayerMask { get; set; }
public static AudioClip LastSoundPlayed { get { return lastSoundPlayed; } set { lastSoundPlayed = value; } }
public static PlayerEntity Player { get { return GameManager.Instance.PlayerEntity; } }
public static PlayerActivateModes CurrentMode { get { return GameManager.Instance.PlayerActivate.CurrentMode; } }
public static WeaponManager WepManager { get { return GameManager.Instance.WeaponManager; } }
bool isBashReady = true;
// Mod Textures
public Texture2D ChestChoiceMenuTexture;
public Texture2D InspectionInfoGUITexture;
[Invoke(StateManager.StateTypes.Start, 0)]
public static void Init(InitParams initParams)
{
mod = initParams.Mod;
var go = new GameObject(mod.Title);
go.AddComponent<LockedLootContainersMain>(); // Add script to the scene.
go.AddComponent<LLCObject>();
mod.IsReady = true;
}
private void Start()
{
Debug.Log("Begin mod init: Locked Loot Containers");
Instance = this;
mod.SaveDataInterface = ModSaveData;
MainCamera = GameObject.FindGameObjectWithTag("MainCamera");
PlayerLayerMask = ~(1 << LayerMask.NameToLayer("Player"));
PlayerActivate.RegisterCustomActivation(mod, 4733, 0, ChestActivation);
PlayerEnterExit.OnTransitionDungeonInterior += AddChests_OnTransitionDungeonInterior;
// Load Resources
LoadTextures();
LoadAudio();
RegisterLLCCommands(); // For testing custom windows
Debug.Log("Finished mod init: Locked Loot Containers");
}
Here is what the start of the "LLCSaveData" class looks like as well:
Code: Select all
[FullSerializer.fsObject("v1")]
public class LLCSaveData : IHasModSaveData
{
public Dictionary<ulong, ClosedChestData> ClosedChests;
public Dictionary<ulong, OpenChestData> OpenChests;
public Type SaveDataType
{
get { return typeof(LLCSaveData); }
}
...
Not sure if that will help at all, just figured I'd give it a shot.