Posted on January 18, 2021

Source code

Super Meat Boy Forever is a 2020 2D autorunner that relies heavily on random level generation. When the game first came out, the speedrunning community was in need for a better understanding of the game internals, and for tools to ease the speedrunning activity. This project is the result of my reverse engineering work on the game’s level generation logic and save file format. It contains in particular a script that generates information about a save file knowing only its seed (an 8-digit hexadecimal number that fully determines the pseudo-random generation of the game1). It also includes a script that generates save files at various stages of completion, with a user’s chosen seed.

Most of the work behind this project went into reversing the game’s executable, which is compiled from C++ code. After having found and analyzed the random number generator, I had to track every single call to it during the level generation and reconstruct the logic around those calls. Another important challenge, which was initially my main motivation, is to determine the best2 of the 2^32 possible seeds. This requires to generate every single seed, so efficient code was necessary for this task.

Comment on the implementation

The scripts that perform save file analysis and manipulation are written in Python. There is also a C++ program that loops through all of the seeds, for which I did some memory allocation hunting in order to make it fast enough.


  1. More precisely, every time the player starts a new game, a seed is automatically generated. The player may override the generated seed and enter one they chose. The seed is used to generate the composition of each chapter and each level. Therefore, if one is able to determine the generation algorithm, one may know in advance where everything will be in the game.↩︎

  2. As a speedrunner, I mean the seed that allows to complete the game in the shortest amount of time. This means that in addition to reverse engineering the game internals, I had to time the fastest way to complete each of the ~1400 chunks that may compose the levels.↩︎