Hi, I'm a game dev interested in all sorts of action games but primarily shmups and beat 'em ups right now.

Working on Armed Decobot, beat 'em up/shmup hybrid atm. Was the game designer on Gunvein & Mechanical Star Astra (on hold).

This is my blog, a low-stakes space where I can sort out messy thoughts without worrying too much about verifying anything. You shouldn't trust me about statistical claims or even specific examples, in fact don't trust me about anything, take it in and think for yourself 😎

Most posts are general but if I'm posting about something, it probably relates to my own gamedev in one way or another.


🕹️ My Games
boghog.itch.io/
🎙️ Game Design Vids & Streams
www.youtube.com/@boghogSTG
☠️ Small Updates + Dumb Takes
twitter.com/boghogooo

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 :

rng

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 :

rng

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.


You must log in to comment.

in reply to @boghog's post:

Have you tried either dead cells or hades, both of those use rng in terms of the levels you run through when playing the game. Both games do this well but again both also have issues with this too.

Example in dead cells, you could die near the end of one section, it'll restart you gain your soul back but the weapons you're than given to start your next run can either hinder you or help you finish said section.

Hades to some extent is fun, you can add additional modifiers in the game to tweak how it runs. But all that is lost, once you get a specific weapon which leads to you just blasting through everything with ease.

Would be interesting to see how you would incorporate this into the games you make.

I tried Dead Cells but got kinda bored after a few hours, nothing really hooked me and made me go "holy shit thats awesome!" and the platforming felt waaay too automated to the point of feeling crappy.

The item RNG in RLs just kinda sucks I think, especially permanent stuff. Spelunkys kinda the best and worst of both worlds, on 1 hand it does something brilliant by limiting how many items you can carry and making the items temporary, situational & utility based instead of being straight upgrades....but then it also has some straight upgrades and downright bonkers items. If you wanna have fun check teleporter speedruns for Spelunky

interesting take on this application of RNG. I have a feeling the reason this kind of thing has yet to be practically implemented is because most RNG relies on the current number being used to generate the next one, and the goal of a good algorithm is generally to have a wide spread between numbers. with xorshift you're going to perform a series of bit shifts and XORs on the current number back to back to get the next number in the sequence, which sort of goes against a table storage technique unless you generate all the numbers in advance, which then can ruin the periodicity of the algorithm, etc. etc. switching to a table system would effectively be a switch to determinism, but maybe with enough slightly different tables that you switch between with actual RNG you could make a best of both worlds solution. something like setting up a general "table curve" that then becomes the mean of a gaussian distribution with a tight std dev that you generate 40 separate tables with. results like [..., 19, 22, 25, 14, 9, 7, ...] for one table, [..., 20, 21, 27, 18, 9, 8, ...] for the next, [..., 22, 20, 26, 14, 11, 5, ...] etc. so that they all end up with a similar sort of flow while still having slightly different values.

something I brought up in my last article was the idea of modeling RNG within my particular analytical system using a Markov Decision Process, where there's assorted probabilities of given things happening in a system and said probabilities change based on the actions taken by some action-making agent (in this case the player). I've often thought this would work well for enemy AI: you offer a way for the player to manipulate the probability of a given action coming out without making it an explicit guarantee. doesn't necessarily work well large-scale for altering the game state fully as you're trying to do here, but maybe with enough of them stacked at once between different on-screen entities it can provide the same sort of dynamism.

Well the point I wanna make is that in games, RNG systems being deterministic (in terms of not being particularly well obfuscated and variable) isn't a problem. Doom's RNG table despite its simplicity and determinism is still uncracked, players struggle to manipulate RNG even for SECONDS, and they end up relying on luck - is anything past this really necessary for most games?

Either way you slice it, what we consider to be "deterministic" will depend on the purpose of the system - a "non deterministic" system in games will be too deterministic in the context of say security or what have you.

When you get down to it, why are devs using LCG or Xorshift methods, really? Why are they randomizing seeds? Why are they trying to minimize looping in the sequences of numbers they get? It's inherited from different fields that were trying to solve different problems. Even the more deterministic tables are more the product of circumstance rather than design choices.

I think the reason devs haven't taken advantage of this is just cuz they don't see it as a viable space for design. I imagine if there was a mentality shift, devs would rethink how they approach RNG and tailor it more to their game...or maybe just say "fuck it too much work" and keep using the same systems. But at least that'd be an artistic choice at that point.

The markov decision process thing would be great to mess around with as well and I think thats probably the best route to go for strategy games without an execution element (since you can't use that inconsistency to create variety of outcomes). But then if you think about this at a really small scale in an action game (lets say optimizing 3 seconds of gameplay), you can run into the same issue as with normal RNG - you might increase the probability by doing specific actions but at the end its still gonna be out of your control. Unless you eventually max out the probability based on the player's execution/decision making with frame perfect execution being 100% guarantee of a specific result, thatd be a cool way of handling it

yea I think my reply was still sorta colored by that same "well the goal is still for it to be somewhat random" mentality that you're calling out here, and I agree, I think regardless of the choice just weaving RNG proactively into the design would be a good move, especially if it's integrated with an abstraction that can actually be understood by the player. and you're right, from an engineering perspective virtually all of these software techniques are deterministic because fundamentally if you're in a particular state and you use a certain input, the next state will always be the same. the only difference here is really the point at which a single fuck-up will completely throw you into disarray and make you improvise.

it occurs to me now that another solution to this would be frequent points at which the RNG (and maybe all entities relying on it) resets, maybe with the player's control. reminds me a bit of something like time trials in crash bandicoot, where everything in the level is on a predictable cycle, and if you save a little extra time at the beginning of the level you'll have to relearn the end bcs everything will be in a different part of the cycle. switching it so that all of the entities are manipulable by the player could give it a similar feel if there's a "butterfly effect" that propagates to later parts of a level, or it could be that manipulable entities are effectively inactive until you contact that them and thus there's a "reset" between segments. sort of a specific example for that particular structure but it's interesting to think about.

the MDP stuff I actually synthesized with my work while also playing a lot of older monster hunter a couple years back lol, but it sort of tracks because in those games the actions are extremely coarse and segmented compared to a lot of action game enemies, and the main manipulation is all through positioning. def integrates cleanest into turn-based stuff tho; I was working on a system last year where there were explicit Guarantees built in for each boss that would increase your score if you hit it, which also opened up some avenues for guaranteeing particular nasty attacks from the boss in exchange for score, but I haven't picked it up in a while. probably need to get back to it!