Modding Guides

The following are guides that I've written for some aspect of modding The Sims 4. If you have comments or questions, I suggest asking in the creators-workshop section of Deaderpool's discord. I don't have a devoted section for modding questions in my discord and I'm the only modder I know of in my discord who pays attention to it. Deaderpool's discord is the main hangout I know of for modders, so you'll likely get better help there.


Injecting to Test Autonomous

Download Template Script


I suggest downloading the Template Script first, so that you have the full thing on hand for reference. This guide assumes you have basic knowledge of modding for The Sims 4 already (though you are of course welcome to jump into the deep end if you don't) and will attempt to show you how to inject to the tuning in an interaction test_autonomous through a script, bypassing issues with overrides and compatibility, such that you will be able to:

  • Allow an interaction to be autonomous under new circumstances. For example, make it so that guitar_Practice can be done autonomously under new circumstances, like when a sim has the dazed buff from losing a fight.
  • Restrict an interaction's autonomy, such that under your desired circumstances, the sim can never do the interaction autonomously. For example, making it so that bed_Nap can only be done in a certain time range during the day (ex: from 1pm to 5pm).
  • Have some awareness of the limitations of injecting to test_autonomous and the logical issues that could arise if two different mods have conflicting design goals for the same interaction.

What this guide will NOT cover:

  • How to make an interaction autonomous that has its allow_autonomous tuning set to False. This is another topic and could require a lot more than fiddling with test_autonomous
  • How to change an interaction's test_globals or main tests section. For some interactions, you would need to modify both these and test_autonomous to expand the circumstances under which the interaction can autonomously occur. That is a convoluted area and is just a mess to work with for some interactions.
  • Why it is that the other reindeer never let Rudolph join in any reindeer games. That's a question for the creators of the character. I mean, who was raising those other reindeer? Bullies, I tell you.

Step 1: Allowing, aka: Whitelist

The first thing we will cover is how to add something as a new type of circumstance under which the interaction can trigger autonomously. We will be using the interaction guitar_Practice as the interaction we want to modify. I suggest locating this file in your extracted files if you have them all extracted, or going and extracting it with your XML Extraction Tool of choice, so you can follow along.

If you look in its test_autonomous section, you will notice a number of circumstances under which the interaction can occur autonomously already. Things like if it passes the appropriateness parameter, if Guitar Skill is level 2 or higher, etc. Note that each <L></L> part is a set of tests. This is important information, but don't worry, you don't need to memorize it. There won't be a test. I mean, wait. There will be tests... in the interaction. There won't be a test, testing you.

You know what I mean.

For what we're wanting to accomplish, we want to add a new set of tests, or new list, aka: <L></L> part. We're going to place these tests inside of a TestSetInstance file, so that our script only needs to know how to inject one type of input: a TestSetInstance file. You can go and extract any TestSetInstance file for reference, to build yours off of. I'm going to go for the first one I see, which is testSetInstance_NotOverflowingTrash, but it doesn't matter which one. I'm just pulling one out and making a copy so I don't have to write all of the code by scratch for our TestSetInstance file. I'm going to rename its n= value to Triplis:TestSetInstance_InjectingToTestAutonomous_Tutorial and then use my Auto Hash tool on it to get it set up more quickly.

Now we need to figure out what tests we want to have. How about I get your input? ... What's that? You want to make it so that sims can go for the Guitar when their bladder is low? Alright, if you say so.

I'm going to now go through the game files and look for an example of a test that checks for a statistic being in a certain range. There is no method to this particular madness, I just sort of search through a giant folder of the extracted XML files with various search terms until I find what I'm looking for. Aha! I found it and it's referencing bladder already too. Saves some time there.

Your file should now look something like this:

TestSetInstance file

No wait, that's a picture of somebody's lunch. Hang on...

Here we go:

TestSetInstance file

Now that we have our test, we need to add it to the interaction, but without needing to override and create compatibility problems. So our script comes into play. I suggest going and pulling up your Template Script you forgot to download at the beginning and/or I forgot to upload to the website. You will need it to follow what I'm talking about and create a working script for your mod.

The next step should be extremely simple, so I'm going to drag it out and make it sound way more complicated than it is: In the area of the Template Script where it says <- Put TestSetInstance ID here, put the s= value of your TestSetInstance file. This will summon the God of Thunder, Thor, who will bless your script with the electric fire of a thousand screaming suns.

Next, in the area where it says <- Put Interaction ID here, put the s= value of your Interaction file (in this case, the value from guitar_Practice). This will summon the God of Thunder, Thor, who will be very annoyed at you summoning him twice in a row and will smite you with the electric fire of a thousand screaming suns.

Finally, make sure that the part that says add_to_all on Line 67 is set to False. (Oh and if you're feeling daring and/or know how to code, you can change the comment that says "Put thing here" to the name of the interaction or test set, so you'll know what it's referencing at a glance.)

And you are done. Now you just need to do the steps which I will assume you already know how to do, even if you don't, because this tutorial isn't built to cover those things. Things like putting the TestSetInstance in a package file and compiling the script.

Step 2: Blocking, aka: Blacklist

This step erroneously assumes that you have done the first step, which may be very wrong-headed, but it does it anyway, so that it doesn't need to explain the same things twice. This step is all about blocking, aka: blacklist, aka: preventing an interaction that can be done autonomously from ever being done autonomously, unless it's under the circumstances you desire.

Incidentally, this is where things start to get complicated. Not the code or the steps you will need to perform, but the logic of the operations. I will cover this more in the final section, but for now, just know that making absolutely sure nothing can get through your blacklist operations can mean making sure things happen in the correct order. You may now proceed to furrow your brows and carry this concern with you throughout the rest of the guide.

For this example, we're going to revisit guitar_Practice. We're going to include what we did before and add on to it, so if you haven't done the first step yet, I suggest ignoring it and jumping into this with total confusion. I mean, no. The opposite of that. Whatever that is.

I will now get your input again... what's that? You want to make it so that guitar_Practice can only trigger autonomously if the sim's bladder is low? Well... ok. Weirdo. That makes things a bit easier though. Since we're doing it this way, we already have our TestSetInstance file ready to go and it can be used for our blocking/blacklist procedure.

We're going to go through the exact same procedure with our Script Template again, including being smited by Thor's unholy wrath, except this time we're going to make sure add_to_all on Line 75 is set to True. This will tell the code to add our test to every single test set in the test_autonomous tuning of the interaction, rather than only to a new, additional one.

The result is that every single set of tests in the test_autonomous tuning for guitar_Practice will now require the sim's bladder to be low, in addition to any other requirements it may have, for the test to be able to pass. Note that we're doing both this and adding a new set of tests with our bladder test, so that the sim can also pass the test just by having a low bladder, as that is a pretty important feature here. Who doesn't go for a Guitar when they need to pee? This needs to be as realistic gameplay as possible.

And now it is time for the last step, where I attempt to explain some convoluted scenarios and confuse you.

Step 3: Logic, aka: Headaches

If you have followed along to this point and understood clearly the directions provided, you may be wondering: That's it? All this for a couple of simple procedures? I brought the unholy wrath of the Thunder God, Thor, down on me for this?

Yes, but Thor thought you were important enough to smite. That's gotta be worth something, right? Furthermore, the main reason I decided to make an actual guide out of this is because of this last section.

Here's the deal: If you've been reading between the lines, it may have occurred to you that if, for example, Bob the modder makes a mod that changes guitar_Practice, specifically with the addition that it can occur autonomously when a sim is in their last stage of pregnancy, Bobbo (Bob's evil twin) may come in and make a mod that changes guitar_Practice, specifically with the change that it can only occur autonomously when a sim has the irritated moodlet from having witnessed a nearby toddler throwing a tantrum. One of these is going to lose out in the process.

In terms of code and errors, there will be no noticeable incompatibility between the two mods. In terms of design and desired outcome, one of two things will happen: Either Bob's mod will get away with running when it wants to, potentially trivializing the way Bobbo's mod restricted the interaction. Or Bobbo's mod will get away with blocking Bob's test from passing, potentially trivializing the way Bob's mod expanded the interaction.

And this is where order of operations comes in, which can be managed to some extent in the context of your own mod, but would probably be a lost cause if you're trying to resolve a conflict between two mods in this way. For example, in my Love and Hate Mod, I do all of my allowing/whitelisting first and then my blocking/blacklisting after. I do this because I have two different types of priorities at play: Checking for something a sim Loves, expanding when they can do a particular interaction if it pertains to something they Love, and blocking a particular interaction if it pertains to something a sim Hates. The whitelist procedure (which is the same one used in our Template Script) only expands the operations of the given interaction if it has something in its test_autonomous already. Otherwise, it would be creating an exclusive circumstance under which the interaction can occur in an interaction that has no existing test_autonomous restrictions, rather than expanding on the existing circumstances under which it can occur. So the blacklist needs to come after. If it was first, the whitelist would see the added blacklist and assume the interaction's test_autonomous has some kind of built in circumstances, so we need to expand on them.

This is just one example of the sort of convoluted logic you can get into with test_autonomous. It's also worth noting that expanding the circumstances under which an interaction can occur autonomously does nothing to how desirable the interaction is overall, so you could make something more available only for it to never, or rarely, run because there is little to no priority for it to do so.

With this knowledge in mind, you should be better equipped to handle it when someone comes to you and says your mod isn't working and you can't trace it to a script or tuning error. And then you realize that Bobbo, your evil twin, has once again been going off and wreaking havoc on the world, and you need to go collect the Sword of Indecisive Weight from the Stone, so that you can become King Arthur.