Extensive introduction into 3 advanced abstract RNG-manipulation methodologies for various games
3 years ago
Bavaria, Germany

Okay here is an introduction into 3 genuinely really sophisticated general types of strategies (likely involving RAM search & watch and potentially disassembling/understanding the code related to RNG to find and figure out the behavior of RNG and how its values are mapped to outcomes at a critical event, figuring out a sufficient amount of bufferable movement branches up to such event from a suitable starting place and how to use them to maximize the probability of a favorable outcome at the event), so bear with me.

A different way to summarize what follows: A few potentially up to significantly probability of favorable pseudo-random outcomes increasing general methodologies for games with frame-based or CPU-cycle-based RNG, provided the RNG's sequence of future RNG values is fixed, or in some situations possibly even also input-based RNG (for when the ''RNG's path'' is directly input-dependent but there being restrictions to when player input timing affects it or the number of frame perfect required inputs being low).

Be aware that I'm not forcing anyone to read all this, so just see it as an invitational write-up (which also took its due time and effort) to the extent to which there may be interest in it by others. I'm mainly motivating myself to write down and share/spread these 3 general luck manipulation approaches further because I expect (but also hope) that at least some of these can still at least in principle find many applications across various games, where such applications may not have been discovered yet. While I'll be referring to ''movement'' being what is buffered, this approach is about any buffered activity via inputs and is not limited to games in which some character is moved around.

Explanation of the general problem type & setting: For some kinds of goals in games (like speedrunning or completing specific challenges with additional constraints to the gameplay) sometimes one may run into situations where a point in time during the gameplay comes up that has an event for which the outcome significantly depends on the value of a pseudo-random number (produced by a deterministic random number generator) to get a favorable outcome or not, and where it would be useful to have some kind of setup or approach for it that can increase the chances of getting the desired outcome. And in the following I'll try to explain a few methods that can be used for such purposes, but the applicability of these methods expectedly are very limited.

Note that throughout this write-up, whenever I'm using the term ''bufferable'' (or ''buffered''), I'm using a weaker (although still good enough) notion of it than the meaning that is commonly understood with the term, namely as ''input-wise bufferable'' where upon some initial frame in which one or more certain buttons are pressed, the configuration of which buttons are pressed and which aren't pressed on the input device stays constant until after passing the time of the event for which the effect of the input buffer was intended. In particular, by ''bufferable'' I'm referring to ''game-state-dynamic-preservation-wise bufferable'', or in better words: A given set of movements (or sequences of actions), that only deviate from each other in the timing of pressing or releasing inputs that occur in any frame and contain reasonably wide frame windows for each button press or release, represents and is in here referred to as 1 bufferable movement in this sense, if all cases start out with the same part of the whole game-state that ends up being relevant to an associated RNG-manipulation and if there exists at least 1 frame during the whole movement process upon which all in the movement set entailed movements coincide in the part of the whole game-state that from there on ends up being relevant to an associated RNG-manipulation, and correspond to the same input-wise buffered movement (i.e. coincidence in the commonly understood sense). This means that there can be intermediate deviations between such bufferable movements e.g. for when a button is pressed or released, as long as these differences in the input sequences don't lead to a specific RNG-manipulation failing when there is at least 1 case among them where it works. Investigating where the limits are for individual button press or release timings for such bufferable movement (in the weaker, but less restrictive sense) can be done using TAS tools (especially in case there may be subtle otherwise unnoticed differences such as lag differences leading to deviations, expectedly especially rather on consoles than emulators, in some cases due to the Sound Processing Unit), and concrete examples of such bufferable movement can be found in the bullet point list beneath.

Because of the nature of bufferable movements for RNG-manipulations these kind of approaches may in some cases be not useful for speedrunning purposes, e.g. if the bufferable movement just loses too much time over a faster alternative that doesn't allow as much to keep any kind of control over relevant parts of the game state development, so that foregoing bufferable movement would be preferable, and especially if any potentially required additional setup time involved in it is too much compared to the benefits that may come from it.

Also note that while I'm only going over button inputs for these approaches, they may also just as much hold for when control stick movement is involved, to the extent to which this is controllable.

Regarding what situations RNG-manipulation approaches start out with, in principle, these approaches may in theory at least potentially have a chance to work from any point at which one can start or continue the game (depending on how the game treats RNG values, and e.g. if there is frames at which a normalization of the RNG value occurs), but the preferable choice of the starting location typically depends on the goal of the RNG-manipulation, and the same for other parameters that may play a role. In particular if at saving the game the current RNG value or some change of its behavior is saved alongside other variable values, one may still be able to construct setups, either for specific saved RNG values or behaviors of it when the game is powered on again, but might rely on being able to save with the right RNG value conditions and maybe being able to identify somehow if this is the case, or one may even be able to construct a setup for any saved RNG value case to continue with.

Figuring out exactly which RNG values will lead to what outcome for a given RNG-dependent event as well as using lua scripts or other means to map this info onto the given advancement of the RNG for the buffered movement for the range of different RNG values it provides to arrive at the critical event that relies on certain RNG for a favorable outcome would be an own topic and would have to be figured out individually, but here is some links to pages from TASVideos that explain how to identify memory addresses associated to game variables in general ( http://tasvideos.org/MemorySearch.html ) and in particular RNG variables and explain common properties and behaviors of it: http://tasvideos.org/LuckManipulation.html

I. In the following I present a concrete example case (from which can be abstracted to carry this approach over to other games) of 1 kind of RNG-manipulation approach for a game in which this approach was successfully developed and tested, which hopefully helps making this more understandable:

Here would be a visualization corresponding to what is described below:

Game, start situation & (local area) setting: The game in question in this case is Super Metroid, the start situation when the game is turned on consists in its relevant parts of having 1 (of in total 3) save files prepared to the point that upon starting to play on this save file the introduction cut-scenes are skipped (which otherwise would just add significantly to the amount of not input-wise bufferable inputs required to advance past it) so the player would start with Samus automatically on her own riding down the elevator of Ceres Station (the game's introductory area). Ceres Station consists of 6 rooms in total, with this elevator room on the left end and an introduction boss, Ridley, being located at the other end in the final room to the right, with all other rooms lacking any noteworthy activity going on in them.

Goal of the approach: The specific goal in question in this case would be to make the odds of Samus entering and arriving at Ridley's room in Ceres Station such that the pattern of Ridley's attacks (of which there exist 3 different kinds) avoid 1 kind of attack (where Ridley directly accelerates towards Samus in a ram attack which is especially hard to dodge) for as long as possible as high as feasible, for the purpose of allowing the player to shoot 100 projectiles at Ridley during this time and end the boss encounter that way without taking any damage (which itself would be just a part of a game completion with least necessary damage taken). Note that the purpose here is to increase the odds of getting any good pattern, while no setup for it is required for a damage-less encounter, but in this case one might need much more time and might rely on many more attempts until successfully passing this boss encounter damage-less. And as side-effect, not only can this then help to get any good pattern of attacks, but can allow to identify mid-fight which particular attack pattern one currently is confronted with (namely as soon as it deviates from any attack patterns associated to RNG values for nearby frames at which the room could instead have been entered, to know from that point on exactly what to expect for the rest of the encounter, and not only that, but another side effect in this case is (and in general can be) that instead of practicing the boss encounter for various sufficiently long patterns, one can reduce the practice (or the need for preparedness) to an up to much smaller set of workable cases. With this written, I think an approach like this in some cases may also make the difference between some special ruleset category being barely accessible for speedrunning or more accessible.

RNG-dependent target event/behavior of the manipulation: Being able to get past Ridley without getting hit heavily depends on Ridley using a ram attack or not within the first roughly 5 to 7 attacks, with the 3 different attack options being (i) straight ramming Samus which is almost unavoidable, (ii) flying in a circle which is mediocrely dangerous since sometimes it amounts to taking a 50% bet on 1 of 2 spots that are usually safe from the tail that Ridley can whip Samus with, and then there is (iii) the fireball attack where 1 such attack consists of 2 fireball waves which is the most favorable option because it is easy to dodge and is most time-consuming for Ridley while shooting Ridley. As long as Ridley doesn't use the ram attack, Ridley's entire behavior including the attack pattern is fixed and in particular independent of what the player does once Samus is in the room and only depends on the RNG (Random Number Generator) value with which Ridley's room is entered, or (effectively equivalent to that) the total amount of time (in terms of the global amount of frames) that was needed to enter the room upon powering up the game. So the idea behind this particular approach to achieve this goal was to make sure that the RNG variable has a suitable value when Samus enters Ridley's room.

Obtaining an accurate, complete, ordered list of the available RNG value cases that the target event/behavior depends on: For the purpose of this goal Taco (a former Super Metroid TASer) made a lua script that allowed me to get a finite, chronologically ordered and complete list of fixed Ridley attack patterns always up to the 1st ram attack (from which on the pattern wouldn't be independent of Samus' movement in the room anymore) for all candidate frames for Samus' arrival at Ridley's room (or equivalently for all RNG values with which the room can be entered). Alternatively one could have used RAM Watch for the RNG on an accurate SNES emulator (like lsnes) to manually write down what patterns are encountered for different RNG values with which Ridley's room was visited, but this would have taken much more effort.

Evaluation of the obtained list of available potential RNG value candidates for the manipulation for the purpose of probability maximization of a successful outcome with the buffered movement approach: With and in this list I was able to locate the longest time interval (which was 4 frames in a row with by their associated RNG values determined suitable patterns) that consists only of those Ridley patterns where it would take Ridley long enough (in terms of time but also number of attacks) to be able to do a ram attack. This means that if one would practice just those few different patterns so that one can consistently survive them without taking damage, then the only remaining problem would be to make sure (with an as consistent as possible setup) that Samus arrives in that room within this small frame range.

Creation of one or more base approaches that are and represent types of bufferable movement (besides potentially existing not bufferable components) from a calibrated starting situation (e.g. powering on the game with fixed SRAM) up to the target event/behavior of the intended RNG-manipulation: What can be exploited once Ceres starts up, is the fact that there is a whole variety of easily bufferable (that means with long frame windows for player inputs where it doesn't matter if one is a frame off with input as long as the input happens within the respective frame window) manners in which one can make Samus move with consistently always the same amount of frames through Ceres Station up to Ridley (due to room geometry reasons, a variety of easily controllable buffered player character movement options, and the long duration of door transitions). This holds true at least for decent emulators, while for actual consoles there may be slight inconsistencies when a lag frame more or less may be present (typically due to synchronizing issues with the Sound Processing Unit, apparently), but it'd still be close enough in that case. In the following I'll explain the initially devised default bufferable movement (from which alterations were made to adapt the timing as necessary for aligning the advancement of the RNG values with entering Ridley's room) in this particular case through the rooms of Ceres Station. During the elevator ride by buffering Right Samus will walk off the elevator platform. Then starting to hold Left within a decently long frame window (for making any frame timing within there lead to these cases merging back into equivalent states later) while Samus is falling midair turns Samus around and aligns Samus against the elevator platform's edge and continues moving Samus to the left after Samus moves far enough down to pass the platform's edge while falling. Then the same (just in the other direction) done by starting to hold Right towards the left edge of the next lower central platform that Samus falls onto works analogously, and continuing aligns Samus at the opening door at the room's floor and leads to the next room. Then (while still holding Right) a full spinjump is started (by pressing & holding Jump for at least as long as it takes Samus' jump to reach its apex) but only once Samus fully walked off and down the at first diagonally sloped floor onto the even low floor but before walking into the even high grounds in the center to land there and continue holding Right to walk into the next room. Then one starts holding Left once Samus falls again (off the floor with the upper stairs) to change the movement direction just like it was done for the elevator room platforms, and finally the same except rightwards is done again by starting to hold Right once Samus falls off the floor yet again, and from there one just continues to hold Right to eventually enter Ridley's room.

Devising & gathering variations of one or more RNG-manipulation base approaches by which alternate, still bufferable movement can branch off from a base approach: The following bullet points describe a quick list of concrete examples for the main options that are available to change up in which (for the relevant aspects of the game state development) bufferable manner Samus moves through the rooms of Ceres Station. ° Adding any fixed amount of so-called armpumps (changes to the angle at which Samus' arm cannon is held) while Samus moves along the ground, as each of them moves Samus forwards exactly 1 pixel each time; ° Adding any fixed even amount of turnarounds to go backwards through any door transition (by holding Left or Right during door transitions to move to the backwards direction) to enter and move through any amount of previous rooms before turning around again analogously; ° Adding any fixed amount of starting to hold the Dash button during any transition to run instead of walk through the next room; ° Adding any fixed amount of releasing or starting to hold Dash in the middle of Samus' movement through a room safely while Samus is falling midair or just after Samus bonked into a door (which opens up on its own based on proximity, with a decently long delay after bonking against it); ° Adding any fixed amount of spinjumps with (easily bufferable) maximal jump height while making sure each of them safely (i.e. with sufficient frame window) starts at some given floor height specific to that jump and safely lands on another floor height specific to that jump, while moving in only 1 direction (rightwards or leftwards) throughout the whole jump (so that even though the sideways movement speed during the jump is different from the movement speed on ground, the total amount of time spent moving this way midair stays fixed, independent of jumping earlier or later).

Identifying/Determining the RNG value (or time, by the amount of frames) towards which the whole RNG-manipulation approach (with its bufferable and not bufferable components) shall be calibrated (by it being the most frequent occurring case in practice, in the end): In general, the longest amount of consecutive frames that correspond to favorable outcomes obtained with them might not necessarily be the best case to aim for with the bufferable component (and the degree of freedom that comes with it) of an RNG-manipulation approach, but depending on a player's personal probability distribution of relative arrival times at the target event of the RNG-manipulation, aiming for other arrival times (e.g. after having to rapidly mash buttons to advance past some menus) may be better. To go a bit into mathematical modelling for such a situation using probability theory, one could interpret it as follows: Let the positive real numbers p(-n), ..., p(0), ..., p(n) (with sum equal to 1) be a given and fixed probability distribution for arrival frames (from -n to n for some positive integer n, with central frame 0 being a chosen reference frame) at the target event of an RNG-manipulation, for a given person and the setup the person is using and the manner in which the person is approaching rapid button mashing to pass not bufferable components of the manipulation. Then for a given corresponding distribution (d(-n), ..., d(0), ..., d(n)) (which would represent the frame range to which one is calibrating the RNG-manipulation) of truth values (with 1 for true and 0 for false) for a useful or useless outcome occurring on the associated frames (assuming any useful outcome in there is equally good as any other), in order to maximize the chances of success one might want to maximize the sum p(-n)°d(-n) + ... + p(0)°d(0) + ... + p(n)°d(n). An example to illustrate how different situations would compare to each other based on this modelling approach: Let p(2 frames early) = 20%, p(1 frame early) = 20%, p(aimed for frame) = 20%, p(1 frame late) = 20%, p(2 frames late) = 20% hold. Then calibrating an RNG-manipulation approach around a longer interval of consecutive frames with useful outcomes by centralizing the approach around that, like e.g. with (d(-2) = 0, d(-1) = 1, d(0) = 1, d(1) = 1, d(2) = 0) with associated chance of success according to the model being 0°20% + 1°20% + 1°20% + 1°20% + 0°20% = 60%, which would contain a 3 frames long window of useful outcomes may nonetheless end up worse than centering such a setup elsewhere e.g. when there's nearby split up frame windows with useful outcomes, such as with (d(-2) = 1, d(-1) = 1, d(0) = 0, d(1) = 1, d(2) = 1) with associated chance of success according to the model being 1°20% + 1°20% + 0°20% + 1°20% + 1°20% = 80%. Furthermore, for rapid button mashing parts of an RNG-manipulation approach, in order to advance past menus in a game each time nearly as soon as possible, in some of those cases after a lot of practice and experience with what an early and what a delayed advancing past some menu screen looks or sounds like, with more detailed insight into recognizing these differences one may be able later on during the bufferable part of the approach to slightly compensate for such recognized deviations in order to nudge the pace at which one is approaching the target event of the manipulation in the right direction, back into the aimed for frame window, depending on if there exist options to slightly change the pace of the bufferable part of the approach. Using this abstract probabilistic modelling approach, a sequence of 4 consecutive RNG values was found that all provide usable Ridley patterns, which appeared to be the best scenario to aim for (with 1 exception of there being an earlier but possibly too early similar situation of 4 suitable RNG values in a row that was ignored).

Dealing with performing the (for this specific approach a rather straight forward case of) not bufferable components of the RNG-manipulation approach: The remaining task was to then figure out with manual attempts of different versions of the approach at which frame one arrives at Ridley on average (or rather the most frequently if there is no symmetry of the distribution of frequencies to be assumed) and to then figure out to what Ridley pattern (or associated timing or RNG value) each new iteration/version of the approach corresponds to and is calibrated to, within the ordered list of RNG values, and each time compare that to how far (and in what direction) that timing deviates from the target timing that one wants this average arrival frame at Ridley to be in the end (which should be some central frame within a cluster of frames with high local density of strictly good associated patterns) to know how many frames one needs to shift the arrival time forwards or backwards in time using the available controllable bufferable movement options that one has for going through the rooms. The tricky part though is that one has to start from power on or the RNG will not be predictable (as it keeps running on and on almost every frame and the current RNG value is usually unknowable and contained in a large set of possible RNG candidate values), and that there is then a few menus through which one has to advance the game in order to reach Ceres Station. So through these menus the only remaining working option (besides trying to aim for advancing past menus with single inputs, depending on what cues are available for doing so) would be to rapidly mash the Start and Jump buttons (in this game case the only available buttons to advance past the menus) as fast as possible, since the faster it is done the smaller the possible realistic range of frames becomes at which Samus arrives at Ridley, in order to make sure that the number of frames that it takes the player to reach Ceres Station takes always close to the same amount, with as little deviation as possible. And with this method, after having found a suitable version of buffered movement through Ceres Station, the rate of obtaining useful patterns among all samples was 13/30 (without trying to slightly change up the buffered movement as reaction to observing a too long delay before menus were advanced, and with slower button mashing in later samples for quickly advancing past the initial menus).

II. Special case scenario of caging the RNG into a tiny separate loop of RNG values, explained using an example from Super Metroid (for the purpose of subsequent RNG-manipulations): Super Metroid uses a broken version of a Linear Congruential Generator (LCG) ( https://en.wikipedia.org/wiki/Linear_congruential_generator ) in order to calculate a new RNG value based on the previous RNG value or the RNG seed value. Because of a slight deviation from a ''clean'' LCG process (that would just create 1 closed loop of RNG values within which the proceeding RNG would advance forever in 1 direction) for calculating new RNG values, the (directed) graph ( https://media.discordapp.net/attachments/396448200447361024/740000116643201096/Super_Metroid_RNG_graph.png?width=952&height=597 ) consisting of 1 unique vertex for each possible RNG value (which are the integers from 0 to 65535) and 1 directed edge from any vertex that represents some RNG value to another vertex that represents another RNG value if the former RNG value as input into the LCG produces the latter RNG value consists of 3 separate components ( https://en.wikipedia.org/wiki/Component_(graph_theory) ), each with their own loops (that the RNG is forced to run into and stay in eventually) of different lengths. Now there is certain rooms in the game that have certain kinds of enemies that will force the current RNG value to be set to always the same fixed RNG value specific to the kind of enemy in the room for 1 frame when the room is entered, from where the flow of future RNG values will continue. Furthermore, only for rooms that load or have lava or acid in them, during normal gameplay frames in those rooms, the high byte of the RNG value will be swapped with the low byte of the RNG value exactly once per frame (so that e.g. an RNG value VWXY turns into XYVW, with V, W, X, Y being placeholders for hexadecimal values from 0 to F each). This swapping effect is what allows the RNG to jump from 1 component of this RNG graph to another and can be abused to cage the RNG into the smallest graph component consisting of just 1 loop of 87 unique RNG value vertices. There exists a suitable room that is heated, has lava in it and has an enemy of the kind in it that will calibrate the sequence of RNG values to start out at a fixed RNG value at a fixed frame relative to entering the room, which with the right amount of energy and letting this be drained to 00 in an always consistent amount of frames allows to enter the game over screen (during which the swapping of the RNG value's high byte and low byte will not continue anymore) and load the game up at a previous save such that the RNG will be caged in this tiny loop due to the timing of entering the game over screen being chosen (by having the right amount of energy be drained by heat damage) in such a way that the last swap of the high byte and low byte that occurs to the the RNG makes it jump to an RNG value that is part of this tiny RNG value loop of the RNG graph. Now, such kind of approach to cage the RNG in a small and more controllable loop of RNG values may not be available in most games, but for games with similar behavior of the RNG and a small separate loop of RNG values for which there is specific ways for the RNG to enter it, this kind of manipulation may be possible.

III. Another conceivable theoretical approach that one could try to use for RNG-manipulations (in which the goal is to make some favorable RNG-dependent outcome occur) would be in advance developed but in real-time adaptive movement-buffer RNG-manipulation approaches that are branching off to suitable, still bufferable versions of them, based on throughout the buffered movement accumulated - and the RNG value at some chosen specific local reference frame piece-wise further and further specifying - information, allowing to identify what the particular RNG value was at some particular nearby earlier point in time (in that reference frame), or to significantly narrow down the list of RNG values to a concrete small set of remaining RNG values as candidates for what the RNG value could have been at that earlier particular point in time (in that reference frame). However, the applicability of this type of strategy is highly theoretical & speculative and may due to its nature be rather inaccessible to use in almost all cases, and I'm not aware of a single game for which such a strategy has been deployed.

I'd be interested in what other RNG-manipulation approaches of this kind exist already, especially the more convoluted, sophisticated cases. I'm so far besides this concrete case only aware of what I heard about Ninja Gaiden and what might be more of an accidental lucky lining up of for speedruns suitable enemy behaviors throughout the stages as long as the speedrunner keeps moving through the stages with certain strategies at a fast pace and without deviating too much from that pace by making execution mistakes. But I've also come to know a little about how similar RNG-manipulation approaches are utilized in Pokemon game speedruns.

Redigerad av författaren 3 years ago
Finland

thats a lot of text

Ivory tycker om detta