Unable to Solve Token Mismatch

Discuss modding questions and implementation details.
Post Reply
l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Unable to Solve Token Mismatch

Post by l3lessed »

So, I'm still struggling with this last issue when running my mod on a stand alone. I removed all offending code and then setup this very simple check.

Code: Select all

                DaggerfallMobileUnit mobileUnit = marker.mobileEnemy.GetComponent<DaggerfallMobileUnit>();
                MobileGender enemyGender = mobileUnit.Summary.Enemy.Gender;
This specific line causes the token error. When removed everything goes back to functioning just fine:

Code: Select all

                MobileGender enemyGender = mobileUnit.Summary.Enemy.Gender;
It seems any call to the enemy summary object causes the token error to appear. Why would merely grabbing it and assigning it to its own object be a token mismatch?
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Hazelnut
Posts: 3016
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Unable to Solve Token Mismatch

Post by Hazelnut »

I think this is due to the change in PR#2284 off the top of my head. If you change DaggerfallMobileUnit to just MobileUnit and it should work if I am right. Can't look right now to check. Sorry I didn't realise you were doing anything with mobileunits in this mod otherwise I'd have give you a heads up about it.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Unable to Solve Token Mismatch

Post by l3lessed »

Odd still getting it with this setup.

Code: Select all

                
void Start()
{
            marker.mobileNPC = gameObject.GetComponent< MobilePersonNPC>();
            marker.mobileEnemy = gameObject.GetComponent<DaggerfallEnemy>();
            marker.flatNPC = gameObject.GetComponent<StaticNPC>();
                
            MobileUnit mobileUnit = marker.mobileEnemy.GetComponentInChildren<MobileUnit>();
             MobileGender enemyGender = mobileUnit.Summary.Enemy.Gender;
}             
             
I attach my marker script to every enemy found within the location area. Upon attaching, it tries to grab the npc object type, which is uses to figure out how to setup the marker later. At this point, it uses the saved enemy object to grab the MobileUnity object. After assigning it to a MobileGender object, I get the token mismatch again. I'm so confused.

If it matters, which I don't know why it would, here is how the script gets attached to the enemies.

Code: Select all

            //find mobile enemies and mark as red. any hostile npc.
            foreach (DaggerfallEnemy mobileEnemy in mobileEnemyArray)
            {
                if (!mobileEnemy.GetComponent<npcMarker>())
                {
                        npcMarker newNPCMarker = mobileEnemy.gameObject.AddComponent<npcMarker>();
                        currentNPCIndicatorCollection.Add(newNPCMarker);
                }
            }
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

User avatar
Hazelnut
Posts: 3016
Joined: Sat Aug 26, 2017 2:46 pm
Contact:

Re: Unable to Solve Token Mismatch

Post by Hazelnut »

Well it was not the PR I thought it might be then. Sorry from the info provided I have no idea what the problem could be.
See my mod code for examples of how to change various aspects of DFU: https://github.com/ajrb/dfunity-mods

l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Unable to Solve Token Mismatch

Post by l3lessed »

Well shoot. When I dig through the individual scripts for the enemy and mobileunit and their objects, my nub programming eyes don't see an issue. And, it isn't an issue when in the editor version. It only crops up when used in a stand alone version with my compiled mod.

Is there an easy way to grab a units texture file using just the daggerfallenemy object?

Right now, the only reason I use mobileunit is to grab the summary texture archive information for using in the ImageReader.GetTexture object call.

Code: Select all

                    
markerTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", mobileUnit.Summary.Enemy.MaleTexture), 0, 0, true, 0);
Is there a easier/better way to do this than digging into the mobileunit summary?
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

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

Re: Unable to Solve Token Mismatch

Post by Interkarma »

l3lessed wrote: Mon Apr 11, 2022 10:02 pm Is there an easy way to grab a units texture file using just the daggerfallenemy object?
You'll need to look in MobileUnitSummary, that's the only place where this information is stored about an instanced mobile.

The MobileUnit instance can be replaced with a custom asset. This might be leading to the mismatch in your live environment. The below would be the "safest" way to do this starting from a DaggerfallEnemy.

Code: Select all

marker.mobileEnemy = gameObject.GetComponent<DaggerfallEnemy>();
MobileGender enemyGender = marker.mobileEnemy.MobileUnit.Summary.Enemy.Gender;
Internally, DaggerfallEnemy.FindMobileUnit() handles both default and custom mobile unit assets. If you use the DaggerfallEnemy.MobileUnit property provided, you should always get the right object.

Does that resolve the token mismatch error? If not, could you please share the exact error you see in the logs?

l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Unable to Solve Token Mismatch

Post by l3lessed »

Still having the issue.

Here is my current setup, per you recommendation.

Code: Select all

            marker.mobileEnemy = gameObject.GetComponent<DaggerfallEnemy>();
            
                if (marker.mobileEnemy.MobileUnit.Summary.Enemy.Gender == MobileGender.Male || marker.mobileEnemy.MobileUnit.Summary.Enemy.Gender == MobileGender.Unspecified)
                    npcTempTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", marker.mobileEnemy.MobileUnit.Summary.Enemy.MaleTexture), 0, 0, true, 0);
                else
                    npcTempTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", marker.mobileEnemy.MobileUnit.Summary.Enemy.FemaleTexture), 0, 0, true, 0);
Works in 13.5 source editor, but in a stand alone 13.5 build, I get this token error.

Code: Select all

TypeLoadException: Could not resolve type with token 0100008b (from typeref, class/assembly MobileUnitSummary, )

 
(Filename:  Line: -1)
If you want to try it yourself, this script should work if you compile it into a mod and run it on game load. On launch, it figures out the location type, grabs all the enemies in that area, drops them into a list, then loops through the list and grabs the texture using the mobile unit summary.

Code: Select all

private void Start()
{
	//location check logic ladder. Grabs the enemy array using proper location object.
 	if (!GameManager.Instance.IsPlayerInside)
                {
                    location = GameManager.Instance.PlayerEnterExit.ExteriorParent;
                    mobileEnemyArray = location.GetComponentsInChildren<DaggerfallEnemy>().ToList();
                }
	//set inside building interior indicator size and material and grab npc objects for assigning below.
	else if (GameManager.Instance.IsPlayerInside && !GameManager.Instance.IsPlayerInsideDungeon)
                {
                    interiorInstance = GameManager.Instance.InteriorParent;
                    mobileEnemyArray = interiorInstance.GetComponentsInChildren<DaggerfallEnemy>().ToList();
                }
	//set dungeon interior indicator size and material and grab npc objects for assigning below.
	else if (GameManager.Instance.IsPlayerInside && GameManager.Instance.IsPlayerInsideDungeon)
                {
                    dungeonInstance = GameManager.Instance.DungeonParent;
                    mobileEnemyArray = dungeonInstance.GetComponentsInChildren<DaggerfallEnemy>().ToList();
                }
                
	//loop through location enemies, grab their mobile unity object, and use it to check gender and setup marker texture into empty texture object.                
	foreach (DaggerfallEnemy mobileEnemy in mobileEnemyArray)
	{
		Texture2D npcTempTexture = null;

		if (mobileEnemy.MobileUnit.Summary.Enemy.Gender == MobileGender.Male || mobileEnemy.MobileUnit.Summary.Enemy.Gender == MobileGender.Unspecified)
			npcTempTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", mobileEnemy.MobileUnit.Summary.Enemy.MaleTexture), 0, 0, true, 0);
		else
			npcTempTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", mobileEnemy.MobileUnit.Summary.Enemy.FemaleTexture), 0, 0, true, 0);
	}
}
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

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

Re: Unable to Solve Token Mismatch

Post by Interkarma »

Good news of a sort - I don't experience this in a built mod on my end. Here's the full script I used. I set this up so I could press K and trigger your code anytime I want.

Code: Select all

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

namespace TestBlessedMod
{
    public class StartupScript : MonoBehaviour
    {
        public static Mod mod;

        [Invoke(StateManager.StateTypes.Start, 0)]
        public static void Init(InitParams initParams)
        {
            mod = initParams.Mod;
            var go = new GameObject(mod.Title);
            go.AddComponent<StartupScript>();
        }

        private void Awake()
        {
            GameObject go = new GameObject("Doing stuff");
            go.AddComponent<DoStuff>();
            Debug.Log("StartScript has completed.");
        }
    }

    public class DoStuff : MonoBehaviour
    {
        private void Update()
        {
            if (InputManager.Instance.GetKeyDown(KeyCode.K))
                EnumEnemyTextures();
        }

        private void EnumEnemyTextures()
        {
            GameObject location = null;
            DaggerfallEnemy[] mobileEnemyArray = null;

            //location check logic ladder. Grabs the enemy array using proper location object.
            if (!GameManager.Instance.IsPlayerInside)
            {
                location = GameManager.Instance.PlayerEnterExit.ExteriorParent;
                mobileEnemyArray = location.GetComponentsInChildren<DaggerfallEnemy>();
            }
            //set inside building interior indicator size and material and grab npc objects for assigning below.
            else if (GameManager.Instance.IsPlayerInside && !GameManager.Instance.IsPlayerInsideDungeon)
            {
                GameObject interiorInstance = GameManager.Instance.InteriorParent;
                mobileEnemyArray = interiorInstance.GetComponentsInChildren<DaggerfallEnemy>();
            }
            //set dungeon interior indicator size and material and grab npc objects for assigning below.
            else if (GameManager.Instance.IsPlayerInside && GameManager.Instance.IsPlayerInsideDungeon)
            {
                GameObject dungeonInstance = GameManager.Instance.DungeonParent;
                mobileEnemyArray = dungeonInstance.GetComponentsInChildren<DaggerfallEnemy>();
            }

            //loop through location enemies, grab their mobile unity object, and use it to check gender and setup marker texture into empty texture object.
            int countTexture = 0;
            foreach (DaggerfallEnemy mobileEnemy in mobileEnemyArray)
            {
                Texture2D npcTempTexture = null;

                if (mobileEnemy.MobileUnit.Summary.Enemy.Gender == MobileGender.Male || mobileEnemy.MobileUnit.Summary.Enemy.Gender == MobileGender.Unspecified)
                    npcTempTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", mobileEnemy.MobileUnit.Summary.Enemy.MaleTexture), 0, 0, true, 0);
                else
                    npcTempTexture = ImageReader.GetTexture(string.Concat("TEXTURE.", mobileEnemy.MobileUnit.Summary.Enemy.FemaleTexture), 0, 0, true, 0);
                countTexture++;
            }

            Debug.LogFormat("TestBlessedMod counted {0} GetTexture() calls.", countTexture);
        }
    }
}
This works both in editor and builds without any errors. Here's the output from player.log in live 0.13.5 build inside Sentinel castle.

Code: Select all

TestBlessedMod counted 102 GetTexture() calls. 
Since error doesn't throw on this end, here are some things to try:
  • Delete project and re-clone fresh. Sometimes Unity editor caches some funky info, and this might be leeching into built mod.
  • Check your "using" statements in the affected script as missing one can cause TypeLoadException errors - though no idea why this would compile and work in editor if that was the case
  • Check other mods. Try my repro script above in total isolation with no other mods or changes to environment. Maybe something else in mix is triggering.
One other tip - you should check out the "GameManager.Instance.PlayerGPS.GetNearbyObjects()" method. This is a central helper that keeps track of common scene objects so they can be queried efficiently without needing to search scene yourself. This will also help track enemies that later pop into existence after your script has run (e.g. quest spawns, random spawns). See DetectEnemy script for an example of use. You could use this as the back-end and further track enemies in a dictionary using their LoadID if you need to add some other logic layer over it.

l3lessed
Posts: 1403
Joined: Mon Aug 12, 2019 4:32 pm
Contact:

Re: Unable to Solve Token Mismatch

Post by l3lessed »

Well, thanks for all the assists. I fixed it. I almost don't want to say the issue, because it is another dumb, nub oversight. I thought the stand alone build I was on was 13.5, but it was 13.4. Sorry for the stupidity and time waste. I guess that's why you don't do the lazy thing of copy and pasting over an old stand alone build folder.

The patience and level of assistance this community gives is really top notch.
My Daggerfall Mod Github: l3lessed DFU Mod Github

My Beth Mods: l3lessed Nexus Page

Daggerfall Unity mods: Combat Overhaul Mod

Enjoy the free work I'm doing? Consider lending your support.

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

Re: Unable to Solve Token Mismatch

Post by Interkarma »

Happy to hear it's fixed! :)

Post Reply