Making new games for retro consoles is something that amateur developers can do quite easily thanks to today's technology. Last year, I released a new game for my favorite console: the Super Nintendo (SNES). The project went as far as an actual physical release, with a cartridge and a cardboard box like the 90's. In this article, I'll present you the numerous steps of this incredible journey: designing the game, overcoming SNES-related technical issues while programming it, manufacturing new SNES cartridges, and creating the manual and box.
The game : Yo-Yo Shuriken
Yo-Yo Shuriken is a fast-paced arcade game for 1 or 2 players on Super Nintendo (SNES).
The core gameplay revolves around shooting a single shuriken that you can magically recall at any time, so you can hit enemies from the front or from behind! You can even focus energy into the shuriken to deliver a powerful charged attack that can cut through several enemies at once.
The game is available on cartridge with a beautiful cardboard box and a manual from Catskull Games:
And if you prefer to play it on emulators, you can also get the ROM of the game here:
Now that you are more familiar with the game itself, let's explore how it was designed.
Designing the game
Making Yo-Yo Shuriken was quite an organic process. I tested gameplay ideas as I came up with them, and tried to refine them until I had a "fun" game in hand. Let's start with the initial idea. For a long time, I wanted to make a shooting game with a single bullet. So the player must retrieve it each time he shoots. Besides the "one bullet" idea, I also wanted to make a game that could be enjoyed with a friend, in co-op. With both ideas in mind, I created the game step-by-step. Each major progress I made was labelled as a new "version" and playtested heavily. If the current version was good, I continued to add new features. Else, I kept working on the current features until the game was fun to play again before adding anything new. Here is a rundown of the major game prototypes, with screenshots. If you want to play the actual ROMs of these prototypes, they are one of the many perks available to my Patreon supporters.
1) Cyber Ninja - version 1
The first thing to do when making a game on a platform you don't know is to display something onscreen! So I drew a robotic ninja sprite and tried to have the SNES to display it onscreen. When it worked, I added code to make the sprite moves with the D-Pad. And then I made a walking animation when the sprite moved. These firsts steps may look simple. But remember that it was my first time making a game for the SNES! So it actually took quite some time to do, as I was learning how the machine worked while making the game. As the current project only displayed a robotic ninja, I named it "Cyber Ninja."
2) Cyber Ninja - version 2
The actual player sprite, a ninja, appeared in this second version. So the robot sprites naturally became their enemies, as everyone know that ninja and robots hate each other! As a proud ninja, the player can throw a single shuriken. The shuriken can get stuck on the screen border, and the player must pick it up to be able to shoot again. The robot enemies can move aimlessly on screen, but no collision detection is performed yet.
3) Yo-Yo Shuriken - version 1
After several tests, I thought that the shuriken could come back to the ninja automatically when the player pressed the button a second time. I had a lot of fun while testing this mechanic, so it became the core of the whole game! I also changed the project title to reflect this evolution: say goodbye to "Cyber Ninja", and welcome to "Yo-Yo Shuriken"! Indeed, in the game the shuriken goes back-and-forth, much like a yo-yo.
I also added collisions detection. Now the robots disappear when the shuriken hits them. But if a robot hits the player, he's the one who disappear. While everything is still in a very basic state, the core gameplay of the game is almost complete in this third game prototype. So I decided to "stress test" the engine to see how far I could push it before the game lags. I managed to have up to 80 enemies walking and interacting on screen. Remember that a SNES can display a grand total of 128 sprites, so having 80 of them updated 60 times per second with collisions and animations is some kind of achievement.
4) Yo-Yo Shuriken - version 2
In this fourth version, the enemies are no longer limited to straight line movements. They can now move in several directions. They also bounce off the screen borders to avoid exiting the game area. The game became more interesting as a result.
5) Yo-Yo Shuriken - version 3
I added a different background color, and a system to spawn enemies endlessly. In the previous version, once the 80 robots were destroyed, the game was empty. Here an endless army of robots is generated! The enemies can also follow the player, to force him to keep moving. Indeed, in this fifth version, the game became quickly boring if the player remained static.
6) Yo-Yo Shuriken - version 4
In this version, I faced my first big technical difficulty: displaying large explosion sprites whenever a robot dies. I chose to have quite small player and enemies sprites : 16x16 pixels. That way, I could display loads of them on screen while keeping enough empty space for the player to move around and avoid hitting enemies (the SNES screen resolution is 256x224 pixels). However, I decided to draw my explosions at larger size: 32x32 pixels. The Super Nintendo is capable of displaying two different sprites size at the same time. The developer can choose a "small" and a "large" sprite size from a short list of sizes (8x8, 16x16, 32x32 and 64x64) and the console will use this information when accessing the video ram to display the sprite data onscreen. This is one of the many graphical features that make game developers' life easier. But as any technical feature, it can become daunting when you don't know how to use it!
In my case, in this current prototype, I was only able to display a small portion of the explosion sprites, no matter what I did. The issue was actually quite simple: I wasn't uploading the sprite data where needed in the SNES video memory. So the machine couldn't read them back. I did find the solution after spending several hours on the wonderful documentations made by the homebrew community over the years. I thank them a lot for their hard work on creating and sharing all this precious knowledge: without them, amateurs like me wouldn't be able to make SNES games!
7) Yo-Yo Shuriken - version 5
This prototype marks the addition of another key feature: the two players co-op mode!
New kinds of enemies join the fray too: the orange robots can take several hits before exploding, and the blue robots can chase the player anywhere. I also added coins that you have to collect to score points. This mecanic greatly improves the gameplay. Indeed, the only way to score points is to collect coins. Killing robots doesn't bring you any "reward" per se, it's just a way to prevent your avatar from dying. The robots drop coins when they die. But the coins disappear after a few seconds. And there are always loads of robots on screen, that will kill you instantly when touched. To earn points, player must thus take a lot of risks and move among the robots, else he won't be able to make a high score. But sometimes, it's better to let some coins disappear to avoid losing a life. This is what game designers call a "risk / reward" choice, and it's a great way to make a game interesting. Here, this mecanic allows Yo-Yo Shuriken to offer a smooth difficulty progression to players. Usually, a rookie player will tend to stay static, and will solely focus on destroying the robots. He won't get points, but he will be able to continue through the game and defeat the final boss. Once a player starts to get more confident, he'll be able to collect coins to make a highscore. And of course, experienced players can try to make a "perfect run" by collecting all the coins, although it means taking an insane amount of risks!
8) Yo-Yo Shuriken - version 6
As playtesting went on, I realized that the game was becoming quite repetitive. I tested several ideas to solve this issue. The one I found the most interesting was to hold down the shoot button to "charge" your shuriken. When you release the button, it triggers a "super shot" that can cut through several enemies. This mecanic brings a bit of strategic thinking to the game. Now, the player can choose to perform several simple shots to kill the enemies one by one. Or he can choose to perform a charged shot to kill several enemies at once. But then he'll be vulnerable while the super shot is charging.
9) Yo-Yo Shuriken - version 7
Starting with this version, all the game mecanics that defines the core gameplay were in. So the project entered the longest and most tedious phase: adding content and polishing the game. First, I added sound effects, that I created with BFXR. I also included the wonderful music tracks composed by XRACECAR. I also modified the game GUI and moved it to the top of the screen.
Regarding graphics, I added a pattern to the game background. As my artistic skills are limited, I had an hard time drawing a convincing background. I made several attempts, including this one, before settling on a "wood planks floor" to emphasize that the game takes place inside a dojo (see next version).
Last but not least, I started to create the various game levels. Each level is composed by several enemies waves, with increasing strength and numbers. I spent an insane amount of time testing and balancing those enemies waves to make the game entertaining. Each game designer does this his own way. Personally, for an arcade game, I like to mix intense and challenging moments with easier moments so the player can catch his breath. For example if the player manage to pass a moment with fast moving robots chasing him while the dojo is already filled with slow moving enemies, I'll reward him with a slower-paced moment. Like 4-5 basic enemies moving very slowly so you can easily kill them and collect their coins.
On a side note, you may notice that the explosions graphics are still particularly hideous at this stage.
10) Yo-Yo Shuriken - version 8
In this version, a new type of enemy joined the fray: the "shield" robot. They can only be hit from behind. The "yo-yo shuriken" mecanic becomes even more meaningful here. Indeed, the best way to kill shield robots is to shoot around them first. Then, you'll have to call the shuriken back and to try to hit them by controlling its return trajectory. I also made new explosions sprites, and the background image is better looking. I even added an invincibility bonus pickup (a white ninja head, replaced by a star in the final game).
11) Yo-Yo Shuriken - version 9
The last major feature arrived in this version: the game bosses. I spend a lot time designing and testing numerous bosses. This was one of the most enjoyable part of the game development process!
In the screenshots, you can see a prototype of the "snake" boss, and a boss not present in the final version: the tank. The tank boss must be destroyed in several steps. It has several weak points (the orange balls) that have to be hit one after the other. Once a weak point is destroyed, it removes part of the tanks structure, exposing new weak points. This was a challenging boss. For example, one weak point is at the end of a tunnel, so it requires a very precise aiming.
On paper, this boss idea was quite interesting. It took me quite several days to program it. But after many play sessions, I decided to removed it from the game as it was boring. Indeed, it was sometimes quite hard to destroy the boss because of its huge size. Also, if the boss managed to block you into a corner, you were dead as you couldn't hit any of its weak points. In the end, facing this boss was a more frustrating than fun experience. As you can see, even in amateur game projects, sometimes you have to cut disappointing content despite the time you spent making it!
12) Yo-Yo Shuriken - version 10
The key word of this final version was "polish." I added the title screen, the introduction and ending animations, and a screen to explain how the game plays. The final touch was to include a hidden bonus mode: the "double ninja" mode, where you can control two ninjas with a single controller. To unlock this mode, you simply need to finish the game once (or use a cheat code!).
So, after more that one year of development and 5491 lines of code, Yo-Yo Shuriken was finally completed! The game ROM works perfectly. It was tested on several versions of the original game console (Japanese Super Famicom, US Super NES, PAL Super Nintendo); on modern versions (PAL modded with the 50/60hz kit from FFVIMan, Analogue Super NT); and on many emulators (Higan/BSNES, SNES9X, ZSNES, No$SNS, RetroArch, etc.) for various platforms (PC, smartphone, PSP, Raspberry Pi, etc.).
Once the game software final version was validated (all bugs fixed after an extensive beta testing phase), the hardware part of the project could begin. In other word, we needed to make the game available on actual cartridges with a beautiful cardboard box! But before exploring that part of the process, I'd like to give you more details on developing this game for a SNES.
Programming the game
Making games on retro platforms comes with a lot of technical constraints. Using modern tools does simplify the task compared to what the developers from the 90's faced. But you still have many constraints related to the limited specifications of the hardware. Like all the other homebrew developers, I struggled with these limitations while making Yo-Yo Shuriken. Here are the tools I used and the main issues I faced. I hope they'll help you figure how the SNES works under the hood.
Tools of the trade
Back in the 90's, game programmers had to learn and use assembly for each machine they were working on. The SNES was a difficult machine to work on because you had to learn not one, but two assembly languages: The 65816 assembly for the CPU, and the SPC700 assembly for the audio chip.
Nowadays, you can still use assembly, and it's actually the only route to get the most power from any retro machine. But you can also make some really cool games with easier to learn languages, like C or Basic. For the SNES, you have only one C compiler available: tcc816. It's far from perfect, as you have to use some python script to optimize / fix bugs in the code it outputs, but it works. A talented coder named Alekmaul took this compiler and built a full framework to ease the creation of games: the PVSNESlib.
I used this library to make Yo-Yo Shuriken, so I could code it in C language. For graphics, I drew BMP images that were converted to the SNES graphics format. For audio the framework accepted wav files for sound effects and .it files (Impulse Tacker format) for music. It was still quite a challenge to make a game running on the SNES, but PVSNESlib made it a "hard but fun challenge"!
How does a SNES works anyway?
Compared to other machines like the Mega Drive / Genesis or the PC-Engine / TurboGrafx16, the SNES is quite a complex machine, with a lot of different graphics modes. But it's general workflow is actually quite simple. Basically, a SNES can display graphics data using two channels: the "background" and the "sprites". The background is a full screen image made of 8x8 tiles. The background can have several layers (from 1 to 4) that can be scrolled independently. The video RAM is limited, so you usually have to stream graphic data from the cartridge ROM to the video RAM in real time in order to display some endless or large scrolling areas.
For the sprites, the SNES can display different sizes: 8x8, 16x16, 32x32 and 64x64 - only two of such sizes can be on screen at the same time. To animate sprites you have to manually set their position on screen and modify the graphical data that they will display, 60 times per second. To do that, like with the background, you first have to copy the graphical data (i.e. part of your spritesheet) from the cartridge ROM chip to the video RAM of the console.
The SNES can also play audio using a dedicated chip (SPC700). For input, it's quite easy to read what buttons players pressed on the SNES gamepads. (the best gamepad ever designed!)
In the end, even if you use a tool like PVSNESLib, you'll need to be familiar with how the SNES works in order to make actual games for it. Hopefully the wonderful homebrew community have consolidated some very extensive documentation. I'll recommend:
- The PVSNESLib wiki, that will guide you on how to set up the tools and how to make simple SNES programs: https://github.com/alekmaul/pvsneslib/wiki
- The NoCash SNES specs (technical, but thorough) https://problemkaputt.de/fullsnes.htm
- The SNESdev section of the NESdev forum: https://forums.nesdev.com/viewforum.php?f=12
The community is very helpful and skilled. They saved my life more than once when I was making Yo-Yo Shuriken!
Now that we have covered some basics, let's dig into some technical issues I faced.
How many enemies can we display on screen?
In a game like Yo-Yo Shuriken, the more sprites on screen (enemies, explosions, etc.), the better the game will be! However, the game cannot afford to lag. So you have to find the maximum number of enemies that the CPU can handle while keeping a smooth 60 fps display. The SNES is often touted as "slow" compared to the Genesis / Mega Drive ("Blast Processing" anyone?). And, in a way, this is true. While the SNES can display more colorful images and higher quality sound, the CPU time available is usually lower than the Genesis. In other words, the Genesis could usually moves more sprites on screen that the SNES. The best example of this difference are Contra III (SNES) and IV (Genesis). And more specifically, how each game handle explosions:
Explosion on SNES' Contra III (left) are made with a few sprites alongside a special graphical effect (transparency), while Genesis' Contra IV (right) renders them with an insane amount of sprites on screen. When programming each console like they are meant to be, directly in assembler, you can feel this difference in processing power. But when using a C compiler like I did for Yo-Yo Shuriken, the difference becomes even more obvious. So the total number of enemies I could display was limited by the CPU time available. But the CPU tasks are not limited to sprites management. It must also handle animations, upload graphical data to the video ram, manage collisions, read controller inputs, trigger sounds and music on the audio chip, etc. Developing Yo-Yo Shuriken was a constant struggle to keep as many enemies as possible onscreen, while all the other elements were eating the total CPU time available. Hence, I had to decrease the number of enemies several times as I added new features to the game.
At first, when there was only standard robots moving in straight line without collision detection, I was able to display 80 enemies onscreen (plus 1 player and his shuriken). When I added collisions detection between enemies, player and shuriken, I had to reduce this number to 40 enemies. Adding the second player, explosions, sound effects and music also took a big chunk of the CPU time available. In the end, the final game can only display up to 24 enemies onscreen in order to maintain a smooth 60 fps disp