Replies: 7 (Who?), Viewed: 423 times.
Test Subject
Original Poster
#1 Old 9th May 2021 at 7:00 AM
Default My Custom Skill Mod Won't Allow Game To Start
I'm trying to create a basketball skill mod. As of right now, I'm just trying to get the skill to show up in the game. I used this tutorial to create a game compatible Visual Studio project. I took the code provided by Inge for his custom skill tutorial and pasted it into my project. I built a solution for the project and imported the .dll into my .package. I also ensured that _XML resource's name matches with the class that contains the kInstantiator. I filled out the SKIL using Inge's instructions.

The example skill mod that Inge included works perfectly but whenever I have mine installed it causes the game to crash before hitting the start menu. I was wondering if anyone has also encountered this issue and could give some insight.
Advertisement
Virtual gardener
staff: administrator
#2 Old 9th May 2021 at 11:54 AM
Heya! I had some issues with that tutorial as well, but could you send either your XML file and the code snippet here or the package? That way I can check it out for you (or someone else!) if there are any errors
Test Subject
Original Poster
#3 Old 10th May 2021 at 2:42 AM
Quote:
Originally Posted by Lyralei
Heya! I had some issues with that tutorial as well, but could you send either your XML file and the code snippet here or the package? That way I can check it out for you (or someone else!) if there are any errors

I uploaded the package. Thanks for your help!
Download - please read all instructions before downloading any files!
File Type: 7z TRAS_BasketballSkill.7z (4.2 KB, 7 downloads)
Virtual gardener
staff: administrator
#4 Old 11th May 2021 at 12:52 PM
Quote:
Originally Posted by TheRealAnimeSpot
I uploaded the package. Thanks for your help!
I think the reason we both had some issues with the tutorial is probably because of the way the game back then parsed skill data and how it does it now. There are a few extra lines that are needed, but first a few things inside the code

In your preload function, I'd always make sure when you're coding (unless you're releasing your mod of course ) to 'print' any errors. A try and catch statement basically helps with that, so the catch, if printed, will let you know what went wrong. Whether that's a null reference, or forgetting to close a bracket at the end of your XML line, etc. It's a helpful debugger! So I'd change that to the following:

Code:
     private static void OnPreload()
    {
        try
        {
            if (!HasBeenLoaded)
            {
            // The XML code you're using here I just deleted for easier understanding. But keep that the same of course 
            }
        }
      // Added a variable next to the Exception so that the catch can easily add it's code to the variable! 
        catch (Exception exception)
        {
         SimpleMessageDialog.Show("TITLE OF DIALOGUE, CHANGE TO ANYTHING", exception.Message); // Or you do exception.ToString() for the full error, which could be pretty overwhelming data if you're new to coding
        }
    }
First I'd try that, see what the error is

Secondly, Boostrapper, the class, doesn't need to be derived from GameObject. I think that's more of a coding style rather than anything, or that back then that was the only way that class would work, but nowadays, just doing 'public class Bootstrapper' is fine too

I also noticed that the HEX you're parsing into the ExampleUsesClass is incorrect. So the way how the 'parser' is converting your Hex, is that it chops off TRAS_BasketballSkill=0x93771772 into 'TRAS_BasketballSkill' and '0x93771772'. Not to get into the technical details too much, but that all has to do with parsing the enum value to the SkillNames enum, so that it has a 'name' and the 'number'. 
So, with that said, this variable:

Code:
private const SkillNames ExampleCustomSkillGuid = (SkillNames)0x0EDB3583;
Needs to actually be:

Code:
private const SkillNames ExampleCustomSkillGuid = (SkillNames)0x93771772; // The hex you gave it in the XML
You see how the number after (Skillnames) is now the hex you put in in your XML?  If the game parsed your skill data correctly, then this should work. But believe me, the parsing data thingy is super tedious. So one spelling mistake and it's not loading :p so debugging this thing is just... a pain.

Now, I will say, the exampleUsesClass is a bit misleading if you're new to sims 3 script modding. Personally, I'd say, remove that altogether and use nraas > mastercontroller > Advanced > Skill and see if your skill is there. It's probably at this point looking like a bunch of numbers

Now let's get to the XML... Right there you (And Igne's tutorial too actually) are missing something quite crucial, which is this line:

Code:
<CustomClassName>Sims3.Gameplay.Skills.Lyralei.SewingSkill, GlobalOptionsSewingTable</CustomClassName>
What this stands for is the Namespace + the skill class name , The DLL name it's in. In your case that would be:

Code:
<CustomClassName>Sims3.Gameplay.TRAS.Bootstrapper.BasketballSkill, TRAS_SimsModTemplate</CustomClassName>
Since you're creating probably a skill that will have a journal, it's always good to add this

And after that, it should probably work! If you want to actually see how you could apply your skill, I have a few links from my sewing table mod from Github you could check out

My SewingSkill setup: https://github.com/Lyralei1/SewingT.../SewingSkill.cs
My customised Skill Parser setup (Second try/catch in the OnPreLoad() function: https://github.com/Lyralei1/SewingT...sSewingTable.cs
CTRL+F to find 'SewingObjects' interaction and anything mention skills is what you can do with it: https://github.com/Lyralei1/SewingT.../SewingTable.cs

I'd suggest adding this to your Skill class though, since it's easier to then call it in your interaction as I did

Code:
Public const SkillNames ExampleCustomSkillGuid = (SkillNames)0x93771772; // The hex you gave it in the XML
Hope this helps! sorry it got to so long!
Test Subject
Original Poster
#5 Old 13th May 2021 at 12:09 AM
Quote:
Originally Posted by Lyralei
I think the reason we both had some issues with the tutorial is probably because of the way the game back then parsed skill data and how it does it now. There are a few extra lines that are needed, but first a few things inside the code

In your preload function, I'd always make sure when you're coding (unless you're releasing your mod of course ) to 'print' any errors. A try and catch statement basically helps with that, so the catch, if printed, will let you know what went wrong. Whether that's a null reference, or forgetting to close a bracket at the end of your XML line, etc. It's a helpful debugger! So I'd change that to the following:

Code:
     private static void OnPreload()
    {
        try
        {
            if (!HasBeenLoaded)
            {
            // The XML code you're using here I just deleted for easier understanding. But keep that the same of course 
            }
        }
      // Added a variable next to the Exception so that the catch can easily add it's code to the variable! 
        catch (Exception exception)
        {
         SimpleMessageDialog.Show("TITLE OF DIALOGUE, CHANGE TO ANYTHING", exception.Message); // Or you do exception.ToString() for the full error, which could be pretty overwhelming data if you're new to coding
        }
    }
First I'd try that, see what the error is

Secondly, Boostrapper, the class, doesn't need to be derived from GameObject. I think that's more of a coding style rather than anything, or that back then that was the only way that class would work, but nowadays, just doing 'public class Bootstrapper' is fine too

I also noticed that the HEX you're parsing into the ExampleUsesClass is incorrect. So the way how the 'parser' is converting your Hex, is that it chops off TRAS_BasketballSkill=0x93771772 into 'TRAS_BasketballSkill' and '0x93771772'. Not to get into the technical details too much, but that all has to do with parsing the enum value to the SkillNames enum, so that it has a 'name' and the 'number'. 
So, with that said, this variable:

Code:
private const SkillNames ExampleCustomSkillGuid = (SkillNames)0x0EDB3583;
Needs to actually be:

Code:
private const SkillNames ExampleCustomSkillGuid = (SkillNames)0x93771772; // The hex you gave it in the XML
You see how the number after (Skillnames) is now the hex you put in in your XML?  If the game parsed your skill data correctly, then this should work. But believe me, the parsing data thingy is super tedious. So one spelling mistake and it's not loading :p so debugging this thing is just... a pain.

Now, I will say, the exampleUsesClass is a bit misleading if you're new to sims 3 script modding. Personally, I'd say, remove that altogether and use nraas > mastercontroller > Advanced > Skill and see if your skill is there. It's probably at this point looking like a bunch of numbers

Now let's get to the XML... Right there you (And Igne's tutorial too actually) are missing something quite crucial, which is this line:

Code:
<CustomClassName>Sims3.Gameplay.Skills.Lyralei.SewingSkill, GlobalOptionsSewingTable</CustomClassName>
What this stands for is the Namespace + the skill class name , The DLL name it's in. In your case that would be:

Code:
<CustomClassName>Sims3.Gameplay.TRAS.Bootstrapper.BasketballSkill, TRAS_SimsModTemplate</CustomClassName>
Since you're creating probably a skill that will have a journal, it's always good to add this

And after that, it should probably work! If you want to actually see how you could apply your skill, I have a few links from my sewing table mod from Github you could check out

My SewingSkill setup: https://github.com/Lyralei1/SewingT.../SewingSkill.cs
My customised Skill Parser setup (Second try/catch in the OnPreLoad() function: https://github.com/Lyralei1/SewingT...sSewingTable.cs
CTRL+F to find 'SewingObjects' interaction and anything mention skills is what you can do with it: https://github.com/Lyralei1/SewingT.../SewingTable.cs

I'd suggest adding this to your Skill class though, since it's easier to then call it in your interaction as I did

Code:
Public const SkillNames ExampleCustomSkillGuid = (SkillNames)0x93771772; // The hex you gave it in the XML
Hope this helps! sorry it got to so long!


Thank you for your help! The reason my game wouldn't start is because I was building the .dll with v4.6 of .NET, so I changed it to 2.0. Unfortunately, the skill isn't showing up when I use MasterController. The exception message isn't showing up either. Its supposed to appear in-game, correct? Here's what I changed my code to.

Code:
namespace Sims3.Gameplay.TRAS
{
    public class Bootstrapper
    {
        static bool HasBeenLoaded = false;

        [Tunable]
        protected static bool kInstantiator = false;

        static Bootstrapper()
        {
            // gets the OnPreload method to run before the whole savegame is loaded so your sim doesn't find
            // the skill missing if they need to access its data
            LoadSaveManager.ObjectGroupsPreLoad += Bootstrapper.OnPreload;
        }

        static void OnPreload()
        {
            try
            {
                if (HasBeenLoaded) return; // you only want to run it once per gameplay session

                HasBeenLoaded = true;

                // fill this in with the resourcekey of your SKIL xml
                XmlDbData data = XmlDbData.ReadData(new ResourceKey(0x0CE74B4C5ACE0EB7, 0xA8D58BE5, 0x00000000), false);

                if (data == null)
                {
                    return;
                }

                SkillManager.ParseSkillData(data, true);

            }

            catch (Exception exception)
            {
                SimpleMessageDialog.Show("You f***** up!", exception.Message);
            }
        }

        public class BasketballSkill : Skill
        {
            public BasketballSkill(SkillNames guid) : base(guid)
            {
            }
            private BasketballSkill()
            {
            }
        }

        public class ExampleUsesClass : GameObject
        {
            private const SkillNames ExampleCustomSkillGuid = (SkillNames)0x93771772;

            public void ExampleUses(Sim s)
            {
                if (!s.SkillManager.HasElement(ExampleCustomSkillGuid))
                {
                    s.SkillManager.AddElement(ExampleCustomSkillGuid);
                }
                s.SkillManager.AddSkillPoints(ExampleCustomSkillGuid, 3.0f);
                Skill sk = s.SkillManager.GetElement(ExampleCustomSkillGuid);
                float sl = sk.SkillPoints;

            }

        }
    }
}


Virtual gardener
staff: administrator
#6 Old 14th May 2021 at 11:19 AM Last edited by Lyralei : 14th May 2021 at 11:19 AM. Reason: Fixed spoiler being removed
Hrm I'm not sure if you have the same issue, but I had to write my own custom importer, since riiight at the end where the game would parse the skill into it's Dictionary, mine would get flagged for some reason. So, this was the code I came up with for it:


In your case, if you do choose to try my parser, you can replace:

Code:
SkillManager.ParseSkillData(data, true);
To:

Code:
ParseSkillData(data, true);
And voila! It also makes it easier to debug the skill and putting print statements on each line :p that's what I do!
Test Subject
Original Poster
#7 Old 19th Jul 2021 at 1:19 AM
I copied your skill parser from your Sewing Table mod, made a .dll of it and referenced it in my basketball mod. There weren't any errors when I compiled it but its still not showing up in game. The error message isn't showing up either. But I know that its being loaded into the game because its listed under loaded assemblies in the error log. Does the code for the skill parser have to be included directly in my basketball mod in order for it work?
Instructor
#8 Old 21st Jul 2021 at 11:15 PM
Have you checked to see if there is an existing hidden skill for the store basketball goal? That might be causing trouble.

Echo Weaver's Simblr: http://echoweaver.tumblr.com/
A portrait in stubbornness - Playing the same legacy since 2009
Sample a Brave Legacy: http://sims3sample.illation.net
Back to top