Quick Reply
Search this Thread
Scholar
Original Poster
#1 Old 19th Oct 2021 at 2:50 AM
Default Custom Moodlet Tutorial
My new tutorial on creating Custom moodlets is here check it out



For some reason processing is taking a lot of time. Maybe cause it's a long video. If there are problems let me know.

If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Scholar
#2 Old 26th Oct 2021 at 3:11 PM
Oh, wow! Your tutorials are amazing. I have spent a long time working from Nona Meena's custom moodlet tutorial, but there's just no substitute for seeing it in a video. (And I speak as someone who usually only wants text tutorials )

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
Scholar
Original Poster
#3 Old 26th Oct 2021 at 10:06 PM
Quote: Originally posted by echoweaver
Oh, wow! Your tutorials are amazing. I have spent a long time working from Nona Meena's custom moodlet tutorial, but there's just no substitute for seeing it in a video. (And I speak as someone who usually only wants text tutorials )


Thank you very much! Means a lot.

If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Scholar
Original Poster
#4 Old 27th Oct 2021 at 6:34 PM
Part 2 is here. Shows you how to create custom thumbnails for your moodlets. Check it out.


If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Scholar
Original Poster
#5 Old 23rd Nov 2021 at 9:51 AM
Part 3 is here. Shows you about 4 methods used in moodlet class. Check it out.


If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Forum Resident
#6 Old 27th Nov 2021 at 11:03 AM Last edited by olomaya : 27th Nov 2021 at 11:23 AM.
Would you be able to share the cs for the script and package file you used in the video? I'm trying to create custom moodlets for my mod and haven't had any success with any tutorial I've tried so far even when copying word for word. I'd love to just see a full basic template to better understand where I'm going wrong.
Scholar
Original Poster
#7 Old 28th Nov 2021 at 3:16 AM
Quote: Originally posted by olomaya
Would you be able to share the cs for the script and package file you used in the video? I'm trying to create custom moodlets for my mod and haven't had any success with any tutorial I've tried so far even when copying word for word. I'd love to just see a full basic template to better understand where I'm going wrong.


Yea sure.

Tips:- If you created separate namespace and class for moodlet then you will need a new kInstantiator or similar variable. Make sure all the numbers are correct in the xmldb code. The xml itself is correct. No missing </...> . xmls for other mods also can't have missing close tags.

Ask me for more help if you need. @ my name though or I won't get notification.
Attached files:
File Type: 7z  Class1.7z (2.7 KB, 38 downloads)

If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Forum Resident
#8 Old 28th Nov 2021 at 12:57 PM
Thank you! I think my issue is likely with the instantiator class. I'll do some more testing tomorrow.
Forum Resident
#9 Old 29th Nov 2021 at 12:23 PM Last edited by olomaya : 29th Nov 2021 at 1:37 PM.
@PuddingFace, Thanks again for sharing. Unfortunately, I'm still stumped in that none of my custom moodlets are showing up in the game. I've quadruple-checked at his point to make sure there are no issues with the XML, the Stbl entries, and I have social data in the same script that is loading fine, just not the buffs.

Code:
namespace olomaya.Religious.Buffs_Socials
{
	public class Main
	{
		[Tunable] static bool init;

		static Main()
		{
			LoadSaveManager.ObjectGroupsPreLoad += OnPreLoad;
			World.sOnWorldLoadFinishedEventHandler += OnWorldLoaded;
			World.sOnStartupAppEventHandler = (EventHandler)Delegate.Combine(World.sOnStartupAppEventHandler, new EventHandler(OnStartupApp));
		}

		public static void OnPreLoad()
		{
			new BuffBooter().LoadBuffData();
		}

		static void OnWorldLoaded(object sender, EventArgs e)
		{
			Initialize();
		}

		public static void OnStartupApp(object sender, EventArgs e)
		{
			try
			{
				LoadSocialData("Olomaya_Religion_SocialData");
				LoadSocializingActionAvailability("Olomaya_Religion_SocializingActionAvailability");
			}
			catch (Exception exception)
			{
				SimpleMessageDialog.Show("Socials not loaded", exception.Message);
			}
		}

		public static void LoadSocialData(string resourceName)
		{
			XmlDocument xmlDocument = Simulator.LoadXML(resourceName);
			bool isEp5Installed = GameUtils.IsInstalled(ProductVersion.EP5);
			if (xmlDocument == null)
			{
				return;
			}
			XmlElementLookup xmlElementLookup = new XmlElementLookup(xmlDocument);
			List<XmlElement> list = xmlElementLookup["Action"];
			foreach (XmlElement item in list)
			{
				XmlElementLookup table = new XmlElementLookup(item);
				ParserFunctions.TryParseEnum(item.GetAttribute("com"), out var value, CommodityTypes.Undefined);
				ActionData data = new ActionData(item.GetAttribute("key"), value, ProductVersion.BaseGame, table, isEp5Installed);
				ActionData.Add(data);
			}
		}

		public static void LoadSocializingActionAvailability(string resourceName)
		{
			XmlDbData xmlDbData = XmlDbData.ReadData(resourceName);
			if (xmlDbData == null)
			{
				return;
			}
			try
			{
				if (xmlDbData.Tables.ContainsKey("SAA"))
				{
					SocialManager.ParseStcActionAvailability(xmlDbData);
				}
				if (xmlDbData.Tables.ContainsKey("TAA"))
				{
					SocialManager.ParseActiveTopicActionAvailability(xmlDbData);
				}
				if (xmlDbData.Tables.ContainsKey("ActionNames"))
				{
					SocialManager.ParseActionNames(xmlDbData);
				}
				if (xmlDbData.Tables.ContainsKey("ActionTopics"))
				{
					SocialManager.ParseActiveTopic(xmlDbData);
				}
			}
			catch (Exception)
			{
			}
		}

		public static void Initialize()
		{
			
		}
	}
	internal class BuffBooter
	{
		public void LoadBuffData()
		{
			AddBuffs(null);
			UIManager.NewHotInstallStoreBuffData = (UIManager.NewHotInstallStoreBuffCallback)Delegate.Combine(UIManager.NewHotInstallStoreBuffData, new UIManager.NewHotInstallStoreBuffCallback(AddBuffs));
		}

		public void AddBuffs(ResourceKey[] resourcekey)
		{
			ResourceKey key = new ResourceKey(ResourceUtils.HashString64("olomaya_Religion_Buffs"), 53690476u, 0u);
			XmlDbData xmlDbData = XmlDbData.ReadData(key, bSuppressLogs: false); 
			if (xmlDbData != null)
			{
				BuffManager.ParseBuffData(xmlDbData, true);
			}
		}
	}
}


I added in an exception catch and keep getting the message upon startup "A null value was found where an object instance, etc". Does that mean the issue is with the XML not being read?
Scholar
Original Poster
#10 Old 30th Nov 2021 at 7:28 AM
@Olomaya Ok I suggest creating separate namespaces like in my mod. Separate it out. Remove the moodlet code from your project and start fresh. Copy paste my code into your project and change the names to fit your mod. And then try.

If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Forum Resident
#11 Old 30th Nov 2021 at 8:59 AM
Quote: Originally posted by PuddingFace
@Olomaya Ok I suggest creating separate namespaces like in my mod. Separate it out. Remove the moodlet code from your project and start fresh. Copy paste my code into your project and change the names to fit your mod. And then try.


@PuddingFace Ah, yay, that worked! Separating it out into new namespaces did the trick. I was even able to keep it in the same project. I have it working though not all of my moodlet images are showing up. So I'll guess I'll be watching your third video today to deal with that.
Thanks so much for your help!
Scholar
Original Poster
#12 Old 30th Nov 2021 at 9:35 AM
Quote: Originally posted by olomaya
@PuddingFace Ah, yay, that worked! Separating it out into new namespaces did the trick. I was even able to keep it in the same project. I have it working though not all of my moodlet images are showing up. So I'll guess I'll be watching your third video today to deal with that.
Thanks so much for your help!

Yay! That's awesome!

If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Scholar
Original Poster
#13 Old 24th Dec 2021 at 3:01 AM
Forgot to post here but part 4 is here. Shows you how to make Instance class and through that add vfx via moodlet and change the value of a variable inside the moodlet after it has already been added through external means.


If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Scholar
Original Poster
#14 Old 23rd Jan 2022 at 6:21 PM
Part 5 is here. Shows you how to add Event Listener to a Sim via a moodlet.


If you like my mods. Consider supporting me on Patreon
Check out my website for updates on my mods and other work PuddingFace.wixsite.com
Check out my Youtube channel for tutorials(modding tutorials) and other content Youtube

Follow me on Twitter Instagram Pinterest Tumblr
Test Subject
#15 Old 2nd Mar 2025 at 6:50 AM Last edited by simmerbago : 3rd Mar 2025 at 6:51 AM. Reason: spelling
Default Question for regarding Loading Buffs
Hello @PuddingFace,

Thank you for the tutorials! They've been really helpful. However, I'm currently stuck as the moodlet is not appearing in the game. Could you nudge me in the right direction and point out where the issue might be?

Any guidance would be much appreciated!

Project Name: Royalliving


Adding 2 Namespaces
Code:
namespace Royalty_MoodletLoaderTutorial
{
    // The BuffBooter class is responsible for loading custom moodlets into the game.
    // This ensures that our custom buffs/moodlets are recognized by the game when the mod is loaded.
    internal class BuffBooter
    {
        // This method initializes the loading process for our custom moodlets.
        public void LoadBuffData()
        {
            AddBuffs(null);
            // Add a callback to load additional buff data when needed
            UIManager.NewHotInstallStoreBuffData = (UIManager.NewHotInstallStoreBuffCallback)Delegate.Combine(UIManager.NewHotInstallStoreBuffData, new UIManager.NewHotInstallStoreBuffCallback(AddBuffs));
        }

        // This method fetches the moodlet data from an external XML file and loads it into the game.
        public void AddBuffs(ResourceKey[] resourceKeys)
        {
            // Read data from the external XML resource file
            XmlDbData xmlDbData = XmlDbData.ReadData(new ResourceKey(ResourceUtils.HashString64("RoyaltyMod_AllBuffs"), 53690476U, 0U), false);
            bool flag = xmlDbData != null;
            if (flag)
            {
                // Parse the loaded buff data and add it to the game
                BuffManager.ParseBuffData(xmlDbData, true);
            }
        }
    }
    
    // The Instantiator class ensures that the BuffBooter loads our custom moodlets when the game starts.
    public static class Instantiator
    {
        [Tunable] // This attribute allows the value to be configured externally if needed.
        internal static bool kInstantiator2 = false;

        // Static constructor that triggers when the game starts.
        static Instantiator()
        {
            // Registers the OnPreLoad method to run before objects are fully loaded in the game.
            LoadSaveManager.ObjectGroupsPreLoad += OnPreLoad;
        }

        // This method ensures that the BuffBooter class loads the custom moodlets.
        public static void OnPreLoad()
        {
            (new BuffBooter()).LoadBuffData();
        }
    }
}

namespace Royalty_MoodletsTutorial
{
    // This class represents an individual custom moodlet, defining its properties and behavior.
    public class BuffTutorialTestMoodlet : Buff
    {
        // Every moodlet needs a unique identifier (GUID) to prevent conflicts.
        private const ulong kTutorialTestBuffGuid = 0xCB5CDCDEC3B74570;

        // This property returns the GUID for our custom moodlet.
        public static ulong StaticGuid
        {
            get { return 0xCB5CDCDEC3B74570; }
        }

        // The constructor initializes the moodlet with its data.
        // The BuffData parameter holds the information about how the moodlet behaves in the game.
        public BuffTutorialTestMoodlet(BuffData data) : base(data) { }
    }
} 


Creating a string:

All Buff List -Bufflist_RoyaltyMod
Quote:
<?xml version="1.0"?>
<buffs_RoyaltyMod>
<BuffList>
<BuffName></BuffName>
<BuffDescription></BuffDescription>
<BuffHelpText></BuffHelpText>
<FirstPersonDescription></FirstPersonDescription>
<Category></Category>
<PermaMoodlet>False</PermaMoodlet>
<PermaMoodletColor></PermaMoodletColor>
<AxisEffected></AxisEffected>
<PolarityOverride>NoOverride</PolarityOverride>
<EffectValue></EffectValue>
<DelayTimer>0</DelayTimer>
<TimeoutLength></TimeoutLength>
<SKU>BaseGame</SKU>
<SolveCommodity></SolveCommodity>
<AttemptAutoSolve>False</AttemptAutoSolve>
<SolveTime></SolveTime>
<Stackable></Stackable>
<IsExtreme>False</IsExtreme>
<FacialIdle></FacialIdle>
<IncreasedEffectiveness></IncreasedEffectiveness>
<ReducedEffectiveness></ReducedEffectiveness>
<Hex></Hex>
<CustomClassName></CustomClassName>
<ThumbFilename></ThumbFilename>
<Topic></Topic>
<ShowBallon>True</ShowBallon>
<Travel>False</Travel>
<DisallowedOccults></DisallowedOccults>
<JazzStateSuffix></JazzStateSuffix>
<Version>0.1</Version>
<SpeciesAvailability>All</SpeciesAvailability>
</BuffList>
<BuffList>
<Hex>TutorialTestBuffs = 0xCB5CDCDEC3B74570</Hex>
<SKU>EP6</SKU>
<BuffName>RoyaltyMoodletBuff</BuffName>
<BuffDescription>RoyaltyMoodletBuff_BuffDescription</BuffDescription>
<ThumbFilename>moodlet_ensorcelled</ThumbFilename>
<AxisEffected>None</AxisEffected>
<EffectValue>0</EffectValue>
<TimeoutLength>180</TimeoutLength>
<CustomClassName>Royalty_MoodletsTutorial.BuffTutorialTestMoodlet, Royalliving</CustomClassName>
</BuffList>
</buffs_RoyaltyMod>


Thanks for the help
Screenshots
Back to top