Hey guys! I've developed a game in 48 hours for the game console that I have been working on lately!
The following Youtube video contains all of the info about the gameplay as well as a bit info about how this game were made. Please do watch it! :)
It isn't possible to develop a game within 48 hours without any preparation work. Therefore, I did spend quite a bit of time on preparing it. The preparation includes:
I wish I could get a third party to review this game. Unfortunately, it isn't possible for anyone else to play this game for now because the game console isn't released yet. So here's my self-review of this game.
As a game developed within 48 hours, I'm rather satisfied with the result. Thanks to my preparation work as well as my previous experience on game jams, I'm able to finish this game on time.
The game is rather challenging and well-balanced. The game is made interesting by having the player keeps try picking up coins. That's the only way to score in the game. For each coin the player had picked up, the game gets a little bit more difficult until the player couldn't hang in there and lose the game. With randomization of various elements in the game, including the spawn rate of conveyors and hostile entities, the position of the objects, etc. The difficulty of the game is partly based on the luck of the player. That makes it a fun game for players with any level of gaming skill.
For the program of the game, it's rather sad that there's quite a bit of code duplication in the game. That's partly because I'm on a memory-constrained system. Another reason is that there's a time limit for the jam. Anyway, the game jam had ended. I'm not going to fix that. :P
This game demonstrates that the game console I'm developing is capable for running games! It shows the system API of the game console is good enough for game development. Therefore, I am able to move forward to further develop this game console. In the future, this game console might become an alternative to PICO8 for game jams participants.
I'm sorry that I didn't update about the progress of the development of the game console for a while. A lot of progress were being made lately!
The second prototype of the game console is ready! It's soldered on a perfboard. There're a few upgrades made in this new prototype. Here's the specs of the second prototype:
The PCB to be designed will be based on this second prototype.
Despite that I had professional experience in embedded programming, I'm rather green. Therefore, I've discussed with some veterans in embedded programming about the design of this game console. Since this game console works by loading the game from SD card to the internal flash of the microcontroller by self-flashing, they immediately pointed out that performing frequent self-flashing would wear off the flash of the game console quickly.
I've checked the datasheet of STM32F030K6T6. The guaranteed number of flash write cycles is merely 1000 cycles. That's a little bit small and it will cause problem to our game console. Interestingly, the 1000 number of write cycles is "Guaranteed by design, not tested in production". For other microcontrollers produced by STMicroelectronics, the number of write cycles is often 10000 and it's "Guaranteed based on test during characterization".
It just doesn't make much sense to have this little number of write cycles. Here're some theories I have about the number:
In long run, maybe I should do my own research on figuring out the actual number of flash write cycles of the microcontroller I'm using. I refuse to believe that the write cycle is 1000 cycles in room temperature. If the write cycle is like 3000 cycles, it's kinda acceptable because that'd mean that the user can load 10 games every single day for 300 days until the game console breaks. And I doubt that there's such an enthusiastic player of this game console anyway. But 1000 cycles is really a bit too little.
To reduce the number of flash write cycles, I've modified the bootloader firmware so that it only perform flash erase and rewrite if the source ROM on SD card is different from the previousy self-flashed game inside the microcontroller flash. That would cause self-flashing not to be performed if the same game is launched again after a reboot. This should help reducing the flash writes by quite a bit, especially if the player is repeatedly playing the same game over and over again.
Another issue that those professionals pointed out was the Game Flash and RAM Offset. They raised an interesting idea about the offset of Flash and RAM.
In the past, I designed the Flash and RAM layout like this:
There's a huge problem with this design. For the flash, if I ever update the firmware and the size of the firmware got increased, that would cause the offset of the Game Flash to be changed. That'd require the game to be rebuilt to work on the newer version of the game console. The same issue goes for the RAM.
Therefore, I've modified the layout. Now it looks like this:
For the Game RAM, I put the bootloader-exclusive RAM at the end. This design allows the bootloader RAM to expand without changing the origin offset of the Game RAM. In addition, if I ever upgrade to a microcontroller with more RAM, the entire RAM space would be expanded. And I would push the Bootloader RAM to the end of the RAM, and the Game RAM space would also be expanded. Since the origin of the Game RAM remains unchanged, I can still run the game that's built for the pre-upgrade version of the game console.
The same story goes for the flash. However, it's a bit more tricky because I need the bootloader to take the first sector of the Flash. That's because the first sector contains the interrupt vector and boot-related stuffs. I have to take the first sector so that the bootloader would be loaded on power up instead of the previously flashed game. Other than the first sector, the remaining part of the bootloader is put at the end of the flash space. That brings us the same advantage of putting the bootloader-exclusive RAM to the end.
This thing was done long time ago. But I've been too busy to blog about it. In the past, we made something called EXTIF to allow the game to call the functions located in bootloader by using a software interrupt, just like how BIOS work. It turns out that this design is utterly dumb because there's a function calling convention for ARM. It's called Procedure Call Standard for the ARM Architecture(AAPCS). As it's the go-to standard for functions compiled for ARM microcontrollers, it's possible to call any functions compiled by any compiler with any amount of parameters as long as you have the address of the functions.
For this reason, I just made a veneer on a fixed address for each of the system API functions. The veneer redirects the function call to the actual address of the function inside the bootloader. To call the system API function, the game declares all of the system API functions available in the bootloader and assign those fixed addresses of the veneer to the function declarations. With GCC, it's possible to map a function to an address by using the --just-symbols parameter when you invoke the linker.
The latest bootloader firmware is able to redirect almost all of the interrupts of the microcontroller to the Game ROM. A veneer interrupt handler were used for calling the interrupt handlers in the Game ROM. That enables the game developers of this game console to perform low-level programming. Along with the high level API inside the bootloader, this game console allows its game developers to learn about both higher level programming and low-level programming.
Here I've managed to complete the 4th Alakajam by developing a game for my game console. :)
Now that the firmware of the game console is ready. The next step of the development of this game console project is to design the PCB. After that, perhaps I'll also draw a case for the game console. If I have the time, perhaps I'd also develop an emulator for it. Since the microcontroller behind this game console is an ARM one, it should be possible to modify a Gameboy emulator for running games developed for this game console.
Just as I planned, I expect this project should be completed some time in 2019. Maybe the emulator would be available in 2020 if I end up working on one.
That's it for this blogpost. I'll update you guys soon! :)
As of 15th Oct 2018, I'm currently in between jobs. I was an embedded programmer of thermostats with a bit more than a year of experience. I did firmware development, Python automation scripts as well as tools for internal use, including setting up MQTT server and web server on a Raspberry Pi. In addition of that, I have been a hobbyist programmer for 9 years since I was back in middle school. Currently I plan to learn further about Python and modern web development technologies, mainly the back-end and devops ones. Then I'll start actively looking for another job. I prefer to go for a remote-working job. It can be full-time, part-time or freelancing.
If you're looking for someone to fill in any sort of programming-related positions, feel free to contact me via "hire dot me at sadale dot net". Alternatively, you can look for me on Freenode for having informal conversation with me. My nickname is "Sadale" there. Keep in mind that you have to identify (i.e. login) on Freenode in order to PM me. That's a new policy of Freenode to deal with the recent IRC spambots.