logoalt Hacker News

Reversing Factorio's RNG

152 pointsby jheitmannlast Saturday at 5:02 PM20 commentsview on HN

Comments

PennRoboticsyesterday at 9:51 PM

Stardew Valley has two random number seeds. One is the normal character seed. The other, your multiplayer ID, can be determined by analyzing the save file.

Except! On the Switch, you can't easily access the save file AND the random number generator is different than on PC. There is a seed cracker that looks at your traveling cart listing and calculates the character seed. Maybe because it's less important and harder to observe, I haven't found any tool to crack the other seed and don't have time to attempt writing it myself.

By inspecting cracked geode contents, you should be able to isolate your multiplayer ID and then predict random events on Nintendo just as PC players have done for the last decade with access to the save file.

The C# code for the game is online and the Switch RNG is known, so you never have to work in the dark. It's three steps: ensure your Switch RNG implementation works by testing against the normal seed, ensure your geode RNG implementation works by testing against the PC RNG, and then apply the Switch RNG to the geode function enough times that only one seed could create your observed sequence.

-----

Two semi-related open questions: Are you able to solve as quickly while starting at ANY geode as you'd be solving from the first geode? Does the RNG eventually repeat, so it actually doesn't matter what your multiplayer ID is as long as you observe a unique sequence, since there will only be one continuation of that sequence?

show 1 reply
cmovqtoday at 1:43 AM

One of the reasons I dislike boost is in the first code sample. What’s the point of implementing what boils down to a 10 line function (as shown in the decompiled output) like this

    typedef xor_combine_engine<
  xor_combine_engine<
    linear_feedback_shift_engine<uint32_t, 32, 31, 13, 12>, 0,
    linear_feedback_shift_engine<uint32_t, 32, 29, 2, 4>, 0>, 0,
  linear_feedback_shift_engine<uint32_t, 32, 28, 3, 17>, 0> taus88;
Aardwolfyesterday at 10:17 PM

> We chose taus88 mainly because it is the fastest from boost’s generators.

That's an RNG from 1996. It seems neither recent C++ standards, nor boost, know anything about the modern PRNGs that are much faster yet better at passing test suites

EDIT: Ok the above quote was from 2014, and boost seems to know some now! https://www.boost.org/doc/libs/latest/doc/html/boost_random/...

torvin92today at 12:32 AM

As if Factorio wasn't addictive enough, now we can predict ore patches! My sleep schedule is already ruined.

hbroomtoday at 12:04 AM

Dedication like this is awesome. Finally, we can optimize those starting resource patches without endless map restarts!

show 1 reply
harlan_pdxtoday at 1:22 AM

Factorio players reverse-engineering an RNG? Peak Factorio. The dedication to optimize everything, even randomness, is truly something.

Founderarcstoneyesterday at 10:56 PM

Really cool example of how something that looks random can become predictable once you understand the underlying system.

strstryesterday at 8:54 PM

I did an easier version of this in my college intro class. There was a class competition that involved rock paper scissors as a subcomponent, and ties were broken with randomness. You could rig Java’s prng so you would win all ties.

The prng was seeded with usec time at first call. I called the rng a bunch of times to harvest entropy, and scanned the plausible usec times to find the seed. Then I primed the prng so I would win ties.

Frankly, I assume I implemented this wrong, but the theory was there lol.

show 2 replies
vlyanyesterday at 10:09 PM

by far the blackest magic I ever saw for that game.

I'm an upper intermediate at Factorio, resorting to someone else's blueprints only for belt balancers and rail intersections, and I can't even begin to figure out how it's done.

pema99last Saturday at 11:13 PM

Super cool

show 1 reply
myhfyesterday at 9:40 PM

Impressive work!

lowbloodsugaryesterday at 8:31 PM

Madman. Brilliant.