Lately, I've been exploring NES development (yes, the OG Nintendo). This has led to quite a few insights on what can be made easier, what I should focus on in Foxie, and what should be kept "standard".
First, I should note: I've been playing "the Nintendo", as I've called it since childhood, since I was able, around 4 years old or so (I wasn't any good, but still). It was my first console, my first exposure to video games, Super Mario 3 in particular. It has a special place in my heart, so to be able to create a game for this surprisingly powerful little engine is, in short, a dream come true.
Enough dreaming. So what can the NES do??
First things first, this thing was (obviously) made for making games. This may seem like a tautology or redundant statement, like "freezers are for freezing things".
But no! The NES was designed from the ground up to make it easy to get something on the screen, sing an 8-bit tune, read from controllers, and do other things that game devs on a regular ol' computer of the time would've found more difficult. The Nintendo was a labor of love, clearly.
How does it do this?
The most notable things about the Nintendo design are its PPU, or Picture Processing Unit, and the APU, the Audio Processing Unit. Now bear with me, because I'm still learning how the system works, but these units are basically memory mapped so the CPU, a good ol' 6502 (with BCD disabled), can access the memory with standard instructions.
This leads to my first insight:
The system should offer special facilities for video, audio, and interactivity, but it should do so with standard constructs (like say, special functions that are called, data structures that can be used, etc.). I don't need to reinvent the wheel, just because I'm creating a new language.
Sure, it would be fun, to invent new concepts or try obscure constructs, but it would take a lot more work, for me, and for whoever's learning it and trying to use the thing...
Anyway, back to the NES. It has some pretty ingenious methods for getting around some of the limitations of the 6502-clone CPU powering it.
Speaking of the 6502, it feels absolutely incredible to program an assembly-based system, after years of complicated web software.
I believe it was Les Solomon, in Steven Levy's Hackers, who said programming is enjoyable because it's deterministic, because "the bit is there or it ain't there". These days, it's harder to tell where the bit is and how it got there. Hell, we don't even deal with bits anymore – we're so far removed from the systems we're controlling, we have no idea how they work.
This should be a good thing. In my day-to-day, I don't really care about the bits underlying a web request, for example.
However, it becomes an issue, covering up those bits, when the abstractions underneath are "leaky" or broken. When that happens, you're kind of screwed when things go wrong. See: Rails "magic" and trying to customize its behavior beyond the bounds set by its developers. 😱
I'm starting to think I'd rather be programming 6502s all day. 👀 But I digress. The point is, 6502 is simple at its core, and fun, believe it or not! I'd highly recommend you try it for yourself.
This leads to the second insight from the Nintendo programming adventures: programming in Foxie, making a game, should be fun, first and foremost. Forget about functional programming paradigms and tail recursion support and all that garbage – I don't care. 😐
What I care about is people having fun making games that they can get working quickly, and finish end-to-end with Foxie. That's all that matters, the use case. The rest? That's just my traditional-CS-trained-brain saying "oh you need X, Y, and Z because [insert obscure CS theory that doesn't really matter]".
I expect some of you will recoil in horror at the thought of a language that say, only has global variables, or doesn't have dynamic scope, or something else that doesn't matter to my end user. I don't care.
That's the third lesson, really. Don't make things that ultimately don't matter (that could actually apply to a lot of things in programming, and product development in general).
For example, what does it matter if the user can say, use tail recursion, if they're forced to write data to the screen one byte at a time instead of in batches, as the NES PPU allows? Or if they have to define every point in the amplitude of a discrete audio signal, instead of just defining the shape or envelope of the damn wave?
Some say, "make easy things easy and hard things possible". This only serves developers and their needs. I say, "no, make important things easy and necessary things possible". That matters a lot more to your users.
What was I talking about...oh yeah, Nintendo programming. It's fun. You should try it. In fact, I'm going to get back to it, enjoy the rest of my Sunday...until next time, enjoy an 8-bit rendition of one of my favorite metal tunes.