I've been thinking a lot about random number generators in singleplayer games, their pros, their cons and how well they scale as players improve. Recently a fun idea wormed its way into my head : treating RNG as a gameplay mechanic.
It's a simple premise with some pretty radical implications. Because it requires some pretty extensive design work, I won't implement it into my current games, but it's something I 100% want to mess around with in the future.
Why RNG?
RNG's are usually seen as a kind of external, universal module which can be plugged into a game - an "uncrackable" function you're going to be using to introduce luck into games.
I think viewing game RNG this way doesn't make much sense. Randomness in singleplayer games tends to be a type of shuffling mechanism - you're mixing up different states, scenarios, attacks, enemy configurations, etc. in order to test the player's reactions, decision making, flexibility & general game knowledge. Game randomness is a way to create novelty and delay the game being solved.
Given this, should RNGs be uncrackable? I don't think so, unless you have a good reason for it. Cracking and manipulating even the simplest systems requires immense effort, far more than playing a game "normally". It usually requires reverse engineering, extensive practice, external info and tools. Even if the goal is to make sure that at mid to high levels RNG is a constant factor, a perfectly crackable system will still get the job done.
What's more, RNG systems simply don't scale up very well. If an RNG heavy game becomes highly optimized, then RNG will stop making it more engaging and instead just make it frustrating to deal with. Decision making fades, and you're left re-rolling for better luck.
With all this in mind, I think it's worth thinking of RNG not as a modular, uncrackable system, but as a real, BESPOKE in-game system made to suit the game you're making. Think of it as a gameplay mechanic.
Thinking Mechanically
When thinking of RNG as a system-mechanic like any other, a lot of things become clearer, and it opens up the design space substantially. You can see this in how games with simpler RNG systems, which are manipulated in speedruns, for example :
- Doom's RNG table where value gets picked based on player input & snowballs from there (afaik TAS only)
- Pokemon Red/Blue's system where it advances on game logic ticks (afaik player movement/actions of any kind, among other things) and can be fairly consistently manipulated even in non-TAS runs
Visualize Doom's RNG table as a very granular movement mechanic. It's not unmanageable because it requires pixel perfect precision per se, because a lot of physics based-games do too at highest levels of optimization. It's unmanageable because the outcome differences are so extreme. And the outcomes snowball to such an insane degree throughout a run that they become unmanageable.
Imagine a top down racing game, you're taking a line through a corner. The racing equivalent of this would be if you lost 3 seconds because your steering angle was 271°/272° instead of 270°. And that single time loss would completely change what was and wasn't a viable line for the rest of the race.
If we simplify this further into a list of values + an index picking out values, we get something like this :

We're going for 3, but missing it even slightly ends up with a ridiculous, massive deviation which will potentially completely change the outcome, instead of slightly altering it. When viewed as a mechanic the solution becomes clear - simply make the value ranges more gradual. Rewrite the table of values so it looks something like this :

This keeps the frame-perfect nature of executing the RNG manipulation, but gives some room for error. You might not get the exact value/damage you want, but you'll get something close. And if every value check is like this, you could potentially compensate for this mistake down the line, or average things out over the course of a run. Things aren't quite this simple in practice, but more on that later.
To my knowledge (and I'm no expert here), Pokemon added another beneficial layer to this by having much slower tick-rate. It's not checking your inputs every frame, so it becomes a lot more consistently manipulateable. It does, however, still have the insane snowballing where every mistake will change things for the rest of the run. To alleviate snowballing, games can have really good RNG reset points - end of levels or even, say, specific items which reset RNG on use.
If you combine the more granular range of inputs, a slower tick rate & frequent resets you get games with much more manipulateable RNG systems, ones which high level players can take advantage of, and ones that add a meta-layer to in-game decision making, similar to Battle Garegga's rank manipulation. All while making the system difficult enough so that anyone who isn't at high level will, at most, only have some very general rules of thumb in mind, and will still experience the "shuffle" effect of the RNG.
The extent to which games allow RNG to snowball, the ways players advance and/or reset the RNG index, the distribution of numbers in the random value table - all of that will contribute to a game's unique character.
Problems
While all of this might sound sweet, the reality of the situation is a lot more difficult & complicated. Because RNG systems are so abstract and detached from the in-game actions they're typically used for, this creates a lot of problems that have to be factored in at the initial stage of a game's development. Lemme go through a bunch :
- What if the difference between 3 and 5 is the difference between an enemy doing an iframe dodge, and an enemy standing there doing nothing? Making the values more granular won't make games less punishing of anything less than frame-perfect inputs. This is the hardest challenge to overcome. It might only make RNG manip viable for more granular stuff - slowly moving scenery objects and that sorta stuff, not what you'd really want it for which is stuff like enemy behavior manipulation.
- How do you handle binary decisions/outcomes and modulo stuff in general? You might have to use the position of the index itself, rather than the value it's pointing to for that one. Or build several different, independent RNG tables.
- How do you telegraph any of this to the player? Making it explicit & clear will potentially make them worry about RNG manip too early & too much, but hiding it makes it a nightmarish, annoying system to deal with. People already freak out about Battle Garegga's rank.
- How do you handle everything with just 1 RNG system? Different aspects of the game like damage vs enemy behavior vs item drops might require different systems, and that can quickly become unmanageable.
- How can snowballing be handled? The player fucked up a few times in a row and threw off their routing - how do they recover? Should there be a way to "go back" in the table somehow? Or do you just use frequent resets for this type of thing?
As difficult as all this shit is, I think it's interesting to think about because it's a space for game design which players have tapped into, but developers have not as far as I know. And it creates a very nice, granular way of controlling the entire game state, rather than only giving the player granular control over their own movement. Def something I'll be thinking about a lot.
