I've been working on this game for about 6 months, on and off. I just graduated college, so I'm back to working on it. It's using the Kirby's Adventure cart (MMC3 512K PRG, 256K CHR) for maximum graphics space, but I don't intend to ever make cartridges because of copyright issues.

It's a demake of Super Smash Bros. for the NES. The character roster is all Smash Bros characters who had NES games:

Mario, as seen in Super Mario Bros. 3

Green MarioLuigi, as seen in Super Mario Bros. 3

Peach, as seen in Super Mario Bros. 2

Kirby, as seen in Kirby's Adventure

Link, as seen in Zelda II, Link's Awakening

Samus, as seen in Metroid

Mega Man, as seen in Mega Man 1-6

Marth, as seen in Fire Emblem: Ankoku Ryuu to Hikari no Tsurugi

I have a working game engine with platform collisions and a lot of art, but that's about it so far.

I want to stay true to the style of the original games as much as possible. However, Samus and Marth were designed for pure black backgrounds, so I had to modify their sprites quite a bit. Working around the NES limitations, I came up with this scheme:

The palettes are allocated like this:

Palette 0: Player 1 colors

Palette 1: Player 2 colors

Palette 2: Player 1 accent color, Player 2 accent color, white

Palette 3: Black, item accent color, white

This means that the player sprite could use 4 arbitrary colors plus black and white, without affecting the other player. For example, Mega Man's face uses palette 2, for tan skin and white eyes. Marth's sword uses palette 3 for black and white. If it doesn't create too many sprites per scanline, he may also have light blue accents. The accent sprites need duplicates for player 1 and player 2 versions. Sprites have two layers, but otherwise the ordering is undefined.

The MMC3 can bankswitch 4 separate banks of the sprite tileset. Each player gets one, the interface elements get one, and the current item gets one. The stage can also bankswitch its halves to have animated backgrounds.

There are a lot of graphics that need to go into the game. I manually created metasprites for all of Peach's frames with a tool I created, but that's a difficult process. I draw the characters in a graphics program, so I need to separate each frame into sprites, eliminate duplicates, define the position and attributes of each sprite, etc.

I have automated a few things: every image I want to convert to NES format has an extra row along the top for palette information. The first 4 pixels define a palette. I automatically map the RGB color to the nearest NES color in a LAB color space.

I use Aseprite to create the animations. This lets me use layers and assign tags to frames. Aseprite converts the .ase file into a sprite sheet png and JSON file with information about each frame, layer, and tag. Certain names are special: the layer name "Accent" will have the accent palette, for example, and the frame tag "Common" can contain projectiles which should appear in each of the player's banks.

I'm working on turning that information into metasprites and image data. Each frame can have multiple layers, and I need to find a good decomposition of them into 8x16 sprites which minimizes the number of sprites total and number per scanline. I don't even care about getting an optimal solution, but getting a good one is hard.

On your palette setup, one thing you could do for projectiles is flicker between palettes for unique colors. A good example of this is Rose's fireball in Street Fighter Alpha Game Boy Color: https://www.youtube.com/watch?v=kiZgy8Vv1xo (1:37). Of course YouTube is affecting the framerate here, but for fireball effects it can work quite well.

As for the project title and legality, you should look at Super Smash Land by Dan Fornace. One nice thing about that project was the unique title. I think you should consider a sub-title or changing it up a bit, like: "NES SMASH BROS", or "SMASH BROS ZERO". Maybe if you used unique art it would be less likely to get shut down too. But I see that Tepples isn't complaining, so you must be doing something right.

I have to be honest here; I do not like seeing the word Zero on any completed game title, where Zero is the chronological number in the series of games. I remember reading lists of games in development that had these in their working title, and they were always sure to change...

but one studio decided to break convention, and ever since then it became a trend.

Street Fighter in Japan goes Street Fighter, then Street Fighter Zero, then Street Fighter II in story order. In North America and Europe, it makes slightly more sense: Street Fighter, then Alpha, then II. (II was released before the interquel Alpha.)

tepples wrote:Street Fighter in Japan goes Street Fighter, then Street Fighter Zero, then Street Fighter II in story order. In North America and Europe, it makes slightly more sense: Street Fighter, then Alpha, then II.

And then it all goes down the drain anyway when the sequels for SF2 go in the following order: 4, 5, 3.

I now have a system that converts my animations in aseprite to chr files and metasprite definitions. I spent a long time trying to optimize the conversion, but it is a difficult computational problem. My first try at mostly brute force worked great for images that need at most 3 sprites, but 4 sprites took ~3 minutes. Exponential growth is no joke. So, just to get things going I made the simplest solution that could work: each metasprite is a non-overlapping grid of sprites, aligned with the top-left edge of the image. I don't do any deduplication of images either. This will cause it to use a lot of chr space and a lot of sprites on screen at once, but I can always optimize it later. For now, my 256K of chr space makes it a non-issue.

My metasprite definitions are pretty simple. They are a list of 4 bytes sprites, in a similar format to the oam memory, but in a different order. The bytes are attribute, x, y, and tile. The attribute byte is first as a marker: I set bit 2 of each attribute byte, which is otherwise unused. I know when the metasprite is done when I find a byte equal to zero, the null terminator.
I will need to add a header to the metasprites though. It will include the bank number of the chr data and pointers to the palettes it uses, most likely.

I have the ability to perform a lot of updates to the PPU each frame. I don't use it for much now, but I think it will be useful later on. I use the trick of putting all the data to draw on the stack and performing a bunch of pla, sta PPUDATA operations for general drawing. I also rewrite all of the palettes every frame using self-modifying code. I have a routine in ram which uses load immediate instructions, so all the bytes of the palettes are sent to the PPU in just over 200 cycles. The palettes probably won't change too often, so it might be a waste of ~10% of vblank, but I figure it is better for the time taken to be consistent, that way I don't miss a combination like Kirby transforming, changing his palettes, another character with a power star, and the stage reconfiguring all at the same time causing me to miss the end of vblank.