Forum Announcement, Click Here to Read More From EA_Cade.

Is it possible to make social interactions with XML tuning?

pearlbhpearlbh Posts: 313 Member
edited March 5 in Nominated Threads
I have heard that it is possible to make custom social interactions with XML tuning, but that it comes with the cost of incompatibility with other people's mods. Could someone explain exactly what kind of incompatibility that would be? And if it's really better to use Python, I'd like suggestions on simple absolute-beginner tutorials on how to use it to make a custom interaction.

Just to clarify, I am talking about social interactions for Sims. Specifically, I have a custom trait and I'd like to have Sims with my trait have special friendly interactions that only they can do, the way that some traits, say Music Lover, can "Discuss Favorite Band" or Geeks can "Enthuse about New Show." There are a few tutorials I've found that deal with adding interactions to objects, but I haven't found anything that's for social mixer interactions.
Post edited by EA_Cade on

Comments

  • Options
    thewatcheruatuthewatcheruatu Posts: 295 Member
    I haven't done anything with custom interactions yet, but isn't it just a matter of creating your interaction and then setting the "buff_preference" for it to the hidden custom buff associated with your trait?

    I could be wrong. There may be way more involved in it than that. If so, I'd like to know, as well, since this is something I'd potentially like to do at some point.
  • Options
    pearlbhpearlbh Posts: 313 Member
    I don't know how to even make interactions yet. Our custom traits do come with an interaction XML file, but I don't know how to actually make an XML interaction, let alone python. I think the first thing I'm going to have to do is find a basic beginners python tutorial, them find a tutorial specifically for the Sims 4 and specifically for adding custom interactions (the latter DOES exist on MTS, but I think a general python tutorial is probably necessary first.)

  • Options
    TriplisTriplis Posts: 3,048 Member
    It has something to do with using python scripts to inject the interaction into a list, rather than manually adding it to the game's XML file and using that edited file as an override. Problem is, I'm so far having trouble getting an injection to work, myself. The override method is working for me fine, but that method creates incompatibility problems.

    I can explain about these lists a little bit (at least, on the XML end), but I feel rather out of my element on the subject since I haven't gotten an actual injection working yet.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    RexZhengRexZheng Posts: 201 Member
    I think you can look at this post on MTS, I read the post and now I can inject interactions to the game.

    I cannot post links now, but you cna go to MTS and see the modding discussion section, the first post is really helpful.
  • Options
    RexZhengRexZheng Posts: 201 Member
    @Triplis I have successfully injected interactions, what problems did you encounter?
  • Options
    TriplisTriplis Posts: 3,048 Member
    @RexZheng I made a post over there with my scripts: http://modthesims.info/showthread.php?t=591559

    I'll post them here as well (well, I say "my scripts," but they were pretty much copy/paste with ID name changes).

    Basically, I wanted to inject into the list you find in object_sim, the one for interactions that show up when you click on your sim (and don't require another sim to do them). I thought this was the right code for it, but something isn't working because the interaction simply doesn't show up. It only shows up if I use an XML override, i.e. editing object_sim directly and putting it in my package file.

    (I hope I'm not intruding on your thread, pearlbh)


    Injector (named "triplis_child_play_injector")
    # Python function injection
    # By scripthoge at ModTheSims
    #
    from functools import wraps
    import inspect
    
    # method calling injection
    def inject(target_function, new_function):
        @wraps(target_function)
        def _inject(*args, **kwargs):
            return new_function(target_function, *args, **kwargs)
        return _inject
    
    # decarator injection.
    def inject_to(target_object, target_function_name):
        def _inject_to(new_function):
            target_function = getattr(target_object, target_function_name)
            setattr(target_object, target_function_name, inject(target_function, new_function))
            return new_function
        return _inject_to
    
    def is_injectable(target_function, new_function):
        target_argspec = inspect.getargspec(target_function)
        new_argspec = inspect.getargspec(new_function)
        return len(target_argspec.args) == len(new_argspec.args) - 1
    

    Other file (I don't know what you'd call it... the thing that calls the injector)
    import services
    import triplis_child_play_injector
    import sims.sim
    
    Triplis_Child_Play_sa_instance_ids = (13884954916998690505, )
        
    @triplis_child_play_injector.inject_to(sims.sim.Sim, 'on_add')
    def Triplis_Child_Play_add_super_affordances(original, self):
        original(self)
        sa_list = []
        affordance_manager = services.affordance_manager()
        for sa_id in Triplis_Child_Play_sa_instance_ids:
            tuning_class = affordance_manager.get(sa_id)
            if not tuning_class is None:
                sa_list.append(tuning_class)
        self._super_affordances = self._super_affordances + tuple(sa_list)
    
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    RexZhengRexZheng Posts: 201 Member
    @Triplis Mmm...Yeah your Python lines seems correct, how did you compile them? Maybe it's a process during the compilation that was wrong?
    And, I'm not sure about it, but you could try if you add these lines?
    import objects.game_object
    or
    import sims4.resources

    I know the first line is used when we inject interactions to an object, but the game considers a Sim an object so maybe we should add that?
    Not quit sure, though.
  • Options
    TriplisTriplis Posts: 3,048 Member
    edited March 2017
    @RexZheng Thanks for the help! I just tried adding those and nothing, unfortunately.

    Now that you mention compiling though, I wonder, does the game have issues reading scripts if they are .py, rather than .pyo? I was under the impression that .pyo is for performance, so I've been doing testing in .py and figured I'd compile later, but now I'm wondering if it's something as boneheaded simple as that.

    Also, I just tried compiling to see if that would get any different results and got this error when I tried to compile the second file:

    "ImportError: No module named services"

    I can only assume it's referring to the line "import services" and if it's getting an error on the first line, I don't know if it's even compiling that file at all, even though it did spit out a .pyo file anyway, which I tried along with the other one compiled and still no results in-game. I've no idea why it's giving that error though.

    Edit: I tried decompiling the file I compiled that got the error and it's all there, intact, so I guess the error didn't actually cause any problems. Which unfortunately puts me back at square one, as the scripts still aren't making the interaction show, compiled or no.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    RexZhengRexZheng Posts: 201 Member
    @Triplis I think you need a .pyo file for the game to read it!
    As for "ImportError: No module named services", I encounter it every time and it seems that it just doesn't matter. My scripts are working fine but it shows up every time!
    And...did you zipped those files with the injector? And when I fist made script mods, the WinRAR sometimes create a subfolder inside the zip file, making the game unable to read it.
    Hope this helps!
  • Options
    TriplisTriplis Posts: 3,048 Member
    @RexZheng Thanks! I made sure they are all compiled now. I think with your help I'm steadily narrowing this down.

    I realized now that I'm getting a lastexception error file concerning my scripts when the game tries to load them. Says: ZipImportError: can't find module 'my_script_name' for both scripts.

    I can only assume there's some weirdness with how I'm zipping files that it isn't happy about. Usually what I do is select both at the same time, then right-click and send-to-compressed-zip-folder. They are then both in that zip folder together, which I'm pretty sure is how it should be.

    Anyway, I need to sleep now. Maybe it will make more sense with some rest.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    NeiaNeia Posts: 4,190 Member
    @Triplis
    You can use .py but the files need to be in a /Testing/Scripts/ folder. It's very convenient when you're testing your scripts because you don't have to recompile each time so it saves time.

    @pearlbh
    I've been using the same method as Triplis too : create a XML interaction, and inject it with Python. You can take a look here for some explanation : http://modthesims.info/t/546901 by Scumbumbo with a more in-depth explanation about injection by Deaderpool on post 36. It may be the thread RexZheng was talking about but couldn't link, because it's a really helpul thread. :)
  • Options
    TriplisTriplis Posts: 3,048 Member
    @Neia Oh, that's how you test them. Thanks! I tried that and my scripts work. Woot! Only thing I need to figure out now is what's wrong with my zip files and why the game is complaining when it tries to read the compiled scripts in them.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    TriplisTriplis Posts: 3,048 Member
    @RexZheng @Neia Hey guys, thanks both of you for your help. I just wanted to let you know, I figured out the final issue (this zip import thing) and my scripts are now fully functioning, compiled.

    Apparently I had both Python 2.7 and Python 3.3 installed on my computer. And when I used the run prompt python.exe -O to compile, it was bringing up Python 2.7, which I now realize is not the version of python to use for that lol. As soon as I used 3.3 to compile, no zip error. Lesson learned.

    One less obstacle out of the way. :smile:
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    RexZhengRexZheng Posts: 201 Member
    @Neia Thanks for the link! I intended to post the link but I'm too new to forum so I cannot!
    @Triplis It's good that you've figured it out! Are you making it for your teen traits?
  • Options
    TriplisTriplis Posts: 3,048 Member
    @RexZheng Thanks for asking. It's for a couple of interactions for Child sims, actually. :smile: I submitted the two of them to MTS today, so hopefully they'll be up within 24 hours or so.

    Of course, what I now know about making interactions can be applied to other stuff too. I want to make some interactions to do with the teen traits at some point. Just a matter of priorities.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    RexZhengRexZheng Posts: 201 Member
    @Triplis Fair enough! I thought you're going to make an interaction for teens to choose how they'll react in their adolescence. I personally feel bad to add a trait for teens which will go away when tey grow up, leaving them only two traits, LOL
    Good luck with your mod!
  • Options
    TriplisTriplis Posts: 3,048 Member
    @RexZheng Heh, thanks! :smile:
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    pearlbhpearlbh Posts: 313 Member
    Before I even get to injecting with python though, could somebody tell me how to actually make an XML interaction? I really have no idea how to build anything like that from scratch, since I only have used Sims 4 Studio for editing XML files to make tuning mods.
  • Options
    TriplisTriplis Posts: 3,048 Member
    edited March 2017
    @pearlbh It's kind of hard to explain, as there's a lot of detail that can go into it and different things that can be done for different interactions. Your best bet, I think, is to make sure you can get access to certain files, first of all. XML game files in a way that you can search through relatively easily, if you haven't already (see: http://modthesims.info/t/560317).

    DATA files, in my experience, are a bit more difficult to get straightforward access to. But if you use the method outlined here to get them into a folder: http://modthesims.info/t/540033 (see the section "Setting Up") You'll at least have them somewhere, albeit maybe not in the easiest format to search. If there's an easier way to access them, it's not something I'm personally familiar with.

    The point of this is so that you can use the game files as examples to learn from (and also to copy from). It really is the best teacher, imo, for showing you how an interaction is put together and it's easiest when you can just copy/paste an existing interaction's XML file and do tweaks to make it your own.

    For example, if you want an interaction like Discuss Favorite Band, you can use Discuss Favorite Band's XML file as a base and then make a few tweaks where necessary. The main tweaks that are essential are changing the "n" and "s" values at the top of the file. Example:
    n="Pearlbh_CustomInteractionName" s="13793">
    

    Except the "s" value will be a much longer series of numbers and more random-looking. This is to ensure there aren't conflicts.

    And then the other essential tweak is changing the STBL value under (example):
    <T n="display_name">0x8ACBEBD<!--String: "Play Game"--></T>
    

    This is the interaction name that will appear in the pie-menu. The "Discuss Favorite Band" part.

    There are ways to manually create unique values/name IDs to use, so that you won't have conflicts. What I've been doing for efficiency since I'm usually not needing a huge number of values at once, is I'll create a trait in Zerbu's Mod Constructor, then delete the description and make the value what I want for an STBL value (so if I wanted my interaction to be called "Discuss Favorite Band Manager", I'd change my trait name to that in the interface and then export and save the package file. I can then open up that package file, extract the STBL files, and use them for my new interaction. I can also use the ID generated for the trait itself for the interaction's "s" value. And extract the main trait XML file and use the last part of its name as the unique ID for my interaction XML file.

    Note, however, that the first part of the XML file name is specific to traits if you generated it from Mod Constructor as a trait:
    S4_CB5FDDC7_00000000_
    
    in
    S4_CB5FDDC7_00000000_000000000000860C
    
    is for Traits.

    Then:
    S4_E882D22F_00000000_
    
    in
    S4_E882D22F_00000000_0000000000006557
    
    is for Interactions.

    etc.

    If that's at all confusing, it's because it is. Well, ok... not confusing exactly, but there's just a lot of things you can learn as you go and it's sort of impossible to sum it all up succinctly.

    If you have any questions, feel free to ask. I can honestly say though, for me, most of my questions were resolved through sheer testing and reading different files as examples. It slowly becomes more clear the more you see how the different pieces are put together. I actually find it's mostly intuitive how it all works; you just have to look at a lot of examples and fumble about in the dark a lot. Reading the TDESC's can help, too. There's a TDESC specific for interactions that has some insight in there about certain identifiers being used.

    Also, just a general note, some types of files just need a unique "n" and "s" value and they'll be recognized by the game fine, as long as they're referenced properly (traits and buffs are one of these). For Interactions, injections are needed for compatibility, while making sure your interaction shows up in the right spot. Apart from that, you really just need a unique "n" and "s" value. The reason you want injections is because there are master lists of interactions that keep them all together and make sure they show up properly (ex: Romance interactions under the Romance tab) so if your new interaction is not part of the list, it won't show up in-game. An injection allows you to add it to the list without overriding the base game XML file for that list (if you used the base game XML file as an override, you'd conflict with other people doing the same).

    Edit: Slight revision on something I said. I'm not sure the "n" value even needs to be unique. I think it may be an identifier for keeping your files named in an organized manner, more than anything (so name it in a way that will make the file easy to identify). The "s" value is the part that gets referenced when you're calling on one file from another file and it's vital that that part is unique and won't conflict with any other values.
    Mods moved from MTS, now hosted at: https://triplis.github.io
  • Options
    NeiaNeia Posts: 4,190 Member
    @pearlbh
    For more details about the ID, you can take a look at Maxis' custom content guide here : http://forums.thesims.com/en_US/discussion/779844/maxis-documentation
    It also has some examples with interactions which you may find useful.

    I personally use S4PE to generate my hash code, there's also a program available here : http://modthesims.info/download.php?t=588578

    Some additional bit of info : the "s" value is the decimal conversion of the instance key (which is hexadecimal).

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file
Return to top