Quick Reply
Search this Thread
Test Subject
Original Poster
#1 Old 27th Dec 2025 at 9:29 PM
Default Pet Genetics Mod Questions/Feasability -- specifically horses
Hello!
I've been into sims modding on and off for a few years, but not to a deep extent. I made a jacket recolor once, and a custom clothing object with a totally useless mesh. I've made flat makeup CC. I've also tinkered with making traits and custom aspirations.
I have basic python and computer knowledge. I've taken multiple computer science courses for C++ and Python, but its not my strong suite. I was able to decompile the game and recompile some edits to it in a mod that didn't torch my game, but it didn't seem to work the way I wanted it to(being functionally useless), because of reasons that worry me.

My goal: to make a horse genetics mod that properly mixes the pelts of horse parents in a horse baby, to vary the baby's appearance. Note i am not trying to establish realistic horse genetics, simply some interesting gene mixing.

Currently, the horse coat pattern is copied from either parent A or parent B, which includes the base coat and the custom paint. Each base coat has 3-5 swatches that can be customized, and the paint is overlaid on the base coat. The base coat can be changed independently from the paint in CAS.

The most basic idea(s) for implementation is as follows.
- Foal gets the base coat type from parent A, and the swatch colors from parent B.
- Foal can inherit a copy of either parent but is more likely to be a mix.

That's it. But I've also thought of some alternatives or additional functions.
- White markings that work as either stencils or accessories, that are applied to the custom paint job or the horse upon offspring generation. They are inherited from the parent or randomized.
- Custom paint can be inherited separately from the base coat. So, gene markers would be the base coat type(black vs red, for example), the swatch colors(white vs brown spots), and custom paint(none vs. big blue splotch on the side). So from that, you could get a black horse with white spots and no paint, or a red horse with white spots and a blue splotch, or a black horse with brown spots and a blue splotch.

My first attempt was S4S and looking at the tuning files. I found there was a custom paint inheritance value set to 0. I was like, whaaat? It's that easy? NO! The developers thought about implementing it, but instead, custom paint is flattened to the base coat when they roll for this stuff. At least, thats what it seemed like when I tested for it. Which sucks, because it looked so easy to fix at first. I also found that horse breeding references the cats and dogs pelt system, which I figured.

When I decompiled the scripts, I was looking for where a baby's appearance is actually generated. I looked in pregnancy_tracker, which seemed the most promising. I found create_offspring_data and sim_info.apply_genetics(parent_a, parent_b, seed=(offspring_data.genetics)), but when i looked at sim_info, it was blank--im assuming it didn't decompile. I wish I knew what happened at apply_genetics to see if I can make a horse-specific function that frankensteins CAS parts.

I tried fixing the seed so it was the same every time, but I think the seed doesn't actually determine the baby's coat, but rather the randomization of physical features excluding the pelt.

In short, I'd like to know if anyone has found a way to successfully manipulate sim genetics, or knows where I can go to manipulate paintjobs. Or if its even possible, at all. Or can point me towards any open-source mods i can look at the figure out how a mod might roll together all this stuff. It doesn't seem like anyone cares about pet genetics to make a mod, but I know a few people have expressed interest in seeing or making one.
Test Subject
Original Poster
#2 Old 5th Jan 2026 at 1:57 PM
some new findings
Okay, a few updates. I don't know what I was on when I wrote this. nothing i attempted worked. But things change, thankfully. over the course of 12 hours once I got mad enough at horse ranch to remember i wanted to do this.

** DISCLAIMER: this is my very first script mod... I wasn't even good at creating custom CC, either. (hating 3D modelling...) if i don't use the right words for techy stuff, or I do something in a way that can be done much better and simpler, please correct me!

A couple things:
1. overriding any sort of genetics coding, I figure, may not be wise. i want this to be as safe a script mod as possible for saves. so i've come up with the novel idea of just letting the foal spawn as normal, THEN applying my coat roll immediately after. once I get there.
--> This means I can hook a function right after the foal spawns, which I've deduced is... erm... somewhere in the interactions.utils.pregnancy_interactions module under nonbaby_offspring, I believe. I figure this part is the easy part so I've shuffled it aside for a short period.

2. PYCHARM IS THE GOAT. I was using VS and some random decompiler, but stumbled across this effervescent tutorial. I'm very much awful and I never read anything if I can help it, so this very basic tutorial was a huge revelation for me. My decompiler worked like junk and VS was just... not it for this purpose. But pycharm with the starter project is so incredibly easy. sigh of relief!

3. the secret sauce for a funky horse genetics mod at this stage is not, in fact, apply_genetics. i'm sure that will be important later, but actually, the secret sauce is in extracting, parsing, and modifying the pelt layer data. I can extract the pelt layer data from mom and dad and mash them together as I see fit, because:
  • ts4 horse coat system uses protobuf data, storing PeltLayerData objects under PeltLayerDataList parents.
  • The layer data is stored in two ways. Object format(Protobuf) and bytes format(binary). You want to parse from the object format(protobuf, aka PeltLayerDataList() class) when you want to get modular with the layer details. The bytes format you use to save and store the pelt list, and you'll use it to save to and pull from sim_info. You need to PARSE sim_info.pelt_layers into a usable string list of Pelt Layers to work with them. You need to SERIALIZE a list of Pelt Layers into binary to store it in sim_info.
  • Each PeltLayerData (the individual pelt layer object) has a layer_ID(for the pattern/Type ID) and a color. Both can be looked at in S4S under Game Files -> Pelt Preset -> look at the XML.
  • While I'm not sure, layer maximum for PeltLayerDataLists is probably forever. Either way, you get at least 5-6, plus a paint layer. Layer 0 is the base coat, and layers 1+ are markings and patterns.
So, functionally, you can take parent A and parent B pelt lists, navigate the string lists as you see fit, compute a new string list of pattern IDs and colors for the foal, and apply it directly after delivery.

Here's some code snippets:

Parsing Protobuf
Code:
from protocolbuffers.Outfits_pb2 import PeltLayerDataList
pelt_proto = PeltLayerDataList()
pelt_proto.ParseFromString(sim_info.pelt_layers)


Creating A PeltLayerDataList Object
Code:
pelt_proto = PeltLayerDataList()
layer = pelt_proto.layers.add() # Dynamic attribute (ignore IDE warnings?)
layer.layer_id = 0x512C4 layer.color = 0xFF212121


Serializing to Binary
Code:
sim_info.pelt_layers = pelt_proto.SerializeToString()


I hope I'm not jumping the shark here by assuming there's a lot that can be done within this framework. You could take an entire parent coat(like the game does), mix and match layers and colors, blend colors(thru averaging or drifting rgb values), and add random mutations(new patterns/colors). And because nothing crazy is being manipulated, it should transfer just fine in and out of a save(?) and nothing untoward is getting touched, because the coat reroll can happen right after birth.

This post is getting kinda long I have some underwhelming screenshots of what I was able to accomplish in-game. I'm very nervous about contributing to this forum, and I'm worried about this all being common knowledge to everyone else... hopefully this niche part of the game no one cares about is interesting to other modders here too!
Test Subject
Original Poster
#3 Old 5th Jan 2026 at 2:10 PM
Progress Pics


It aint much, but it's honest work. I used a UI cheat script to pull all the horses of the active household and apply a coat changer function to them. Of course, this function will be triggered by a birth event in the future.

For the coat change, I ended up encoding a pelt preset resource i ripped using S4S into a new pelt object, which I then applied to the existing sim's pelt. Honestly, I feel like it would've been a lot easier to just use the dang file key but I didn't know how, and I'm going on a 24 hour sims bender and don't have the brain power to learn another new thing. But if anyone has insight, please let me know.
Test Subject
Original Poster
#4 Old 6th Jan 2026 at 7:15 PM Last edited by zoisims : 7th Jan 2026 at 1:43 AM.
success in applying a coat to offspring
Freakinggggg awesome sauce, I managed to hook the foal coat change into the birth event. Mom having triplets was completely unplanned, but excellent for debugging.

From here, it's just tweaking my horse_rollcoat function.

Things of note:
I used TURBODRIVER's injector, which can be found here . My implementation code frame was this:

Code:
# INJECTOR FRAMEWORK
from TURBODRIVER_Injector import inject (injector code is in TURBODRIVER_Injector.py)
import sims4.log
import sims4.commands
import services
from sims.pregnancy.pregnancy_tracker import PregnancyTracker

@inject(PregnancyTracker, 'create_sim_info')
def _myfunction(original, _, *args, **kwargs):
    sim_info = original(_, *args, **kwargs)

    try:
        # if birth succeeded...

    except Exception as e:
        sims4.log.exception("Injection", "pregnancy_tracker.create_sim_info injection for EGO failed to run.", exc=e)

    return sim_info (or result of original function)


I'm not sure if I can use xml injector for this, rather than TD's injector. TD's injector works, but its because i included it as a script in the compiled file, and I'd like to not have to do that.

I don't fully understand the whole of how this works yet. My understanding is that the injector tells the code that, when create_sim_info in PregnancyTracker is called, that hey, check this out instead. And then sends over myfunction, which has the same structure as the function its replacing. First, it executes the original function. Then, it tries my own code, logging an error if something goes awry.

However, what I suspect is that this code doesn't take into account twins or triplets, thus making identical twins impossible. Regardless, I'd like to handle identical offspring differently anyway. Realistically, white markings are genetic but their actual expression is random. So I'd like to make twins with the same base coat but different white markings, along with the chance of an identical twin.

What I think I know is that the game handles offspring genetics by a randomized seed in offspring_data. Same seed, same baby, every time. I think.

For now, I am going to go for the vanilla mechanic of monozygotic siblings having the same coat, and tweak their expression later.

** NOTE FOR SELF: I'll want to implement a personal layer max, as well as a reasonable pattern removal protocol, so I don't accidentally bloat generations of pelt layer lists with dozens of patterns from the add/replace mechanic.

What's also been useful for me is using the cheat console to debug where stuff failed.
Code:
# SEND MESSAGE TO CHEAT CONSOLE
def cheat_notif():
    client = services.client_manager().get_first_client()
    if client:
        # client.id is the connection ID!
        sims4.commands.CheatOutput(client.id)("Message")


Second note: in the future, along with this mod I'd like to make a horse game function overhaul, as well. For one, I'd like to handle horses so that they do not take up slots in the active household. The idea being, you could run a 10+ horse farm(if your PC could handle it) but only have your favorite horse(s) in your household.
LittleMsSam does this here. But, its not quite applicable to me, because pets dont give birth on your lot. For a breeding farm, that sux, but I'm very sure there's a good reason LMS did it that way.

I've brainstormed some alternate options, such as tracking horses in a different household and telling them to come to your lot. Then, when horses are competing or pregnant, they are added to your household, and when these actions are completed, they are removed. With MCCC's max household limit coming in handy. Alternatively, and I have no idea if this would work yet and wont for a while because I dont have For Rent, I believe For Rent allows multiple households to live on the same lot. Making a household of just horses could be the move. But, I'd like to minimize pack requirements. If I did, I'd have a base-r game version available first, with additional functionality for For Rent and BH (for making the household sim in the horse household an employee of your stable business...)

But of course, that's a future endeavor.

NOW:
- verify gathered info from parent horses
- design simple horse_rollcoat logic to swap colors
- implement monozygotic offspring chance

LATER:
- mix patterns
- prevent layer bloat somehow
Test Subject
Original Poster
#5 Old 7th Jan 2026 at 1:43 AM
so apparently i have to include the injector script in my file, which makes sense. beginner roadblock to have. but, i did change to Scumbobo's after all.


very excitingly, i have now managed to hook onto the birth event, get both parents info and validate it, pass that info along, compute a new coat and send it back down, and assign it to a foal. I haven't tested any genetics mixing, as the coat i compute at the very tippy top is currently a static red base color, as you can see. but since both parents data is valid(i think), i can start the process of actually developing the genetics.

in the previous test, i was just assigning a pelt when the foal was born. this test was about passing along parent pelts.
Test Subject
Original Poster
#6 Old 7th Jan 2026 at 9:35 PM
OK, so...
I don't have a picture, because I was epically displeased. But, I did manage to pass along parent genetics and randomly pick from those layers.

However... the offspring was so boring! I don't know what happened. Maybe the base color got randomly picked for all of them above their other colors. But, I do know parent genetics are working and are being passed along. I was also right, twins aren't twins...

I've had to delve sooner than I thought into actual genetics. I've gone through and sorted all the pelts by their genetic markers. I'm thinking I'll identify the parent genetics before i roll the coat, rather than try to pass persistent genetic data somewhere. This will require... a LOT of testing... and tuning...
Back to top