# A good genetic system?

I was trying to come up with a genetic system for my game. However, after doing the math I found the system I had in mind won't really work.

Characters have 5 stats that can range from 0 to 12. What I was planning on doing was averaging each stat, and then rolling two numbers for each. The one that would be inherited for each stat would be the one closest to the average.

However, I found the bias isn't that great. For any number between 0 and 12, there's a 23/144 chance, or about a 15% chance of it occurring. This means say that if the two parents had a 12 in a score, there was an 85% chance about that the offspring's score would be lower than 12. Clearly, that isn't going to work. If both parents have the highest number, the odds should be weighed far more towards them.

I could increase the number of rolls, but adding more rolls decreases the odds of the farthest result too much.

If it matters, I'm trying to recreate the genetic system of The Sims 2. I have no idea how it generated its results, other than that all possibilities would possible but somehow weighted based on the parents. The totals of all 5 stats were also always between 25 and 35. I know how that was accomplished, but it doesn't help me with the first part.

I did think of an alternate method, but I don't like it much either. I was thinking of taking the averages of the parents, and then incrementing every stat at random x times, then doing it again x times but this time decrementing. This however doesn't work too well either. Either it would heavily weigh scores towards the middle, or it would make it nigh impossible for a child to match its parent. If I added too many increments/decrements, it would probably result in the final stats bearing no resemblence to the parents. I may as well just be starting with 0, and incrementing stats at random until a total of 30 is reached.

What would be a good system for my game?

update: Thinking about the latter system, I've come to realize its inherently flawed. The problem comes from the fact that the program has to either increment or decrement first. I could have it alternate back and forth, but it may not help much. The issue arises in the fact that no value can be raised above 12. I solved this by having the problem just skip over stats that are 12 when its incrementing, and skipping over values of 0 when its decrementing. This means that if a stat is 0, it has a 0% chance of being incremented, and the other four have a 25% chance of being incremented. When it switches to decrementing, all have a 20% chance of being decremented (assuming none of them are zero of course). Thus the 12 stat is more likely to be decremented than incremented, while the remaining stats are more likely to incremented instead. Stats of 0 would suffer the same problem, but in reverse. This means that this system actually evens out the numbers, and makes it nigh impossible to have a stat of 12 or 0. In order for that to happen, the program would have to in its six tries not chose these stats all six times. That's less than 1/5000 chance about. So clearly this system sucks. Thus I need to pick something more neutral.

There does need to be a randomization element to it. If I just had all the offspring's stats be the average of its parents, then all siblings would have the exact same stats. There has to be some way for them to vary.

My approach would be to take three numbers per stat, mother, father and a random roll between 0 and 12, and then take the average. That will mean that the score will usually be somewhere between mother and father. But for exceptionally good or bad parents, there will be some regression to the mean, and for cases where both parents are very similar, there is a good chance that the child will be slightly better or worse than them. Extremely good or extremely bad values would be quite rare in this system, but possible.

This system could be refined further by changing the respective weights of the parents genes and the random factor.

However, this system doesn't have any guarantees about the sum of the stats. In order to then get a total sum between 25 and 35, I would then "normalize" the stats. I would do that by:

1. calculating their sum
2. divide that sum by the desired sum of 30 to get the factor of how much that sum is above or below the desired sum.
3. apply that factor by dividing each individual stat by it
4. round the results to the nearest integer.

Example:

A: 5
B: 7
C: 10
D: 5
E: 9

Sum: 36


This character is 36 / 30 = 1.2 times as good as they should be. So we divide all stats by 1.2 and then round them:

A: 5   / 1.2  = 4.166 ~= 4
B: 7   / 1.2  = 5.833 ~= 6
C: 10  / 1.2  = 8.333 ~= 8
D: 5   / 1.2  = 4.166 ~= 4
E: 9   / 1.2  = 7.5   ~= 8

Sum: 30


Note that if you have 5 values that sum up to 30, and you round each one up or down to the nearest integer, then you always end up somewhere between 25 and 35.

• That's actually an interesting suggestion. Though I don't see how it would be possible to have all values come up. If the parents scores were both 0, and the roll was a 12, the average would be a 4. Thus, there would be no way to get a 12, or anything above 4. Even if both parents had a 6 (or their scores averaged out to 6), the highest the offspring could get is 8. So that's a range of 4 to 8, not 0 to 12. I was thinking that honestly maybe its just futile, and I need to accept that the offspring will never be that far off from the average of their parents.
– user175083
Nov 7, 2023 at 16:44
• The last method I mentioned in the post btw generates similar results. Assuming the average of the parents is 6, the highest the offspring seems to get is a 10, on freak occasions an 11, though both are clearly the exception rather than the norm (only about 1/10 of the values I generate seem to ever contain a 10 or 11, have yet to see one get a 12). Amusingly though, I rarely get a 12 even if the starting average is 12. Probably because there's 6 chances of it getting decremented, and also the decrements all happen after the increments. Perhaps I should fix that somehow.
– user175083
Nov 7, 2023 at 16:46
• If you want more chance of outliers, you could adapt the above system to have two rolls - one roll for the 0-12 as taken above, and some other (real number) distribution from 0-1 to indicate what weight that roll has, so 0 would mean a straight average of the parents, 1/3 would weight all three rolls equally, 1 is using only the 0-12 roll. Tweak the 0-1 distribution to get the outcomes you want. Nov 7, 2023 at 19:45
• That's actually kinda how the system works in the sims 2 apparently. Strangely, it apparently never takes both parents into account. It only factors in one, or sometimes neither, in which case the values the offspring get are completely up to rng. Come to think of it, maybe that's how all possible results can come up, despite often being biased towards the parent's values. 2/3 times it bases the numbers on one of the parents, the rest not. Its not perfect though; it suffers a glitch that causes most children to have 0 nice points. Seriously.
– user175083
Nov 8, 2023 at 3:22

You could consider taking some inspiration from biology, emulating genes by making the visible stat just the "phenotype" expressed by an underlying "genotype" in the data used under the hood.

So for instance, instead of storing a stat as one number 0-12, maybe it's four separate "genes" each holding a value 0-3 (convenient to store in a "nibble" of 4 bits — half a byte), and the visible stat is the sum of these four genes.

So a sim with a 12 stat definitely has all 3 genes, but a sim with a 6 could have genotypes 0 0 3 3 or 1 1 2 2 or 0 1 2 3 etc.

When creating offspring, emulate crossover and dominance interactions between genes by randomly selecting two genes from each parent to make the four genetic components of the child's stat. Then you can add mutation by having a small chance that each gene mutates to a random value.

You can preferentially mutate-to-decrease when at the high end of the 25-35 total band, and mutate-to-increase at the low end, but without preferentially targeting 0s or 3s specifically. So an individual who's been tweaked to fit the target range can still have some extreme genes in the mix; they don't all gravitate to the average.

(Before any bio geeks storm the comments: yes, this is not how mitosis/mutation/etc. actually works. If you wanted, you could have each parent contain two copies of every gene, then pass on one of those two copies to the child, then have some rule for which copy/copies affect the stat... but I think that's more complex than you need to go for this feature, and the simplified approximation "loosely inspired" by biology gives fewer surprising results where a child gets all the parents' recessive genes and has drastically different stats, looking like a glitch)

With this approach, parents with high stats due to having a lot of 3s will tend to have children with a lot of 3s and similarly high stats, but not always, and likewise for low stats. The chance mutation still gives some chance of children having very different stats — any value could arise by mutation, but values not too different from the parents' are more likely — and you can control how often this happens by tuning the mutation rate.

• Yeah, I was thinking of emulating real-world genetics into the game. The sims 2 does this for physical appearance, it even goes so far as to do the dominant/recessive gene thing, and have genes not express themselves, allowing traits to skip generations (assuming the whole thing doesn't bug out and just start making ever sim born in-game a clone). I thought however that such complexities were unnecessary. I could make this game literally like dwarf fortress and try to emulate reality to the tiniest detail, but that would be a lot of work and I don't really see it adding much.
– user175083
Nov 8, 2023 at 3:15
• If I was to emulate the real world, I would be giving my sims an actual appearance (I may do that anyway though, since apparently one of the handicaps for the sims 2 legacy challenge requires all spouses to have a different hair and skin color). I would also emulate actual nutrition, which would justify having multiple meals like the real game does. I would even have the game actually have a map and have characters moving around in it. However, I never saw such minutia really offering anything in dwarf fortress, so why would I bother with stuff like this in my game?
– user175083
Nov 8, 2023 at 3:18
• On that note, if I was going to go the dwarf fortress route, then why not just play dwarf fortress? Honestly, I never really cared for that game. What's the fun in building this epic base only to see it get leveled over and over again by things that are stupid OP? Of course, part of my dislike of the game is the AI. Yeah, I know not much can be done about that, but you could AT LEAST MAKE IT POSSIBLE TO TELL YOUR DWARVES TO STUFF THEIR STUPID FACES INSTEAD OF STARVING TO DEATH WITH A MOUNTAIN OF FOOD SITTING IN STORAGE.
– user175083
Nov 8, 2023 at 4:11
• You may want to edit your question to include more specific criteria about what traits a "good" system should have and what level of complexity is too much, to help focus potential answers on the types of solutions you're looking for, so users don't have to guess at your requirements. Nov 8, 2023 at 10:32
• Yeah, I was thinking that. But what would constitute a 'good' system? I sorta already explained it; a system that creates clear bias towards the stats of the parents, while leaving all possibilities possible. Essentially, if both parents have a 12 in a stat, there should be a bias towards 12 for all offspring, but even a 0 shouldn't be impossible. Of course, even if all results are possible, having a .001% chance of a 0 occurring would probably still make it rare. There just seems to be no way to make 12 the most likely without making 0 impossible.
– user175083
Nov 9, 2023 at 2:45

To "see the parents" in their young ones you could implement following system: each stat has a 33.3% chance to be inherited from the father, 33.3% chance to be inherited from the mother and 33.4% chance to be a random values between 0 and 12. If the value is inherited from a parent you could make it a range of +-1 around that to not have the exact values of the parent.
At the end you can randomly increase/decrease values until you hit your desired total, but I would suggest to have a much greater chance to change the not-inherited values in this step as to not destroy the feeling of inheritance.
To make it even safer you could make a rule that always at least one stat is inherited from each parent, so you always have at least one stat where you can say: "I inherited that from my father/mother"