EDIT 1: Forgot to finish a certain thing. Also, added one more consideration to group 2, and a consideration to group 1.
For the charity game jam (and apparently there isn’t a blog category here for that, I have no idea why), you will be making a “NES-like” game.
But wait! Before you open up Musagi and turn the reverb up, consider actually doing it properly.
I’m not saying you should quickly download WLA-DX and make a game with it. What I am saying, however, is you should at least make a decent attempt to stick within the limits. There’s no point making it vaguely like a NES and then throwing the palette out altogether and having 256 different colours in a 16×16 area and smooth-as-balls non-dithered gradients, when this is the perfect opportunity to actually stick to at least some of the limits.
So here we go. I’m going to categorise these into groups.
Group 1: The bare minimum
This is what you can easily achieve if you actually try.
- Stick strictly to the NES palette. Really, it’s not hard. You have 56 unique colours to work with, plus you can dither stuff to some extent.
- The tile layer consists of 16×16 tiles (technically a 2×2 group of 8×8 tiles), each consisting of 3 colours + 1 transparency colour. Note, some mappers allow grouping these as 8×8 tiles, although I recommend you go with 16×16.
- The tile layer is scrollable in all 4 directions.
- Sprites are either 8×8 or 8×16 (note, this is a global flag, either all are 8×8 or all are 8×16), and each sprite consists of 3 colours + 1 transparency colour. If you want bigger sprites, or more colours (don’t go overboard with this, please! 2 should be enough), stick a bunch of sprites together.
- Sprites can be flipped horizontally/vertically in hardware, and can be set to either go in front of the tile layer or behind it.
- There is a background colour, which you can set to anything in the NES palette.
- Feel free to consider scanline effects, but don’t go overboard! Something as simple as changing the background colour (or all the colours, typically making everything the same colour) at a few points, or making only the middle of the screen scrollable (although in those cases you shouldn’t scroll vertically!) could work. Take a look at actual 2nd/3rd/4th gen games and see how it’s done.
- Audiowise, you have 2 pulse waves (either 50%, 25%, or 12.5% duty cycle), 1 triangle wave, 1 noise channel (either “periodic noise” or “white noise”, if you’d like to be precise see here), and 1 DPCM sample channel. Please use the crap out of these! Check Group 2 for some stronger restrictions you may wish to consider.
- There are also some audio expansions you might want to consider, for instance the wonderful VRC6 gives you 2 pulse waves (1/16 through 8/16) and 1 sawtooth wave, but if you use them, use the crap out of them!
- NES/Famicom audio doesn’t actually have stereo support, but for Group 1 you can ignore this fact.
- Consider using a 60Hz (or 59.97Hz if you feel like being anal) base clock (divide it how you like, I suggest 30Hz if your game making program isn’t exactly the most efficient). PAL timing is OK but be warned – there are a lot of differences between the PAL and NTSC versions of the NES/Famicom that you might as well just go with NTSC to keep it simple.
Shouldn’t be hard if you actually try, although some of you might get stuck for a few minutes with some of the limitations.
Group 2: The recommended courseload
This is what you will achieve if you actually care.
- Each 16×16 tile can use one of 4 3-colour palettes (editable), and each sprite can use one of 4 3-colour palettes (also editable). Each of these palettes take colours from, you guessed it, the NES palette.
- You can have only 64 sprites on-screen at a time (scanline hackery MAY allow for more but don’t bank on it). Note, this does not need to be a strict limit, but don’t spam over 9000 sprites.
- Consider this, but you don’t need to enforce it: You can only have 8 sprites which have pixels (even transparent ones!) on a single scanline. (The hardware behaviour, if you’re wondering, is to draw the “topmost” 8 for the scanline, and discard the rest.)
- Consider this too, but likewise you don’t need to enforce it: Your tileset consists of 512 8×8 tiles. For each of these, the first or last (globally settable) 256 tiles can be used for the tilemap. A 16×16 “tile” consists of 4 of these tiles in a 2×2 arrangement, which can be any combination of those 256 tiles. For 8×8 sprite mode, either the top or the bottom (also globally settable) 256 tiles can be used. For 8×16, you can use any even-odd pair from the tilemap. Vertically flipping the sprite will flip the whole sprite as a unit, and not just the individual tiles, which is a good thing. (EDIT to clarify: Yes, you can assume CHR-RAM and edit the whole tileset.)
- Consider this also: You can only write so much to the video memory per frame. Try not to replace the whole tileset during vblank!
- Musicwise, you are ONLY going to use the 5 channels indicated, optionally adding whatever expansions you want to squeeze in (USE THE CRAP OUT OF THEM IF YOU USE THEM, I CANNOT STRESS THIS ENOUGH). For this, you will need to stick within the note limits. My advice, just get FamiTracker (or anything that spits out a playable .nsf for that matter, I tend to use s3m2nsf myself, although pcmnsf/supernsf is somewhat cheating here).
- Audiowise, use one (or, if you must, two) of those waveforms for each sound effect. You can layer them over the music instead of replacing what’s playing in the channels, if you like. Please stick within the note limits for this, too.
- The pulse channel note limits are either ~110Hz or ~55Hz (I think there’s a mode that can get you down to ~55Hz but I found that I could only go down to ~110Hz for some reason) for the pulse waves – this is A-2 or A-1. Feel free to assume the latter.
- For the triangle channel, either A-1 or A-0, I’m not sure. Also, the triangle has 2 volumes: “On” and “Off”.
- For the noise channel, there’s 16 discrete frequencies. See here for more info.
- For the sample channel, same deal with the 16 frequencies. See here for more info. Also, like the triangle, there are 2 volumes here, too! Finally, the outputted waveform tends to sound like crap. Sorry, guys!
This is really what you should attempt, unless you speak 6502 assembler.
Group 3: “Head Trauma” all over again
This is a stupid idea and you should just skip to Group 4. I basically did this for my first ever LD (#18, although for the Sega Master System, which is better, so ), and wasted over half the time getting the half-baked emulation right.
- Graphics and audio must be completely accurate ignoring any weird signal degradation / filtering / whatnot, and possibly ignoring some of the finer quirks.
No really, I’d rather code in 6502 asm, thanks.
Group 4: NES-like but without the “-like”
This is what you will achieve if you want to soil your pants at what you’ve managed to achieve in 48 hours. This is much more achievable than it sounds at first.
I’ve done this 3 times. Twice for the Sega Master System, once for the Sega Mega Drive. I also have some base code for the NES but it’s very minimal.
But yeah, seeing as you’ve been given this opportunity, you might as well make the most of it. I personally recommend Group 2, although if that’s a bit too tough, Group 1 should do.
Remind me and I might release a modified atrk-bu.py or an atrk2nsf thing or something like that.