Continuing from my previous post on randomness, I’d like to talk about non-uniform distributions, which certainly don’t get all the love they deserve. When people talk or think about randomness in games, they commonly think about fair distributions. And I know we spent a lot of time in Part 1 actually trying to achieve perfect uniformity because it brings “fairness” to games, but in reality, there are cases where you don’t want your random events to be ruled by a “fair” distribution at all.
Reality Check #4: Sometimes uniformity is bad
Fun fact: For a lot of “random” events in nature, every possible outcome rarely has the same chance of occurring, so perhaps trying to achieve that uniformity in games could be a mistake to begin with.
Let’s take rabbits for instance.
If you observe the population of rabbits of a given area, you’ll notice that they’ll have a”typical average size”. Let’s call that size X. You’ll find that most rabbits in the area will be around that size. There will be a rare few that are either considerably smaller than X or considerable bigger (outliers), but for the most of it, rabbits will be “just around” X in size. Same goes for any other quantifiable trait that depends on enough factors to be considered random.
They will most-likely follow what is called a Normal (or Gaussian) distribution, which is said to appear in nature all the time. The function that defines this distribution is also called the Gaussian Bell, due to the shape of the curve.
DISCLAIMER: This is a rather long post on the topic of random numbers, so …uh, sorry for that.
I want to talk about a couple of interesting things related to randomness and its many nuisances especially when applied to games. But before we get to that I guess I’ll introduce the basic notions for those of you who are not familiar with this whole thing. You can skip the first two sections if you know what a PRNG is, and how it works.
What is Random
Random is commonly defined as “unpredictable“. In general, when we are unable to find a pattern that would allow us to anticipate the outcome or occurrence of an event, we call it “unpredictable” and there’s a chance we will consider the event “random”.
You’ll also hear of “true randomness”, and things like natural atmospheric noise, lightning bolts, or particles falling from the space being used as sources and examples of it. But while we can’t currently predict when and where lightning will hit, events in the universe like electric discharges in clouds are most likely just a massively complicated function of a number of different factors, and not really something that happens with no rhyme or reason. It’s quite possible that if we were able to simulate each particle and sub-particle inside a group of storm clouds and their relevant vicinity, lightning would be trivial to anticipate with accuracy. This makes its “unpredictability” debatable, I guess.
Having said that, let’s not forget that “predictable” and “unpredictable” are relative to an “observer”. What we consider true random events could totally have a logic behind, but what matters is that from our -and our system’s- point of view, they are impossible to predict, and if the machine (or person) is unable to anticipate the occurrence of an event, the definition applies, regardless of the event’s “actual” predictability.
Not long ago I purchased a few 320×240 touchscreen displays from ebay that looked pretty decent and were also fairly cheap. They conform to the Arduino shield form-factor, so they snap directly onto any standard Arduino board, making them really easy to test and use. They also have an integrated microSD slot (connected to the same bus used by the display controller) which is a nice touch and widens the number of possible applications for these modules.
As seen on literally every eBay listing that sells them.
Of course the displays didn’t come with any code, and the most reasonable thing you’ll find online to make them work is Adafruit’s TFT-LCD Library, which includes support for a number of different controllers, and is fully compatible with their very own and versatile GFX framework.
I wanted to add a temperature sensor to a project I’m working on, and while I already had selected the perfect IC for the job, I decided to test a couple of other options I had, to see how they fare in comparison. I was originally going to compare only 3 sensors; the popular LM35, the not-so-popular LM335 and the kinda obscure TMP75, but as I started writing this post I remembered I got a Dallas DS18B20 as part of kit of sensors, so I added it to the mix to balance the digital-to-analog ratio of this comparison.
The original 3 sensors I was going to test.
Ok, so this is probably the last post I’ll make about my Brainfuck-on-Arduino project, basically because it has reached a point where I’ve already tried all the things I wanted to try and I’ve decided that there’s no point in taking it out of the breadboard and build a board for it. At least not for Brainfuck. And I’ll explain why.
The Performance Issue
I previously said that I was expecting the performance to “drop” a bit when reading directly from a SD card instead of the internal RAM, but I was hoping to mitigate that with a sector/block cache similar to the one I wrote for the SPI RAM.
And that’s completely reasonable and actually true. Where I made a mistake however, was in also assuming that doubling the SPI clock would result in a noticeable performance boost. That’s definitely false. Reading a whole 512bytes sector currently takes between 1 and 2 milliseconds at 4Mhz, and RAM access is done at the same speed, so being the RAM pages half the size of the SD sectors it probably takes half that much to get a whole RAM page.
Since we are caching so many bytes in advance, the number of page reads (both from RAM and SD) is not really that high, so even if we were to double the SPI bus speed we will only cut around 1ms from each access. Most programs I’ve tested don’t normally cross the RAM page boundaries nor require more than one SD sector to be stored, so the speedup won’t even be noticeable for most cases. It will be barely 1 or 2 ms, so if we run into performance issues, they are somewhere else. They are NOT in the SPI Bus speed.
DISCLAIMER: Over the course of this post I’ll be dealing with parsing, programming practices, code refactoring, SPI bus oddities, caching techniques,etc. It’s a mixed bag of things and it’s far from being serious analysis on the topic of optimization. Please don’t expect anything particularly smart in this post like branch prediction, overlapping cache windows, partial block reads, etc. This is just a chronicle of sorts, of the things I’ve done over the past few hours to improve the performance of my Brainfuck-on-Arduino interpreter, which was being painfully slow.
So in my previous post you hopefully got a glimpse of my current project: a Brainfuck interpreter running completely on Arduino. Something that I forgot to mention is that all the input/output (for testing purposes) currently happens through a serial connection. I’m using the “Serial Monitor” console that’s part of the Arduino IDE to “talk” with the board and run the code.
I’d also like to point out that I’m using an external 23K256 chip for the Brainfuck data space, This is basically a 32KB RAM IC that is accessed via SPI (Serial Peripheral Interface). This is relevant for some of the optimizations I’ll do next.
So I’ve been fiddling a lot these days with Arduino’s SD Library. I’m doing experiments with SD Cards as part of my BOA (Brainfuck on Arduino) project and I already have a completely functional Brainfuck interpreter that runs on my Pro Mini board and uses a 23K256 (32KB) SPI RAM as BF “RAM space”.
The problem I’m trying to solve now is PROGRAM space (where the actual code will reside). So just for the kicks I”m testing SD Cards as a first “storage” alternative (after all it’s cheaper than EEPROM ICs and offers way more space than the few KB you’ll mostly get from EEPROMs).
I was pretty excited when I learned that Texas Instruments has a line of cheap & open-source development tools for their MSP430 microcontroller family (10 years ago they only offered ridiculously overpriced proprietary tools). They apparently created this new line of programming hardware back in 2010, so I ordered one of their Launchpad boards the other day, which is a MSP430F5529 evaluation board AND an EZ-FET Lite programmer all in one.
Fun in a box.
It was seriously cheap, really. $12.99 USD including shipping (and there’s a cheaper one for $9.99). This is insane considering that their traditional devkits cost over $200.
As I said before, this board not only has a MSP430 processor you can play with (and attach tons of modules, sensors, etc in a very Arduino-like fashion) but also has and on-board programmer and debugger that can be “isolated” and used to program any external MSP430 microprocessor with the Spy-bi-Wire (SBW) technology.