In today's tutorial I'll teach you all about installing.package file Mods for the Sims 3. In today's tutorial I'll teach you all about installing.package file Mods for the Sims 3. Dec 23, 2015 - Explore Mikayla's board 'Sims tutorials,mods,etc' on Pinterest. See more ideas about sims, sims 3 mods, sims 3.
|
This tutorial will explain how to make a pure scripting mod, i.e. a mod that isn't tied to an object.
While getting started is a bit more complicated than for an object mod, the actual coding can be as simple or complicated as you want. For today we will make a handy little mod that pauses the game after loading a save game.
Before we look at the actual code, we need to set up the VS project to support tunable values. I'll explain why we need to do that later in this tutorial.
When VS first opens AssemblyInfo.cs, it will probably throw lots of errors at you. Just ignore that for now. Add using Sims3.SimIFace; and [assembly: Tunable] to it and save. It should now look like that:
(only partly shown)Now bring up the actual code file of your project again. The bare code skeleton VS created should still look like this:
Choose wisely when it comes to your namespace and pick something that hopefully will be unique. You don't want your namespace to clash with an EAxian namespace or with another modder's namespace. Afterwards, the code should look like this:
I am using TwoBTech for my mods, but you must use something else! Don't use someone else's namespace just like that!
Now add the static constructor and a static field with the Tunable attribute to your class. The 'nature' of that field isn't really important. You can use a float or int just as well as a bool. I always use a boolean variable called kInstantiator which is a hidden homage to twallan. The class will now look like this:
Now might be a good moment to explain why we do this. C# or better the .NET framework has some concrete rules. We will 'exploit' one of these rules to get our script up and running in TS3. This rule goes as follows: The first time a static field, property or method of a class gets accessed, the static constructor of that class will be called. That is to make sure that everything is in decent shape before the class has to interact with the rest of the world.
TS3 on the other hand parses all XML resources, and assigns the tunable values it finds in there to the related variables in the related classes. So. TS3 assigns a value to our static variable, the static constructor of our class will be called, and badda bing we have a foot in the door to get our code running. We will make sure TS3 actually finds an XML resource for our tunable variable later when it comes to building the package.
The parsing XML and calling static constructor stuff will be happen really soon, long before the main menu will show for the first time. At that time, our mod can't do anything fancy, because almost none of the interesting stuff is running yet. In Reflector, you'll find a delegate handler called OnWorldLoadFinishedEventHandler in Sims3.SimIFace.World. I trust you know that a delegate is a reference type variable that, instead of referencing an object, references a function. This specific delegate handler, like its name implies, calls all its delegates once a world has been loaded. That will be after you started a new neighborhood, the loading of a savegame, the transition to a vacation world or the transition back from a vacation world. Good time for us to strike, isn't it?
To use OnWorldLoadFinishedEventHandler, add a callback method to your class and, in the static constructor, instantiate a new delegate pointing to that method and add it to OnWorldLoadFinishedEventHandler. It's all right if you're confused now. I know delegates confused the hell outta me. Sometimes they still do. Your class should now look like this:
We now have the basis for our pure scripting mod. All pure scripting mods work that way. In our OnWorldLoadFinished() method, we can begin to invoke our code.
We will keep it simple and make a mod that makes sure the game stays paused after loading a savegame. In Sims3.Gameplay.Gameflow (look that up in Reflector), you'll find find a method to affect the game speed: SetGameSpeed(Gameflow.GameSpeed, GameSpeedContext). That's the method our OnWorldFinished() method will call.
If you look at the code of SetGameSpeed(), you'll see that it does some fancy checks if the setGameSpeedContext parameter is anything but SetGameSpeedContext.GameStates. We don't want any fancy checks or anything. We just want it to set the game speed to pause. I suggest we use SetGameSpeedContext.GameStates as second parameter to avoid the checks. Now add the call of SetGameSpeed() to your OnWorldLoadFinished() method. It will look like this:
The code is now finished and should look like this:
Save your project (again) and click on Build -> Build Solution.
Leave VS open for now.
Open a text editor and paste the following:
Of course you have noticed the kInstantiator variable from the code. Save the file. You can close the text editor now as you won't need it again.
Open S3PE and click on File -> New to start a new package.
First add the script itself:
It's time to save your package. Usually, it's a good idea to begin the filename with your username or something that will identify all your mods.
Now on to the tuning XML:
Save the package.
Give the package a test run in the game. If you followed this tutorial, it will work. Basically. It doesn't pause the game after the transition to a vacation world. Let's see if we can do something about that. The easiest way should be to delay the call of SetGameSpeed() a little until we know that the game clock is actually running. We will do that by adding an alarm that fires one second after setting it.
AlarmManager.Global.AddAlarm(1f, TimeUnit.Seconds, new AlarmTimerCallback(OnPauseAlarm), 'Pause Alarm', AlarmType.NeverPersisted, null);
Of course you assume that you'll find the AlarmManager class in Sims3.Gameplay.Utilities, and you are right. Please note that AlarmTimerCallback is a delegate, too. Your code should now look like this:
Save the project and build the solution again. In S3PE import the updated .dll file. Save the package and again test it in the game.
That's better. The game will now definitely be paused, but now there's a new glitch: If the game was actually automatically paused post load, then the mod will pause it again immediately after you un-pause it. That's not the end of the world, but let us see if we can do something about it nevertheless.
Hint: The quick&dirty but fully functional solution would be to set the game speed to normal in OnWorldLoadFinished() and then pause it again in OnPauseAlarm(). I want to show you something, though.
Now might be a good idea to fire up your browser and learn what events are in programming. That is if you didn't already. In a nutshell, an event is some occurrence of interest, a listener or client is something that expresses the wish to be informed of that occurrence, and the handler is responsible for notifying the listeners, i.e. raising the events. The notifying happens by calling a method that is called callback. And yes, this is delegate stuff again. It's not necessary to fully understand the quoted call right now. It's just important to understand that OnArrivalAtVacationWorld() makes a class named EventTracker raise an event and not just any event but an event that is specified as EventTypeId.kSimEnteredVacationWorld. Look up the EventTypeId enum in Sims3.Gameplay.EventSystem.
Now what will we do about that event stuff?
The code should now look like this:
Save the project and build the solution again. In S3PE import the updated .dll file. Save the package and again test it in the game.
If you followed this tutorial, you should now have a mod that allows you to take a quick leak after sending your sims to a vacation or get some cookies after telling TS3 to load your save game. You know you deserve a cookie now.
You learned how to set up a VS project for a pure scripting mod, and got to know two things that are extremely handy when it comes to modding TS3: alarms and events.
It's perfectly all right if you don't fully understand all this delegate stuff and the syntax right away. You can just copy&paste the relevant parts to your new projects for the time being. Your understanding of C# and the TS3 code base will advance if you just keep going.
The mod we made in this tutorial is as simple as it gets. What you can do with a pure scripting mod is somewhat limited, but there are still lots and lots of things you CAN do. That is if you know how. How do you learn how? For the beginning, I suggest to look at other modders' code in Reflector to see what they did and how they did it. Follow their calls in Reflector and look what the EAxian code they're calling does. Start with simple mods. You can't expect to get accustomed to the whole TS3 code base in an instant.
That's why I lead you to first versions of the mod that didn't do exactly what they were supposed to do, beside showing you alarms and events. That is just how scripting modding goes. Sometimes things work right away, but that will be an absolute exception. I suggest keeping that in mind to avoid getting frustrated.
Ask them here: Q&A Thread for Sims 3 Pure Scripting Modding Tutorial