Forum Announcement, Click Here to Read More From EA_Cade.

Which script(s) modify game strings based on external info?

EvviEvvi Posts: 19 Member
edited March 5 in Nominated Threads
Hiya. So I've been working on a mod that will add some additional possibilities for strings. I've been using the game's gender system as my model, as essentially I'm trying to do something similar to how it works; i.e., when a string says:

{M0.He}{F0.She} now has {2.Number} Followers in total.

...I'm having difficulty figuring out how the game "fills in the blanks", so to speak. I see some of the build_msg functions in some classes use an is_female component, and it seems like maybe inspect.py might have some stuff somewhere? But I just can't seem to find the part that actually edits the string based on an input of info to choose the "correct" option? How does the game decide he instead of she? I've checked XML files too (cuz I have no idea what I'm doing, ha) and didn't really find much, either.
Post edited by EA_Cade on

Comments

  • TURBODRIVERTURBODRIVER Posts: 68 Member
    edited January 2019
    Hey!

    When you want to display any text in the game, that text has to be sent to the client. The client is the C++ application running the game and rendering anything visual, like text.

    In the Python code, you construct a LocalizedString, that contains the string information and tokens. The "{0.String}", "{M0.his}{F0.her}" and so on are tokens. You fill these tokens by either giving it another String, an ID to a String, or some kind of instance, like a SimInfo instance.
    By including a SimInfo instance, something like "{M0.He}{F0.She}" can be replaced with the appropriate information. That information is constructed in functions called "populate_localization_token", you can find one in the "SimInfoNameData" class that sends the data you are speaking of.

    But this is where I need to tell you, what you're trying to do, is most likely impossible with the modding capabilities we have. There is a set of pre-existing LocalizedStringToken types (Token Constructors), which construct the information that is being sent to the client. There is no way you can add your own constructor, and even if you would force it, the client wouldn't recognize it and possibly just crash.
    That's pretty much it. If data has to be sent to the client, that's it, you can't go any further than that without hacking the client itself, which if you would do, it would be illegal to share it.

    If this is for your limited use, try using the "{0.String}" tokens and just have separate strings that replace these depending on the context. but this is if you mainly make mods in Python. Extending the use of this for any purpose wouldn't really work.
  • EvviEvvi Posts: 19 Member
    edited January 2019
    @TURBODRIVER Ahh, I see. That helps a ton, thank you so much for your reply!

    HUUGE MONSTER EDIT:

    Okay, so I've been thinking a little bit more about this. Obviously, I can't create a new token--got it. So I can't just do, for instance, "{0.Option1}{0.Option2}{0.Option3} when there's not a token for option three. And you mentioned overriding strings. What about something like this? (And this may be the exact kind of thing you meant with using the {0.String} method in which case sorry for my brain malfunctioning.)

    So let's assume that in normal gameplay, there is an interaction "Tell Secret" that children can do with friends. And that when they do this interaction, a message is displayed on the player's wall (like in Sims 3). Sometimes, this message says:

    "My favorite color is {#.red}{#.blue}."

    And the game already has a token for this called is_red. The game assigns this token (or doesn't assign it) based on something--RNG, user input, etc. to each sim individually. (I am basing this off of the is_female token that seems to work by having it assigned to female sims, and if they don't have this token, the message, I assume, uses {M0.He}.)

    Alright, and then let's say I decide I want more options for my sims' favorite color. So I decide to make a mod to add some. I want to add the colors purple, green, and yellow as options. Okay, so simply adding {#.green}{#.purple}{#yellow} won't work. And I can't touch the string once it's passed off to the client (well, I can't, both technically and as you've pointed out, legally). So I'm going to try and edit the message while it's being built, and before it gets passed to the client.

    My hypothetical mod has two main parts:

    1. A package file containing new interaction(s?) and any files needed to make it run (pie menu cats, etc). It also contains three new traits and a string table with three new strings.

    The new traits are favoriteColor_isGreen, favoriteColor_isPurple, and favoriteColor_isYellow.

    The strings in the string table are "My favorite color is green.", "My favorite color is purple.", and "My favorite color is yellow."

    2. A python script component.

    And it works like this:

    1. The mod uses python scripting (or scumbumbo's xml injecting for interactions which I just discovered and sounds really cool!!) to inject its new interaction into every sim object in the game. When the player clicks on any sim in the game, they can click on "Change favorite color..." which prompts the submenus of "Green", "Purple", and "Yellow".

    When a player chooses an option, the corresponding trait is assigned to the sim. So, if they click "Green," the interaction now assigns the trait favoriteColor_isGreen to the sim. The trait itself doesn't really do anything, and it is hidden so the player can't see it. If traits wouldn't work for that, maybe a buff? Anyway...

    2. Back in the mod's scripting component, there is another injection. This time, it’s injecting new code into some of the game's functions for handling tokens and strings. For messages where the is_red token comes into play, the mod will get the sim ID used by the is_red token originally. Then, it will use this ID to get the relevant sim’s traits. If the sim has one of my new hidden traits assigned to them, the mod will alter the message being built according. Something loosely structured like:

    if favoriteColor_isGreen in (#tuple of our sim's traits):
        msg = “My favorite color is green.” #or the hash key for this string or however that works.
        return msg
    
    if favoriteColor_isPurple in (#tuple):
        msg = “My favorite color is purple.”
        return msg
    
    If favoriteColor_isYellow in (#tuple):
        msg = “My favorite color is yellow.”
        return msg
    

    And then msg gets sent to the client after that.

    Does something like this seem doable? I wrote this on break at work so I may have some of my assumptions on game mechanics wrong (can’t play around with files right now) and it's a bit vague, I know. If you made it this far, thx for reading.

    TL;DR:
    Make interaction. Interaction assigns new trait to sim based on user choice.

    Script adds code to function(s) to check traits of sim whenever a specific preexisting token is used, using sim ID passed to this token(?).

    If sim has trait assigned by interaction, overwrite current msg with a new, non-tokenized message (or use {0.String}) and pass to client.

    Profit????
    Post edited by Evvi on
  • TURBODRIVERTURBODRIVER Posts: 68 Member
    The way Maxis would handle it, assuming there is a limited number of these strings, they would just write every individual string and use the one that is appropriate. The main use of tokens is to extend translators capabilities. "{M0.xyz}" means that the text will be used when the Sim "0" is an "M" (Male), so you can put anything you want as "xyz". Implementing that for a few colors isn't really worth doing.

    Once you put text into an STBL file, you can't read that text anymore, you are required to use the identifier for that text. This means that you can't swap any tokens before they get sent, because you can't even read the text anymore, you just have an identifier for it. That is unless you create a binary reader for the STBL files and manually identify what text is what (oof).
    If you're going to put text within Python scripts, this problem doesn't even exist. When strings are made in Python, you can make them in any way you like, but then they become untranslatable by others outside that want to use STBL files.

    If you're just going to swap individual words, it's better to just do what I explained at the beginning.
  • EvviEvvi Posts: 19 Member
    @TURBODRIVER Got it, thanks! I'll see what I can do.

Leave a Comment

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