Even dice are pseudo random. If you could start it in the same position and throw it the same way every time in a vacuum, it would land on the same position every time. In a way that’s what speedrunners do - control the starting position and the throw.
@NesHacker5 ай бұрын
Makes sense. At one point in the script I used the phrase "fair dice" but decided to do away with that part to keep things a bit more simple. Thanks for watching!
@JB-mm5ff5 ай бұрын
Speedrunners are all about the loaded dice
@_marshP5 ай бұрын
By that logic, everything is pseudorandom, from the daily weather, to the placement of atoms. ...which is uh, true, save for the Schrodinger stuff and the other quantum physics shenanigans...
@AnonymousAnarchist25 ай бұрын
Yes.. but really no. The dice deform, so you can never know thier true starting position before a roll, while being shaken. Then they generate heat as they are shaken and rolled, so any subsequent roll will have for all intents a totally diffrent random location based on the unkowable state and postion of all the atoms in the dice. Of course without any mechinism for shaking the dice this is all moot, a free thrown dice can be manipulated by a person to roll fairly accuratly, they have to bounce off walls or be shaken in a cup to be fair throws. And that adds a lot of additional chaotic movement. So. yes, but youd have to make new dice for each roll, and not shake them prior to rolling.
@gaeel3305 ай бұрын
I think the "unpredictable" part is what is important here, or at least, it's what I emphasize when explaining randomness. Even cryptographically secure PRNGs are breakable if you're able to extract the seed somehow, and typically a good CSPRNG is a combination of a PRNG that is hard to analyse combined with a way of generating a seed that is hard to guess. Before CPUs had built-in systems for generating seeds, operating systems would "accumulate entropy" by measuring other hard to predict sources, a bit like the "waiting for the player to press start" method in this video. On Unix systems, the /dev/random special file would often accumulate data from things like mouse movements, disk read timings, keyboard interactions, network latencies, etc... Technically, an advanced attacker could try to guess some of these values and reverse-engineer the rest, but if the computer has been running long enough, it becomes unreasonably hard to do so. Basically, the question isn't whether or not "true randomness" exists, but whether or not you're able to be unpredictable enough. In the case of NES games, the fact that speedrunners are able to manipulate the PRNG shows that it's not unpredictable enough to beat a motivated attacker, but for a casual player, who are the intended audience for these games, it's sufficient. On the other hand, if you're running an online casino, you're going to need some way to generate random numbers that is more secure than that. If the attacker is some sort of godlike entity capable of accurately simulating every physical phenomenon around you, then nothing you do will be random to them. For most attackers, whatever CSPRNG library is available for the programming language you're developing with is probably good enough.
@Kwyjor5 ай бұрын
There's a relatively well-known bug in New Super Mario Bros DS where the random number generator can in fact get stuck. The odds of it happening are 0.0000001164% , though.
@jefism5 ай бұрын
to be fair, that is pretty random.
@Max-jz2hf4 ай бұрын
0.0000001164% of the time it works every time
@jefism4 ай бұрын
@@Max-jz2hf they've done studies you know.
@themlgbrosftw49604 ай бұрын
Who are they? ☠️
@canaconn23884 ай бұрын
@@themlgbrosftw4960they did
@gbs_central5 ай бұрын
We recently ran into this issue when coding a Yahtzee like game on the Game Boy where there were inherent biases when trying to use an 8-bit value for a 6 sided die. We used the truncate and rejection to account for that as well and are writing an article about it for our site. Great video!
@NesHacker5 ай бұрын
Nice! Yeah it’s subtle but can have a huge impact if unchecked. One of the other commenters mentioned a method of reusing bits from rejected numbers to get the time cost down considerably (might be worth looking into if for nothing else that “fancy” points 😂)
@christopherr84414 ай бұрын
Recently?
@undergroundmonorail4 ай бұрын
@@christopherr8441people still write game boy games
@TobiasEriksson883 ай бұрын
@@christopherr8441 Yes people still make Gameboy games for fun.
@bagelmaster83 ай бұрын
do you have any more info on the game? sounds cool!
@bubblinebee5 ай бұрын
Using hammer bros as an example of 'fun' rng is... questionable
@NesHacker5 ай бұрын
To be fair I said “hopefully”, which in retrospect kind of makes it and unintentional meta joke 😂
@deerel5 ай бұрын
As an example, it is great. People understand.
@Eliasdbr5 ай бұрын
* flashbacks from 8-3 *
@FFVison5 ай бұрын
This got me thinking "If you can dodge a hammer, you can dodge a ball..."
@wolfy0494 ай бұрын
I will add up my experience, when mario bros (with duck hunt) was basicaly my first games i had hands on, i was 5 / 6 years old, and i agree that i did learn well basic mechanic without knowing it. edit : 4:22 And that the part that blew my mind.
@D0Samp5 ай бұрын
While rejection sampling is good to avoid bias, there is an algorithm now that can largely avoid rejections. You multiply that 8-bit value with 20 (i.e. shift the value by 4 and 2 and add those with carry), perform some adjustment and just take the upper 8 bits of the resulting 16-bit value. (Without adjustments, you have the issue that four consecutive values come from 13 possible RNG outputs, but the fifth only from 12... which is still better than naive modulo, which discriminates against high rolls.)
@NesHacker5 ай бұрын
That’s really clever. You know, sometimes I think I learn more after a video that during the research for it 😆
@alexjackson79295 ай бұрын
That's exactly how the NES Dragon Warrior games generate random numbers within an arbitrary range. They multiply the PRNG output by the desired range and then "divide by 256" by using the high-order byte of the product. Some of the early Square RPGs on the NES, Game Boy and SNES do it this way too (while others use modulo).
@D0Samp5 ай бұрын
Also rejection sampling from 1..160 with a triple right shift achieves something similar as masking the upper three bits. It's a shame you probably don't want to do 1..240, there's no way for integer division by 12 (or modulo 20) that's significantly faster than repeated subtraction.
@magicalgirlnicole5 ай бұрын
What are these adjustments you're referring to? Where can I find more information on this?
@D0Samp5 ай бұрын
@@magicalgirlnicole Can't link it in a comment but there is a paper on this, "Fast Random Integer Generation in an Interval" by Daniel Lemire (arXiv 1805.10941). The included algorithm is defined for 64-bit RNG output with a 128-bit intermediary but works with smaller numbers, too.
@Omnituens5 ай бұрын
I've done some exploration of RNG on a few games and systems. One that caught my eye was Entombed on the Atari 2600 - The RNG is seeded by how long you hold the fire button to start the game - but not by frames. It sits in a small loop rapidly incrementing the value. RNG manip would be CYCLE perfect, not frame perfect trick! It also had the odd effect that because it was stuck in this loop waiting for you to let go, the game would never start if you just... held down the button.
@kirby0louise5 ай бұрын
Interesting. Though it's not terribly different from a modern OS where if you click and hold on a button, it's effects don't take place until you release (well, unless you're going out of your way to handle MouseDown, but almost everyone uses Click)
@NesHacker5 ай бұрын
Yeah that’s very interesting. Halting the game until a key was released sounds like something I’d do in a program as a kid because I fundamentally misunderstood how to write input code 😂
@sakesaurus5 ай бұрын
@@kirby0louiseon that, i really hate the modern touchscreen design of "all buttons are click not mouseDown and if the player shifts the cursor one pixel it doesn't register" Seriously it's so infuriating to click quickly when you are required to stay perfectly stationary in order to click a button.. Rrr
@gairisiuil4 ай бұрын
@@NesHacker to be fair it's the bloody 2600
@AndyScott5 ай бұрын
Awesome! Glad to see you finally tackle this topic in a video! I always find the "RNG manipulation" done in speed runs very fascinating
@NesHacker5 ай бұрын
Yeah there's a lot of other videos that do that topic *way* more justice, just thought I'd mention it here so folks were aware of *what* was being manipulated exactly.
@kaboomkp5 ай бұрын
This channel is awesome … Im 22 but started collecting NES and other retro consoles when I was 12-13. I’m starting to get back into it and learning the ins and out, and have future hardware & software projects I want to start. Your channel has been so great for learning information in a digestible way especially as someone with a non technical background.
@anon_y_mousse5 ай бұрын
One technical note is that the major implementations of rand() in C would double the size of the working state internally so that the period was also double, but they'd only output half of the computed value so you would get numbers that repeat out of the assumed sequence. The biggest problem was that the seed value was the same for each run of a program, so even if the period was only partially known the same values would still be output for each run. This is why usually it's recommended to seed the RNG with time( NULL ). Although, this is more of a modern consideration because not a lot of C compilers actually target a 6502 and even fewer did back in those days.
@NesHacker5 ай бұрын
Still, good information to share for those who are interested! Thanks 😊
@martinchya25465 ай бұрын
FInal Fantasy games (even 8th one) used a simple array with pregenerated 255 bytes in static order. Whenever game expected to get random number, it outputed current number and increased the pointer of table by one, wrapping after 255th byte. Very random if you know that there is always 172 after 60.
@DobinSergei5 ай бұрын
I've using same, "lut" (lookup table) with 255 pregenerated perfect random numbers. Each time next number is taken. For games it is enough, no need for more complicated. Downside is 255 bits of memory is reserved only for this. Method shown in this video does the same only with 2 operations! Definitely is better.
@UwePieper5 ай бұрын
@@DobinSergei It depends. If your game relies on random numbers it might be a bad idea because you have a simple list of numbers. As @martinchya2546 said your players might notice there‘s an order to your „random“ numbers. True randomness might give you the same number twice in a row.
@arkadye4 ай бұрын
Doom did the same thing.
@martinchya25464 ай бұрын
@@arkadye you are right, but in Doom randomness has much different role. It doesnt decide whether enemy will drop super powerful sword, only stuff like shotgun spread or enemy behaviour (as dar as i remember). So Doom case is fine for this method.
@blarghblargh5 ай бұрын
Your videos are getting so polished these days!
@NEStalgia19855 ай бұрын
Polished, he just blew away every statistics professor at community colleges. Thank God they aren't paid through patreon they'd try to corner the market
@tsvtsvtsv5 ай бұрын
great video! i was already aware that the nes has no hardware division routine but i still felt pretty clever for thinking of the "just reroll until you get a number that's in the range" method before you brought it up
@kyoobqa5 ай бұрын
Almost 100K subs, and it still feels unfairly small. I think I cracked it; you make me _feel_ like I understand everything while I really don't. Compressing a vast amount of technical knowledge into easy-to-understand videos requires incredible understanding of the topic, and you've got it. Totally worth clicking the bell, keep it up! P. S. If only you had a creator page allowing people to keep the channel running, hmmm...
@NesHacker5 ай бұрын
Yeah I’ve been resisting setting up a KZbin membership page. But it really makes sense since I’m not able to shout out my own patreon when I have sponsorships ☹️
@kyoobqa5 ай бұрын
@@NesHacker Just do it, man. I may be wrong, but I don't think you're losing anything by doing it, and I'm certain that people would join the channel to help you out. I'd donate myself but our country is blocked from sending money to KZbin and Patreon, sadly.
@Dejan275 ай бұрын
I have a good idea for a new video: "The code that makes Simon/Trevor climb stairs". In both Castlevania and Castlevania III, there are many glitches involving stairs. There's even an interesting one in Akumajou Densetsu in stage 6 - 4 (Sunken City) which was fixed in the international releases. A video explaining both how stairs work and how the stairs glitches happen, would be very interesting. There are also stairs glitches involving the character swap
@RetroCabeza4 ай бұрын
As a classic Tetris player, I find this video really interesting. Thanks to the seed being randomized before the game starts, we can have Tetris GYM and play with the same seed in two separate games.
@springogeek5 ай бұрын
This is a fantastic resource. I've not heard of the rejection sampling technique before, definitely going to use that in the future
@NesHacker5 ай бұрын
I try my best to give a good amount of context rather than just showing some code and call it it a day. I’m happy you found it useful and thanks for the nice comment ☺️
@Novastar.SaberCombat5 ай бұрын
It's kind of like a bubble sort, only you're not necessarily dumping identical values, you're simply axing the unwanted ones. Still, doing such a process wastes CPU cycles, so it's ideal to avoid it if you can. 🙂 Personally, I always loved a bub-sort when you don't want the same number to come up twice in a row (usually from a low range).
@jaredbrown6915 ай бұрын
So interesting, i took a coding class in college and wanted to write a computer version of the board game “acquire” but couldn’t think of how to do a random number generator. Little did I know that someone had already written a computer version back in the early 80s
@Novastar.SaberCombat5 ай бұрын
Using the internal clock as a seed helps as well. After all, it can be re-seeded from the clock at any moment, and that number should always be different every time it is queried.
@vxzcvz3 ай бұрын
i love how when a person thinks of how to generator random numbers, they instantly start off with circular logic
@eduardpaul84132 ай бұрын
Great Video! I used LFSRs to teach programming students random number generation and bitwise operations, never thought about an older system had to rely on these techniques for things now basically taken for granted. Excellent job!
@TRex-fu7bt5 ай бұрын
Nice explanation of rejection sampling! Intuitively, if we had to pick 1-4 with a 6 sided die, we could roll it and reroll if we got 5-6, and this is the digital version of that.
@NesHacker5 ай бұрын
Ahhh, I hadn’t thought of it the other way around with dice. Clever! 🤓
@krunkcleanup29495 ай бұрын
Division method can work with dice too. If you need a number between 1-3, you can roll a 6 sided die and divide by 2, and round up any remainder.
@General12th5 ай бұрын
This is my first video of yours. It was fun and educational!
@NesHacker5 ай бұрын
Welcome aboard!
@pierreolivierlepage6642 ай бұрын
I work in a field that use stimulations a lot. We generally store the random seed of a simulation's rng because we can then reproduce the entire simulation exactly with only the seed and the initial parameters.
@ericcooke26615 ай бұрын
I love your work. Being a trained Mathematician and Videogame enthusiast, I love hearing the back end grit of game design
@NesHacker5 ай бұрын
I’m a fake mathematician (read computer science BS😂)
@Fl3ck235 ай бұрын
Love your videos man! Look forward to every new one!!! ❤
@NesHacker5 ай бұрын
I’m so glad! Sorry they take so long these days 😆
@SneedFeedAndSeed5 ай бұрын
"All I have to do is find a very large prime number and multiply." - Bob Page
@Novastar.SaberCombat5 ай бұрын
Awesome to see a Deus Ex quote in here! 💪😎✌️
@vuurniacsquarewave50915 ай бұрын
Funny that the way I tested my RNG implementation was by writing the output to the $4011 register continuously at a decently fast rate to produce a sound with it. Since I pretty much remade what the noise channel does by default I heard the same white noise that repeats over a few seconds. But I never thought of rejection sampling, I was satisfied by masking off the bits and then looking for some value(s) to get chances of x over 2,4,8,16, etc.
@timseguine25 ай бұрын
When doing rejection sampling you can reduce the number of times you invoke the PRNG by keeping the bits you don't need in a buffer and reusing them. So for your example with a d20 since you only need 5 bits for each rejection sampling attempt, you can make 8 attempts with only 5 8-bit numbers. Because of the rate you have to try again for rejection (3/8) conveniently lines up, it means for a d20 specifically you will expect to need only one 8-bit random number on average for each dice roll if you use the random bits optimally.
@NesHacker5 ай бұрын
Oh that’s super smart! Thanks for sharing 😀
@pedro14925 ай бұрын
y u didnt call the video "randomNESs"?
@Deficard5 ай бұрын
cause they never thought of that
@joeboo86264 ай бұрын
Good play on words. He's probably more scientific than creative, would make a good Statistics teacher.
@RavenMobile3 ай бұрын
What I did when I needed to generate _sufficiently_ _random_ _numbers_ on a Linux-kernel based system: Get a bunch of dynamic content from the system that will be different every access (stuff in /proc/, such as uptime, RAM usage info, and various others, plus the output of dmesg, the date and time with microseconds, and various other system info and status commands), plus the previously generated hash, and a few random salt bytes (which I think I grabbed from the slow /dev/random on script launch). From this giant blob of textual data I used a hashing routine like sha512sum to produce a long string of hex digits. From this giant number I would use modulus to fit it into the small range I wanted. Using my RNG technique I spit multiple GB of random bytes into a file, then reported how many of each character was in the file -- it was almost exactly equal for each digit! It came out more accurate than all the well-known RNG algorithms, and was on-par with hardware chips. Of course it was not particularly efficient to run. It used plenty of CPU time producing the numbers. But for the task I wanted it for -- generating random hardened encryption keys in a particular way -- it worked great! Also, some will say it wasn't random because it is using fixed Linux kernel routines, blah blah, but with how many different pieces of the system I involved in producing the randomness, I don't see any way even an emulator could get it to repeat a sequence of numbers using my technique. It wasn't terribly slow like /dev/random, but just as random. I could produce around 200MiB/sec on my old computer, which at the time was faster than my hard drive could write the data out.
@PeetHobby5 ай бұрын
I made a short video about a 16-bit hardware pseudo-random number generator (PRNG) that uses two 74xx595 shift registers. It's pretty much like what you've explained here, but instead of software, it's all hardware-based. Is called an Xorshift PRNG, I think.
@NesHacker5 ай бұрын
Nice that’s a fun idea :)
@brandonr82692 ай бұрын
Wow, these videos are fantastic! I'm an Arduino programmer and it's awesome to see concepts from C/C++ in Arduino and what they have in common with Assembly in terms of their demonstrated applications in NES games. In Arduino, it's typical to just use a pin connected to the ADC chip to seed the RNG function and modulus math works fine as well. I'm doing my best to keep up with your videos (this one was a little easier for me - note, this isn't to say your videos aren't well explained, to the contrary, they're expertly explained; nevertheless, I don't grasp these concepts as quickly as others might since I have no background in computers at all, just what I had built myself through online learning) On to the next video!
@mithkabob4 ай бұрын
Good explanation of PRNG algorithms. FF1 NES actually doesn't use hardly any of these though, it has a set table of 256 values and cycles through them using the seed that increments once every other frame the menu cursor is visible in battle, and also every time it is used. To get random numbers for a given range, the function pulls the next value in the table, gets a 16-bit result by multiplying the 8-bit PRNG value by the 8-bit size of the range for results it wants, then takes the high byte from the 16-bit result and adds the minimum value in the range. If rolling a range, say from 20-30 it would take the next number and multiples by the range size (11 numbers from 20-30 inclusive). Lets say the seed pointed to 50 in the table, so would be 50*11 = 550 in this example, which has a high byte of 2, so we would add in the minimum of 20 and have a result of 22.
@johneymute3 ай бұрын
Creating different random numbers based on wich frame you start a certain game, is something very clever and well done to deal with such limited random combination of numbers on the nes or whether 8bit system. I personally always found those hammer brothers in SMB1 responding and appearing very random , as you would never know at wich alpatude platform they will appear because it could be the top, the middle or the lowest one,phew🤣
@Jerupitus4 ай бұрын
Great video, fascinating stuff
@logicalfundy5 ай бұрын
The ability for PRNG to get the same results if you use the same seed can be abused in some interesting ways - look at procedurally generated games like Elite from 1984, or for a more modern example, No Man's Sky.
@kanesmith82715 ай бұрын
Minecraft as well with the world seed generation option and people using it to dig for quick diamonds, or was that a lie?
@DobinSergei5 ай бұрын
Literally it makes possible to generate and store huge worlds with procedural generation algorythm. Storing RNG seeds for generating smaller chunk of world, and getting exactly same map every time. Instead of just generate and store all at once. Result is much bigger worlds with same hardware resources usage.
@kirishima6385 ай бұрын
Wonderfully explained
@UltimatePerfection5 ай бұрын
I am blown by the ingenuity of those early RNG systems that had to be seeded with user input because there wasn't any other source of randomness such as RTC (unless added specifically to the cartridge).
@PantlessSunshine5 ай бұрын
Fascinating video, thank you for going so in depth.
@BenMorse05 ай бұрын
4:17 depending on the taps the number of random numbers can be way less than the size of the container
@AlirezaR53 ай бұрын
Thank you sir. That was a really good video ! Well explained
@joshhallam22535 ай бұрын
I got that calculator in 7th grade when I started Pre Algebra. Then, i liked it so much, i bought it later when I was studying for the ACT. I moved and couldnt find it so i bought it a 3rd time in college. I love that calculator!
@madbr39914 ай бұрын
To get a number from 0-19 out of a range (0-255) while it could look sloppy it could work. Make a table with all 256 output values. Manually assign each value in the table a return value 0-19. The random munber from 0-255 gets compared to the table and the return value is the result. Add 1 to the return and you have your d20. It would probably just be more efficient to. Just take the 8 bit random binary. Ignore the 3 bits for (32 ,64, 128) read the remaining 5 bits. (1, 2, 4, 8, 16). And keep re rolling until you get a value between 0-19. Add 1 to the result for a D20.
@snoopy1alpha4 ай бұрын
The first iteration of the Nintendo DS always picked the same seed. In games like Puzzle Quest you always started with the same board state. In games like "Deal or no Deal" (or whatever the game is called in the US), the maximum win was always in the same suitcase for the first game. On the Gameboy button presses where also considered for RNG. That's exploited for RNG manipulation in Pokemon Red/Blue/Yellow and probably also Gold/Silver speedruns. E.g., with this technique you can easily manipulate a male Nidoran (in Red) with (almost) perfect stats to be used during the run. And when believing Kosmic in his Mario speedrun videos for Super Mario Bros. and "Lost Levels" on the NES, the "wait until Press start", that was mentioned in the video, can be important for certain patterns in later levels of the games.
@lean.drocalil5 ай бұрын
Super great content as usual!! 👊🏻
@NesHacker5 ай бұрын
Appreciate it!
@rai_bug4 ай бұрын
I love this video it helps me understand random numbers much more
@psyhodelik5 ай бұрын
Great explain !
@kleytman5 ай бұрын
What's more fun than maths + algorithims + viedo games! a good of explanation of all this
@NesHacker5 ай бұрын
Thanks so much, that’s really my goal: talk technical while trying to keep things accessible 🙂
@just-mees5 ай бұрын
I love it when games have rng systems that are easy to guess and exploit. GBA Fire emblem's rng system is derived from the cursor's movement and it's movement arrow's direction, which means that with savestates you can rig anything just by wiggling the cursor around a bunch Edit: it's actually.. not that. Pathing a unit's movement is done when you move the cursor and this requires a call to randomness so your unit realistically pathfinds around obstacles and units which causes a shift and changes every subsequent random number generated. Shoulda googled it
@ItsHyomoto5 ай бұрын
I appreciate the comment about predictability being desirable. It's very common when people start making games to obsess over how random random is (because they see the effects directly) but will inevitably move on to more controlled randomness as more random is rarely more fun. Don't believe me? Procedural generation is all about making random numbers into something discernable, a Minecraft landscape for example. Now imagine that nice landscape is your chance to hit in an RPG and you'll start to notice what you want is not truly random, it's curated.
@iLLadelph2674 ай бұрын
this reminds me of the exploration Veritasium and Vsauce did a few gears back exploring random vs truly random. in short, no macroscopic natural process is truly random since knowing the initial conditions to a system and its properties theoretically makes it perfectly predictable. really hard to predict, but in theory not *truly* random. the only truly random systems we've discovered are quantum processes which have no discernable way to predict an outcome thanks to the ol Heisenberg Uncertainty Principle: the more you know about one part of a quantum process, the less you know about its other parts. which is one reason quantum computing is a big field of research. almost like a holy grail of encryption awesome video! now i wanna know how modern game consoles took things further than just using bigger numbers and faster processing
@safebox364 ай бұрын
I kinda link when the randomness can be predicted / calculated. It's why I'm looking at putting "fixed" RNG in my game using the same algorithm the early Pokemon games used. So players can figure out what the next number will be if they know what's going on.
@rileytempest6665 ай бұрын
thanks for description references
@tylerbowling5 ай бұрын
This reminds me a lot of the birthday paradox. Thank you for this.
@arnpoly5 ай бұрын
Another way to get a value in a range is to multiply the random 8-bit value with the top of the range (e.g 20) to get a 16-bit result where the top byte is between 0-19. Multiplication is still time consuming but on the whole faster than division on the NES.
@TheUglyAnswers3 ай бұрын
Great video, great channel find!! Keep it up, my friend! ❤️
@rtyuik73 ай бұрын
i forgot if it was iTunes or Spotify or whatever, but the story im trying to retell is that a Music Library had a lot of complaints from users that its "Shuffle" function wasnt Shuffling properly-- sometimes itd play the same song again, or would play more songs from a particular album or artist out of a much wider mix...so the Provider of that library (ie, Apple, if it was in fact iTunes) had to tweak the code, to make it LESS random...because it was actually Already Performing close to a "true random" playlist, but end-users dont realize that "true random" would mean some Repeats, or heavier distribution along a small subsection, so in order to "look" More Shuffled, they had to make it Less Randomized...tweaks like "blacklist recently played songs/albums/artists from queueing up as Next" for example...
@JacksonParodi5 ай бұрын
very nice
@NesHacker5 ай бұрын
*tips hat*
@alexismandelias5 ай бұрын
3:43 I didn't quite understand this part: "Every time you perform this process you generate one random bit, repeat it 8 times and you get an 8-bit byte. This allows you to create all 256 8-bit numbers." My question is how you can be sure that this process generates all random numbers, and doesn't just generate, let's say, 10 in a cycle?
@desertdude5405 ай бұрын
In general, it's not guaranteed. There are, however, feedback arrangements that are known to produce maximal-length sequences. You can search the web for "linear-feedback shift register" for more information.
@SianaGearz5 ай бұрын
It will occasionally generate repetitive bit patterns but kick itself out of it because of how the feedback function is chosen. Ultimately a run of repetitive bits isn't more or less likely than a run of "random" looking bits. The feedback function is chosen to have a maximum length sequence property, so every time it runs through until it repeats, it generates all the states once, basically providing a permutation of the number space, this is how you know it's not going to get stuck generating the same output all the time. There's basically a handful of known good feedback functions.
@NesHacker5 ай бұрын
I think the proof has some deep ties with modern algebra and field theories. While I’ve taken a course in modern algebra 20 years ago I definitely don’t know it well enough to provide a proper proof. Though it does sound like a fun thing to do when on vacation sometime 😂
@crungushakooter5 ай бұрын
I don't have the answers as I don't fully understand the deeper math myself, but it has to do with Galois theory and primitive polynomials if you want to look into it further. Basically your choice of taps has to represent a primitive polynomial, which I believe means you need an even number of entries and they must be co-prime (here I believe that refers to the bit positions). Satisfying these conditions means, and here I get real hand wavey, that you can represent the entire space in terms of the polynomial? Similarly to how the span of a basis defines a vector space, ie the full space is defined by all possible irreducible linear combinations of the given polynomial. Or something like that. And the shift operation here is you stepping through each possible combination in your finite space, ie given a good starting point (primitive polynomial), you represent the entire space. A bad pick for the taps would have you spinning your circles and repeating some entries while skipping others
@kingdomheartslpfan12865 ай бұрын
Very clear and thorough explanation. Do you have any plans to talk about how sound works with the NES? In my opinion, that would be a fun video
@mattwillis32195 ай бұрын
Awesome preamble to the id fast inverse cube root, love this bit shifting binary maths :D
@r.g.thesecond5 ай бұрын
Nice camera work on those TVs! Can't tell if it is a 3D render or actual filming, but it looks great either way.
@NesHacker5 ай бұрын
"IT'S A SECRET TO EVERYBODY" xD
@________Cj_________5 ай бұрын
5:42 the lick
@alexlouismusic4 ай бұрын
Lick confirmed
@fargoretro5 ай бұрын
This video ruled!
@Landrew03 ай бұрын
The best way to get a truly random seed, is to measure the time from startup to the first user keystroke in microseconds, and convert that time to a seed number.
@civrev5 ай бұрын
Cool channel. Subbed!
@NesHacker5 ай бұрын
Thanks! I appreciate it 😀
@Daniel15au5 ай бұрын
On systems with a real-time clock, they often use the current date and time as part of the seed. That's usually how it was done in DOS games for example. On modern systems, you'd just reuse whatever your programming language provides, as all standard libraries have support for random number generation.
@Seumu9905 ай бұрын
I face same problem in arduino exsam. I made crystall ball and its start always in same answer. Then i learn what is pseudo rnd. The solution was to tie the seed number to the analog input, that gave good result 👍
@PSL19695 ай бұрын
I love 6502! Great epsiode! I'm fiddling with some PRNG on C-64 right now.
@NesHacker5 ай бұрын
Nice, the code from the example project should work just fine on C64!
@PSL19695 ай бұрын
@@NesHacker Yes indeed. I ended up using something very similar 👍
@petermuller6085 ай бұрын
Great explanation!
@Hersatz5 ай бұрын
That food mnemonic for exclusive or is so good. Can't believe I never thought of it that way. No food on either side? Can't choose any. Food on each side? I can't decide, there's too many choices!
@akko82105 ай бұрын
I always wanted this video!
@NesHacker5 ай бұрын
And now you have it! Glad I could deliver 🤓
@tur13l5 ай бұрын
Great! Now all we need is some maniac dedicated enough to make a 5e d&d tactical game on the nes :D
@NesHacker5 ай бұрын
Don’t tempt me.
@ListersHatsune4 ай бұрын
Right, that's a much better way of doing it than I used in university. We were programming on GBA and were told that it didn't have rng like a pc did but because of the bias caused by the modulus division I ended up with really predictable rng.
@Daniel_VolumeDown5 ай бұрын
2:01 They don't need to repeat. Simple example is calculating decimal expansion of pi - it never repeats. Another example is I think in video made by veritasium titled " This equation will change how you see the world (the logistic map) " about deterministic chaos but I am not fully sure
@ButteredToits-4 ай бұрын
This was awesome
@LukeAvedon5 ай бұрын
Fascinating topic!
@Novastar.SaberCombat5 ай бұрын
I always enjoyed games where the RNG was the most unpredictable. It made it so you couldn't simply "go on autopilot" and repeat the same inputs just to force the same results. Sure, speedrunners can usually find ways around this, but to a casual gamer, excellent RNG is "truly" random. 🙂
@Bethos1247-Arne4 ай бұрын
did you check if you get an even distribution with this method?
@OriginalSebie5 ай бұрын
I tried this but got different numbers? From 87 [01010111] shifted to 43 [00101011], since we removed 1 from end, did 43^184 (or [00101011] ^ [10111000] in BIN) with result of [10010011] = 147 🤔 next from 147 [10010011] shifted to 73 [01001001], last removed bit was 1, so [01001001] ^[01001001] gave result [11110001] = 241 .. So instead of sequence 87, 192, 201, 55, 32, 173, ... I got: 87, 147, 241, 192, 96, 48, 24, 12, 6, 3, 185, 228, 114, 57, 164, 82, 41, 172, 86, 43, ... and so on. Am I doing something wrong?😮 The sequence repeats itself after 255 values as there is no 0 (as explained in the video). Two annoying things about this generator: - even numbers get just shifted to right and therefore create very recognizable patterns of descending values in the sequence.. - sequence repeats itself with same numbers, so after a specific value you will always have the same next value as in previous run Maybe this can be fixed by getting not only "random" seed, but also "random mask" for XOR operation?
@Dimitri_gdr4 ай бұрын
I got the same result as you, I don’t understand what we are doing wrong 🤔🤔🤔
@lost505 ай бұрын
another good seed or way to get a RN is to incorporate the x or y position of the player at any given time.
@golvellius68555 ай бұрын
❤the explanations
@NesHacker5 ай бұрын
Thank you very much, I spend many many hours working and reworking my scripts to try and make each segment as accessible as possible 😊
@Xanadu325 ай бұрын
I've been programming for the nes for the last few years and random has always been a tough topic. But ill definitely be using the sample rejection method moving forward. Maybe pair it with a for loop to prevent an extended reroll time
@jonopens5 ай бұрын
Is that a Berserk sacrifice brand on the headband on your t-shirt? Because if so, that's awesome.
@CoolDudeClem5 ай бұрын
in my dyslexic mind I read the title as "RING on the NES".
@joyxcore25 ай бұрын
Random numbers do follow a random pattern, it's not predictable but it's certainly a pattern.
@wildside48225 ай бұрын
great video thanks
@ilenewright24635 ай бұрын
Very interesting and affirming of questions I had. Also makes me realize how smart I am not lol. Too many variables for me to keep track of and it gets confusing
@timonus5 ай бұрын
Great vid!
@dukemagus5 ай бұрын
I thought NES devs saved some cycles by embedding tables with numbers on a seemingly random pattern and a counter that would cycle through it so fast that when it needed to select a number, it would look "random enough" with almost zero math operations involved. Speedrunners might break the pattern due to how fast and precise they are, but for the average player, looks random enough.
@NesHacker5 ай бұрын
I think Zelda does something similar to what you’re describing.
@Novastar.SaberCombat5 ай бұрын
Correct. That is why hints like "10th enemy has the bomb" and other forced results always occur. 💪😎✌️ Additionally, enemy movement is almost always influenced by the player's inputs. In other words, if you're holding L, R, U, D, or "A" or "B", etc. However, there's SOOOOO much going on that not even speedrunners can force absolutely every behavior on every single frame, room, scenario, etc.
@deanmoore-TSB-andgamesetc5 ай бұрын
That 20 sided die is used on Dungeon and Dragon games is there any D&D games for the NES I know Zelda can be called a D & D game kinda is there any more ?
@NesHacker5 ай бұрын
There are d&d games for the NES! Check this Reddit post out for more details: www.reddit.com/r/retrogaming/comments/8o4e8u/advanced_dd_nes_games/
@lindoran4 ай бұрын
I recommend you look at George Marsagela's paper on the xor shift algorithm. This could be implemented at any bit depth and produces a very large sample space while using no arithmetic operations simply bit shifts and logical xor. This is absolutely producable by using a memory location and a battery backed ram. It's a shame the paper wasn't published until 2003, this kind of algorithm would have been formative If used in the 1980s for video games or cryptography.
@blemisheddiscgaming6464Ай бұрын
100k! Woooo!
@sanderbos42435 ай бұрын
Great video!
@gsestream5 ай бұрын
yeah you can measure the button press time to get the random noise value of the player
@Arae_15 ай бұрын
On the topic of random, cloudflare uses a wall of random lava lamps to get information
@hansisbrucker8135 ай бұрын
I was looking for a way to more smoothly scale 0..255 to 0..20 after watching this video. ⌈20×tanh(x/128)⌉ where x is between 0 and 255 and ⌈⌉ means the ceiling function seems to produce a nice smooth (as smooth as integers can be) curve. 🤓 Having said that I do realize it would be absolutely slow on that (or any) hardware 🤔
@Mireneye5 ай бұрын
For whatever reason the moment you touched on division not being a thing on the NES. I was like, what about bit shifting to the right? And I was so sure the video would go there haha. Should be a fast way to get it down to the right range? Genuinely wondering, still so much to learn.
@f.berger77565 ай бұрын
On other systems I programmed on I took the current position of the raster beam of the television for the seed. Wasn't that possible on the SNES? I mean having a register to read out that kind of information?
@system64_MC5 ай бұрын
Fun fact, the 2A03 (NES' soundchip) also uses LFSR to generate its noise
@NesHacker5 ай бұрын
Sure does! I think a lot of synth chips did that back in the day, which is rad. I’m curious if something like the original Roland 606 drum machine uses an LFSR for its probability feature 🤔
@iyatemu5 ай бұрын
And other chips like the Atari POKEY and MIKEY used LFSR to generate *everything*