Reversing Factorio's RNG (gegell.github.io)
202 points by jheitmann 5 days ago
PennRobotics 11 hours ago
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?
bombcar 7 hours ago
My favorite is the Doom random number generator, which is just a list of “random” numbers that it cycles through and if you know how to use it, you can do things like concentrate BFG attacks.
PennRobotics an hour ago
:)
the closely related not-at-all-random fizzlefade from Wolfenstein: https://fabiensanglard.net/fizzlefade/
nomel 6 hours ago
Reminds me of a "Dice" electronics kit I assembled when I was a kid. It just used some standard sequential counter ICs run at very high rate. Pressing the "roll" button would just stop the counter!
xoxxala 3 hours ago
EverQuest also used pre-generated numbers. The randomness was derived from the large number of players using the same list.
thaumasiotes an hour ago
torvin92 8 hours ago
As if Factorio wasn't addictive enough, now we can predict ore patches! My sleep schedule is already ruined.
chaz6 27 minutes ago
I read another mention of Factorio today
https://devblogs.microsoft.com/cppblog/bringing-correctly-ro...
It mentions how they had to use a custom math library to differences in results on different platforms causing multiplayer sync issues.
harlan_pdx 8 hours ago
Factorio players reverse-engineering an RNG? Peak Factorio. The dedication to optimize everything, even randomness, is truly something.
jatins 2 hours ago
What’s the goal here with posting AI comments on every post? Does it help you get a job, do you sell this account?
redbear2026 25 minutes ago
It's probably just a test for their bot. We will see them everywhere.
Aardwolf 11 hours ago
> 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/...
cmovq 7 hours ago
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;mitxela 3 hours ago
Boost predates C++11
pema99 4 days ago
Super cool
jvanderbot 13 hours ago
Yeah, no notes. It's remarkable.
TL;DR: Wired up an in-game predictor of RNG output and used it to only craft legendary items when RNG would line up to roll legendary.
From base to legendary at a suprisingly high rate. Look very closely at the video at the top of the post - what I was seeing didn't sink in until I had finished the article. Amazing.
hbroom 9 hours ago
Dedication like this is awesome. Finally, we can optimize those starting resource patches without endless map restarts!
throooooo 5 hours ago
If you're playing/hosting locally you get a preview of the world and can reroll for a different seed if you'd like.
3eb7988a1663 8 hours ago
At the conclusion, he said he spent two years on this! That's a thesis.
strstr 12 hours ago
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.
3eb7988a1663 8 hours ago
I am failing to find the article, but some early online poker systems used the server time as the seed coupled with a weak PRNG. With the information of the hole cards + community cards, after a few hands, could quickly determine exactly what seed was being used and perfectly predict everyone's cards.
e28eta 27 minutes ago
I don't think this was the original source, but this paper matches your (& my) recollection: https://gwern.net/doc/cs/cryptography/2006-arkin.pdf
google surfaces a couple of HN posts, but the source (cigital.com) seems to be a dead domain at this point:
https://news.ycombinator.com/item?id=288138
https://news.ycombinator.com/item?id=9914607
It's a bad shuffle implementation + using time of day as seed (reducing search space). Using the player's 2 cards and the 3 flop cards, it finds the RNG seed in real time, and then future hands (on the same server) are solved in "under one second!"
rogueaine 12 hours ago
That’s not at all what the article proposed. The author constructed and transpose to the linear shift register coefficients and built a circuit network based on this to predict the next state (in the sandbox) and direct recipes.
strstr 11 hours ago
From the article:
> Sampling the current RNG through observations,
> Computing the current internal RNG state,
> Predicting the future internal states,
> Calculating corresponding quality levels for each future call, and finally
> Making use of the predicted levels with some adapters.
The entropy->seeds (internal RNG state) step took more math of course. Frankly, I wouldn’t be surprised if they could have extracted the seeds without the math with a bit of RE and memory inspection.
The version I did wasn’t predicting quality of course, it was predicting tie breakers
Founderarcstone 10 hours ago
Really cool example of how something that looks random can become predictable once you understand the underlying system.
jason_s 9 hours ago
neat! more info on LFSRs, fyi: https://www.embeddedrelated.com/showarticle/1309.php
vlyan 11 hours ago
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.
myhf 11 hours ago
Impressive work!
lowbloodsugar 12 hours ago
Madman. Brilliant.