Monday, November 08, 2010

Sims 3, Late Night, and Transfiguration of Metals

Ok, I know, this is a bit off my usual beaten path, but I don't care. I've played the Sims since 2000, and I freely admit to wasting a lot of time on it.

In the Sims 3, since World Adventures, there has been a pair of objects (the Carter XL Display Cases) that can be filled up with objects and "irreversibly transfiguricated" (more commonly known as transfigurated) into other objects. What object one gets as a result of a transfiguration depends on what objects one puts into it, along with some random factors. Various people who know how to look at the scripting language that the Sims uses internally have done so and posted descriptions of the relevant algorithms. I spent quite some time exploring this for the special case of transfigurating metals, and have a simulator now that can predict the result of transfiguration for any particular combination of metals for a game with the World Adventures and Ambitions expansion packs installed (WA+A). I could do the same for just WA if I wanted to set up an install that had just WA loaded, but I've been too lazy to do this yet.

Part of the algorithm for metals works by XORing together the internal OIDs of the metals involved, and then using that as a index into the list of metals (modulo the number of metals) to generate a random metal. The index is then pushed through a PRNG (pseudorandom number generator), and repeated until metals totaling more than a certain value are created. This worked fine and good in prior versions, with the longest string being about 8 or 9 metals in WA+A, where there were 14 metals. However, while in WA alone (which had 13 metals) it was possible (with some care) to create any metal using this process, in WA+A five of the metals (silver, palladium, copper, titanium, and mercury) could not be produced at all, and two more (supernovium and woohooium) were very hard to produce. This is, no doubt, because the low bit of the XOR result is always 0 (because all the OIDs have a low byte of 0), and the modulus 14 of an even number is always even, and so that effectively excluded half of the metals (the ones with odd indices in the metals table) from being the "first result". Add to that a relatively "inaggressive" PRNG and you get a relatively sparse result set, which is what I had noticed with WA+A.

Late Night (LN) added two more metals; as a result, in WA+A+LN, there are 16 metals. Those of you with some experience with generating hash codes will immediately understand where this all goes belgium, but I'll explain it for the rest of you. A modulus of 16 results in only 4 bits of the source value contributing to the resulting index. And all of the OIDs in use have a 0 in the low byte (for whatever reason). As a result, the random value generated by this process is always 0, which corresponds to iron, the cheapest of the metals. To make matters worse, the PRNG EA uses apparently isn't that "random": it appears to map all values that have a low nibble of 0 to values that also have a low nibble of 0. As a result, every metal after the first is also iron. So, instead of getting a "random" (but predictable with much effort) result of various metals (which makes the process both interesting and potentially useful within the context of game play), the result of every transmogrification in Sims 3 with WA+A+LN is a huge stack of iron bars, which is neither interesting nor valuable within the context of game play; furthermore, the resulting stacks are often so large (in some cases, one hundred or more, although the game doesn't show it) that it corrupts the player's inventory, rendering that game effectively unplayable and forcing a retreat to the last save point. Here's hoping you had one.

This wouldn't have shown up in testing with just the base game plus LN, or with A+LN, because in those games there is no transmogrifier (it's a WA expansion item), nor in testing with just WA+LN because in that game there are 15 metals and with 15 metals the randomness of the distribution will be nearly as good as it was in WA alone (with 13), possibly even better.

I had a lot of fun figuring out the matrix for WA+A, and was really looking forward to doing in in WA+A+LN. A shame it had to be completely broken instead. We can only hope that EA will fix this in a forthcoming patch; however, any patch is going to mean a new algorithm (or at least a different PRNG), which means all the work I (and others) did for the preceding algorithm will probably be wasted.