Darkest Dungeon®

Darkest Dungeon®

View Stats:
I don't understand why RNG + Speed is a thing
What is the point of having speed at all if my Speed 8-10 characters get outsped by some lousy spearfishing Cove slugs.

Like, I really don't understand, am I supposed to get memed on by RNG for initiative and literally watch my characters die, when all my characters have at least 3 or 4 extra Speed compared with the enemy team but they can't attack cuz lousy dice roll?

I really hate the fact that you cannot plan your team and moves in advance due to this lousy mechanic.
< >
Showing 31-36 of 36 comments
No One Jan 11, 2021 @ 1:38pm 
It's called seeding and it's usually done to discourage savescumming.

RNG comes from the term pseudo-random number generation. No game is actually random, it only pretends to be - it is pseudo-random. All programmatic RNG is fully deterministic. Given the same inputs, it produces the same outputs. Typically you generate some seed, then feed the RNG's own output back into the RNG as the next seed, and so on. If the RNG isn't trash, it will produce a sequence that looks random, is plausible as a random sequence, but it's not random given it's 100% reproducible. Given any particular seed, the RNG will produce exactly the same sequence of numbers as an output. This is how Binding of Isaac seeds let you replay the same dungeon, and how Minecraft seeds let you play on someone else's world without having to send a massive save file.

Though admittedly some get fancy and use the microsecond(s) of your system time as one of its inputs, which, combined with quantum jitter in the human nervous system, amounts to true randomness.

Later Civilization games use seeding, to discourage the player from savescumming until they always win their fights. In CIV (and also DQ3) you can burn bad rolls on unimportant actions, though. E.g. if you're sieging a city, you can let the bad rolls kill some cheap, obsolete unit.

DD may even use the modern timestamp-dependent RNG, but it rolls in advance and saves a set of them. Probably takes less than a second to roll ten times as much as you need in a quest. Alternatively, each mission has a seed which is saved. Copying and replacing save files every mission is even less fun than tedious stall tactics, and Red Hook decided to make sure nobody practices it.

The wagon is even less random, BTW. I believe there's a pre-determined deck of classes, and it simply shuffles the deck and deals it to you through the wagon. Alternatively there's some randomness in the proportion of classes in the deck, but it checks in advance that you're not getting too screwed with any of the classes.
In other words if it seems like the wagon likes to give you houndmasters, that's because it does. The deck has many houndmasters in it.
Absolute Madman Jan 11, 2021 @ 1:43pm 
Originally posted by No One:
-snip
Y'know, you're actually quite a knowledgeable dude, if not for being a bit of a prick.
Galroche Jan 11, 2021 @ 1:46pm 
Originally posted by ChopShop:
This game is garbage. There is NO RNG. Perform this test. Enter a battle, any battle, and record the outcome of each round all damage, all resists, in order. Close the game and reload. You will start at the beginning of the battle, again record all damage, resists, in order. Now compare the two battles. You will find that it is exactly the same every time. ALL battles are predetermined before they even begin. You can this test as many times as you want, it will never change. Crits will always happen at the same point, for the same amount of damage. Misses will always happen at the same point.
This basically ruins the game, because if it is all predetermined, what is the point!? There is NO strategy. No Luck.

certainly not predetermined. Seeded ? maybe, haven't tried it.
Skinny Pete Jan 11, 2021 @ 6:11pm 
Originally posted by No One:
It's called seeding and it's usually done to discourage savescumming.

RNG comes from the term pseudo-random number generation. No game is actually random, it only pretends to be - it is pseudo-random. All programmatic RNG is fully deterministic. Given the same inputs, it produces the same outputs.
When you need actual randomness that can't be exploited (think real money gambling), you go for an actual source of randomness. For instance, the higher end poker sites actually use quantum optical processes. Even when the source is random, though, that's usually just what's used to seed the PRNG, often something like Mersenne Twister.

Obviously recreational games don't need this and you'd generally only notice the "pseudo" in the PRNG if you're trying some stunt like scumming.

Originally posted by Overeagerdragon:
You can actually...any character with 9 SPD will ALWAYS go before a 0 SPD enemy.
Good point but as with most things in this game, when you avoid one specific problem you often create others. "Speed teams" are a valid strategy, but you're almost always buying into a situation where your guys go first and "clump up" and if you somehow whiff, the enemy all goes at the same time. This can be problematic as the faster characters (like Grave Robber) are very susceptible to one hit-DD, two hit kills. (At the same time those very characters like GR are very good at single-handedly eliminating an enemy before it can even do anything.)

So I generally think it's preferable to have a range of speeds. Healers are an obvious example of a character that can usually cope with being slow. Them acting last means you can finish off a round with either another attack or a heal. It's often a good strategy to have the backup healer at the opposite end of the speed spectrum.
Last edited by Skinny Pete; Jan 11, 2021 @ 6:23pm
Gilmoy Jan 12, 2021 @ 11:17am 
Ages ago, I even used the pseudo-randomness of a sequence to graft a true Log Viewer onto a pre-existing game's log file. The log file format was never intended to be used that way, but I was able to deduce enough information to recreate every single die roll. The seed is part of the lobby challenge protocol: when player B accepts player A's challenge, the one parameter B passes to A is, in fact, the (twice-encoded) seed. That's the only time they ever synchronize. Thereafter, both copies launch with identical seed, execute identical orders in the same sequence, and generate exactly the same sequence.

I had this epiphany that I could parse a log file for that seed, launch my own local game, and replay the entire game up to any point, exactly as both A and B saw it happen. But my copy is running in the VC++ debugger, and I can single-step through the source and examine variables and the call stack, right up to the point of a crash or error.

Inevitably, when a bug in the code causes one game copy to consume 1 more random number than the other, that's the dreaded Out of Sync (OOS) error. I even found ways to kill off 1 tainted guy without generating any random numbers (stand him in lava), which "cures" certain OOSes. Probably every other network game that complains about OOS-type errors has the same root flaw of mismatched consumption of pseudo-RNGs.

~~~~~~~~

Later, I even codified this experience into some Laws of Game Dev:

0. Use a pseudo-random number generator, so that you can duplicate the sequence of pseudo-RNG calls. Reproducibility enables post-mortem debugging.

1. Write the Log Viewer First.

Don't make me rip out your 2-lane I-90 from Seattle to Boston to put in a 6-lane Log Viewer after the fact. Easier to just start with it in the first place. (Deep Corollary: the game dev company that does start with it is likely to be the one that persists.)

2. Promote your log-round-tripping data into first-class values.

2.a) Every datum is a form of serialization, i.e. saving a piece of game state to an external persistent format (in this case, a text file, but in principle it could be binary) for the purpose of reading it back in. Serialization is a write-(years pass)-read cycle.

One datum could be 1 attack swing, which consumes 1 random number.
It gets logged as a string such as "2 of 5: Alice attacks Bob but misses [96]".
Thus, you need to both write that string, and read it back in.

2.b) For each datum, create 1 (sub)class D of a master LogDatum class.

D implements both the writer (as operator<<(ostream &, D const &)),
and the reader (as operator>>(istream &, D &)).
Textually, put these two adjacent, so that you can single-screen them both.

This alone will save you hours and hours of effort. It sucks beyond words to have two highly correlated (in fact, lockstep-mirror-imaged) pieces of code be widely scattered in 2 (or more) different source files. It's infinitely cleaner to make them be part of the same code, in the same place.

Also, the code itself gets unbelievably beautiful, because it's so terse.
The game code now prints a D like this: ostream o; o << d;
And the log viewer reads it like this: istream i; D d; i >> d;
This reduces every piece of log data to the same mental footprint as an integer.
It doesn't get simpler than that.

~~~~~~~~

Log Viewer worked so well that it basically put itself out of business. Within ~1 year, I caught a couple hundred crash bugs and fixed them all, including some mythical legendary bugs spoken only in whispers since the dawn of the game. Thereafter, there were no more crash bugs. The entire category of solvable-by-Log Viewer bugs basically collapsed to near 0.

Now imagine a game that has Log Viewer from day 1, and sidesteps all of those bugs in the first place, because they're caught in-house during dev. That's actually the normal case we all expect, right? And so must it ever be.

All of this rests on the foundation that pseudo-random number generators are deterministic. Determinism enables debugging.
Last edited by Gilmoy; Jan 13, 2021 @ 2:56pm
ZT Xperimentor Jan 13, 2021 @ 10:53am 
Originally posted by ^7ja^1co:
things games idea of fun is rng...
Reminds me of borderlands lol
< >
Showing 31-36 of 36 comments
Per page: 1530 50

Date Posted: Jan 9, 2021 @ 8:13am
Posts: 36