Recent Blogposts of Product Release

Stay in - My 4th Alakajam Entry. A Game Developed for my Recent Portable Game Console Project!

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! :)

Links: Source code (Github) | Alakajam Entry Page

Game Mechanics

  • It's a platformer game. The character can walk to the left, right, or jump. There's no double jump.
  • There're new platforms keep spawning from the bottom. The platforms move up continuously. The character can stand on the platforms.
  • If the character get out of the screen (e.g. getting pushed to the top by a platform), you lose the game.
  • There're three coins shown on the screen. Taking one would increase your score by one, along with the difficulty of the game being increased.
  • Some platforms are conveyors. They move the character to the left or to the right while the character is standing on the conveyor. The amount of conveyor platforms to be spawned depends on the current difficulty of the game.
  • Avoid hostile entities. Mines move from the bottom to the top. Bullets move from either the left or the right and travel horizontally across the screen. Enemies chase the player. The player has to shoot them down with laser gun before the they get the player. The spawn rate of hostile entities depends on the current difficulty of the game.
  • The speed of the entire game is also affected by the current difficulty of the game.
  • The background of the game has some black dots (i.e. stars) moving upwards. That creates an illusion of the player falling down.
  • Saving highscore to SD card is implemented

Preparation Work

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:

  • Developing Python scripts for packing game ROM and generating graphical image files
  • Developing a tool for creating sound effects
  • Developing a minimalist test game for the game console
    • Writing Makefile for building the game as well as loading the game into the game console
  • Figuring out how to debug the game with GNU DDD
  • ... and of course, getting the second prototype of the game console ready! :P

Self-review of the Game

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

Significance

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.

Update of the Game Console Project since the Last Blogpost

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!

Project Update: Second Prototype

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:

  • STM32F030K6T6 microcontroller with 32kB of flash, 4kB of RAM. (Upgraded from STM32F030F4P6)
    • 12kB of flash and 512B of RAM is taken by the bootloader
  • ST7565R 128x64 monochrome LCD (Upgraded from Nokia 5110 48x84 LCD)
  • Buzzer and audio jack (The old version doesn't have an audio jack)
    • Buzzer and audio jack output switchable by a slider switch (New in second prototype)
    • Volume adjustable by a knob (New in second prototype)
  • 6 buttons, including left, right, up, down, button 1 and button 2
  • SD card slot for storing game ROMs and save data
  • 2-slot AA battery holder (New in second prototype)
  • SWD programming and debugging header pins
  • 12-pin GPIO (New in second prototype)
    • 3 of the pins are shared with master mode SPI bus for communicating with the LCD screen and SD card

The PCB to be designed will be based on this second prototype.

Project Update: Concern of Flash Wearing

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:

  • STM32F030 is a low-end microcontroller. So STMicroelectronics doesn't bother to test for the for the write cycles at all. Therefore, STMicroelectronics could be being very conservative about the rating of the number of write cycles
  • The 1000 write cycles is for the full rated temperature range of operation. It should be far higher at room temperature
  • It's marketing. They intentionally make STM32F030 looks weaker than other microcontrollers to boost the sales of their higher-end microcontrollers. It not very profitable for them to sell low-end microcontrollers like STM32F030.

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.

Project Update: Change of Game Flash and RAM Offset

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:

  • Start of Flash | [Bootloader Flash][Game Flash] | End of Flash
  • Start of RAM | [Bootloader RAM][Game RAM] | End of RAM

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:

  • Start of Flash | [Bootloader Header Flash, first sector][Game Flash][Bootloader Main Flash] | End of Flash
  • Start of RAM | [Game RAM][Bootloader RAM] | End of RAM

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.

Project Update: Removal of EXTIF

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.

Project Update: Availability of Low-Level Interrupts to the Game ROM

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.

Moving Forward

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! :)

Shameless Plug - I'm Currently Looking for Jobs!

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.


mi pana e kalama musi "mi ken ala moli e pipi" tawa jan ali | Release Announcement of Toki Pona Song "Futile Attempt of Killing Mosquito"

toki! ni li nimi mute mi pi nanpa wan pi toki pona lon lipu mi. tenpo suno ni la mi pana e kalama musi "mi ken ala moli e pipi" tawa jan ali a! tenpo suno luka tu wan la mi pali e kalama musi e sitelen tawa. tenpo pi mute wan la mi pali e sitelen tawa a!

tenpo pini pi tenpo sike ni la mi pali e kalama musi mute tan tenpo "Global Game Jam 2018". kalama musi wan pi ona mute li pona mute tawa mi. mi pona e kalama musi ni li pali e sitelen tawa pi kalama musi ni li pana e sitelen tawa ni tawa jan ali.

tenpo pini la mi pali e kalama musi. taso mi pana ala e ijo ni tawa jan ali. jan jo ala e ijo ni la ona li ken ala ante e kalama musi.

tenpo ni la mi pana e ijo ni pi kalama musi tawa jan ali a! sina ken ante e kalama musi ni.

Hey guys! Today I'm releasing a toki pona song "Futile Attempt of Killing Mosquito" along with an animation. I've spent 8 days and nights on this piece of music and its animation! It's also my first serious animation project in my life!

This music came from Global Game Jam 2018. I decided to be a musical guy for the event. So I've made quite a few pieces of music as a practice. That's because we're required to get the work done within 48 hours in the event. So I have to get familiar with the tools. A few months after the event, I found that I love one of those musical segment particularly. Then I elaborate this part and enhance it and I've made an animation for it. And here we have this musical animation.

Unlike my previous music, this time I'm providing source files of music publicly and direct download link to a few variants of its animation. That makes remixing and editing the music and animation much easier compared with my previous works!

sitelen tawa lon lipu Jutu | Animation on Youtube

o lukin e sitelen tawa ni pi kalama musi lon lipu Jutu!

Check out this musical animation on Youtube!

kalama musi lon lipu "SoundCloud" | Music on SoundCloud

[o kute e ni! | Click here to listen to it]

ante pi sitelen tawa en ante pi kalama musi | Derived Works of this Project

sina ante e sitelen tawa e kalama musi la o toki e mi. ona li pona la mi wile pana e lupa pi pali sina lon lipu ni a!

If you distribute a remix of any resources from this project, feel free to inform me. If it's a good one I'd be happy to put up a link to your work right in this blogpost!

sina wile ante e sitelen tawa e kalama musi e kalama uta pi kalama musi la o kepeken e ni! | Resources for Remix, Vocal Swap and Other Modifications

lipu lawa pi "CC BY 4.0" li lawa e sina la sina ken kama jo e ijo lon sewi lipu.

License of the resources above: CC BY 4.0. Please attribute to this blog post or sadale.net. If you do not want to do the attribution, please contact me and let me know what you're going to use these resource for. It's very likely that I'll grant you attribution exemption.

o ante e kalama uta! | Possible Modification with the Resources Above: Vocal Swap

sina wile ante e kalama uta la o kepeken e ijo "kalama musi" anu "kalama musi pi kalama uta". sina pini kalama uta la o kama jo e ijo "kalama musi weka kalama uta" kepeken ilo sona kalama. ilo sona kalama li ilo "Audacity" anu ijo ante. ijo "kalama musi weka kalama uta" en kalama uta sina li kalama musi pi kalama uta sina.

sina ken kalama uta e nimi mute pi kalama musi ni kepeken toki ante a!

If you want to do vocal swap, first, download the resource "Music" or "Vocal Assist". While playing any of these, sing along and record what you're singing. Then download "Instrumental Music" and align your recording to the Instrumental Music track with software like Audacity. Then you've got your voice into this piece of music.

With vocal swap, you can even sing this song in another language!

o ante e nimi toki! | Possible Modification with the Resources Above: Modifying Subtitles

sina wile ante e nimi toki la sina ken kama jo e ijo "sitelen tawa weka nimi Inli" e ijo "nimi pi toki Inli pi sitelen tawa". sina pini ante e ijo "nimi pi toki Inli pi sitelen tawa" kepeken ilo "Aegisub" la sina ken pali e sitelen tawa sin kepeken e ilo "FFMPEG" anu ilo ante. sina jo e sitelen tawa pi nimi pi toki ante a!

sina pana e ijo tan "Aegisub" tawa sitelen tawa lon Jutu la jan ali li ken lukin e nimi pi toki sina a!

If you want to modify the subtitles of the vid, download the resource "Animation without English Subtitles" and "SubStation Alpha English subtitles". Modify the resource "SubStation Alpha English subtitles" with software like Aegisub. With FFMPEG, you can combine the subtitles and the video. Then you get a video with subtitles in another language.

If you provide that subtitles file to the video hosted on Youtube above, other users can view your subtitles.

o ante e kalama musi! | Possible Modification with the Resources Above: Remixing the Music

nasin nanpa wan li ni: sina wile kepeken e ilo "LMMS". o kama jo e ijo "ijo pi kalama musi pi ilo "LMMS"". sina pini lukin e nimi mute lon ona la o kama jo e "kalama uta". tenpo ni la sina ken ante e kalama musi ni.

nasin nanpa tu li ni: sina kama jo e ijo "kalama musi" e ijo "kalama musi weka kalama uta" e ijo "kalama musi pi kalama uta". sina namako e kalama musi ni kepeken ilo sona kalama.

There're two ways to do remix. The first way is to use LMMS to remix the music. Download the resource "LMMS Music Project Source File". Follow the instruction in the file and download "Vocal (for LMMS)". Then you can modify the music right inside LMMS.

Another way is to use other audio tools. After downloading the resources "Music", "Instrumental Music" and "Vocal", you can do operation on the audio to remix it. For example, one can add some drum and stuffs to it, or add some effects to it like adding filters or reverb effect or pitch change or something like that. Just do whatever you want with them!

nimi mute pi kalama musi ni li toki seme? | What's the Language of the Lyrics of this Song?

nimi mute pi kalama musi ni li toki pona. :P

It's Toki Pona. It's a minimalist, constructed language invented by jan Sonja. The entire language is made of 123 words! It's rather easy to get fluent on it. I learned this language like two or three months ago. It took me like a month to learn it.

Long time ago I've attempted learning another constructed language Esperanto. I didn't have much success. Mainly because it really takes a bit of time to learn those vocabularies. I had to look up the dictionary from time to time. But Toki Pona's different. Once I learn all those 123 words, it isn't that difficult to understand any Toki Pona text and conversations. Even if I don't completely understand it, at least I'd have an idea on what it's about because I understand every single word. It's just that I don't understand the combination of words.

If you've nothing to do and interested in learning a useless language, Toki Pona is the language to go! Toki Pona community does exist. It's a bit small, tho. Still, it's rather fun to chat in a language that others couldn't understand. That's how do you talk shit about others without drawing any unwanted attention! :P

jan Sate li pali e sitelen tawa ni tan nasin seme? | Behind the Scenes

nimi mute li pona lili. sitelen lukin li pona mute. o lukin e sitelen ni:

A image's worth thousands of words. Take a look on this pic for an overview of how this vid were made:

An image showing the workflow of using the software for the creation of the animation

mi kepeken e ilo mute a! mi wile ala toki e ilo ali. mi toki e musi ona.

I'll not go thru all of the software above. I'll just cover the interesting parts.

kamala musi | Music

mi pali e kalama lili kepeken e ilo "Palette MCT". mi wile kepeken e ilo "Wine" lon ilo "Linux" tan ni: ilo "Linux" li ken ala kepeken e ilo "Palette MCT".

I made the melody and chord with Palette MCT. It's a great free tool for doing chord progression and designing melody. Since I lack knowledge on music theory about chord and stuffs, this tool is very helpful to me. Previously I did chord progression by trial and error. I adjusts each note tediously until I find the one that sounds right. With this software, it helps me to filter out those inappropriate chord immediately. Then I can focus on the one that sounds good.

Unfortunately, it doesn't support linux. I had to run it on wine. And it's the only non-FOSS tool I've used for this project.

Screenshot of part of the music composition software Palette MCT

As you see, there're those musical notes. The pink notes are non-chord notes. The black ones are the chord ones. And the colored rectangles with letters and numbers are the chord chosen for the measure.

This part was done before Global Game Jam 2018. Once again, this music is a enhancement of a piece of music made during my practice for the jam. :P

sitelen tawa | Animation

mi pali e sitelen kepeken ilo "Inkscape". ilo "Inkscape" pana e sitelen, tawa ilo "Synfig". mi pali e sitelen tawa kepeken e ilo "Synfig". mi kama sona e ilo ni kepeken tenpo suno wan kepeken sitelen tawa ni: [sitelen tawa "How to create animation in Synfig (3rd edition)"]. ona li pona mute.

I made the graphic with Inkscape. Then it's imported to Synfig and turned into animation. I learned its basic within a day using this video course: [How to create animation in Synfig (3rd edition)]. Synfig itself is free. But the video course isn't. Still, it's very affordable. If you're interested in learning it and cannot afford it, I'd be happy to buy a copy for you.

Screenshot of the animation software Synfig

ilo "Synfig" li pona. taso tenpo mute la mi pali e sitelen tawa kepeken ona. mi pini pali la ona li pali e sitelen tawa kepeken tenpo mute mute.

Synfig is a great piece of FOSS animation tool. It's easy to use. But it's rather time consuming to make animation with it. After making the animation, it also takes quite a bit of time to render, especially for video that uses the "Curve Warp Layer". It takes an hour and half to render an animation with like 500 frames on my Bay Trail Pentium laptop. The Curve Warp Layer was used to make the swinging arm animation in our video.

tenpo kama la seme li kama? | What's next?

mi pini pali e sitelen tawa ni la mi pali e ilo sona musi.

pali pi sitelen tawa li pona tawa mi. pali ni li musi. taso mi pali e ona kepeken tenpo mute mute. mi jo e tenpo sin la mi wile pali sitelen tawa sin.

The completion of this video marks the end of the break of my Portable Game Console Project. I'll get back to that project soon.

I enjoyed making this animation. The catch is that it takes far too much time to make one. I'll make another one in the future if I have the time.


International Asynchronous Rock Paper Scissors Tournament 2018 - Site's up!

March 28, 2018, 12:28 p.m. Behind the Scenes Product Release RPS

Hey guys! It's that time of the year again! Our awesome Rock Paper Scissors Tournament will soon be commencing, and its website's ready! :-)

This is supposed to be an annual event. However, it didn't happen last year because the hoster failed to set up the site. Therefore, we're going to host this event on our own this year.

We'll be issuing certificate of participation of all of our participants! If you're looking for a degree or a job, certificates are proven to be helpful on building your portfolio. That's why we're issuing them! Put that in your resume and we promise that'd secure your job offer or degree offer!

This year we've also made the captcha easier than it used to be! We believe that it'll invite some bots to join our event. That'd make our tournament even more competitive than it was! :)

Event details:

  • Duration: 1st April 2018 00:00~23:59 UTC
  • Location: Internet
  • Participation Criteria: Anyone from any country
  • Website for the tournament: https://rps2018.sadale.net/

Technical details

The front-end is almost the same as the old one. Semantic-UI were used. But we've changed the back-end from Django to Flask. Flask takes much less RAM compared with Django. And it takes much less efforts to develop stuffs using Flask, especially for trivial projects like this one. I guess Django is better suit for larger scale websites.

I guess I'll be opensouring this thing. But I'm too lazy to do so right now. Maybe later. :P


Arduino 1602 Snake Game - Snake Game on Alphanumeric LCD!

I'm thinking about making an AVR (non-Arduino) portable game console. I'm evaluating the type of display to be used (including multiple 8x8 LED matrix, graphical LCD, TFT/OLED screen, alphanumeric LCD and combination of them). Then I came up with a weird idea. What if I use a alphanumeric LCD as a graphical LCD? That'd cut me quite a bit of the cost compared with using graphical LCD of the same physical dimension.

I'm a bit bored today. I feel like tinkering around with Arduino and 1602 LCD that has been around in my home. Here's what I've got as a result of hours of boredom. An Arduino-based 1602 Snake Game:

Source Code

Check out the source code in this github repository!

Gameplay

  • Just like other snake games.
  • Controlled with two push buttons. One for turning clockwise, another for turning counterclockwise
  • The length of the snake starts at 4
  • Game field: 16x4 (yes, I split each character into two rows so that you get 16x4 instead of 16x2)
  • The game gets approximately 1.1x faster whenever an apple is eaten.
  • There's no wraping. You die if you hit the wall.
  • If the snake had grown enough to fill the entire game field, you win

Hardware List

The hardware is roughly based on this official Arduino LCD Hello World tutorial, with an addition of two push buttons.

  • Arduino Uno
  • Current-limiting resistor for LCD backlight
  • Potentiometer for LCD contrast adjustment
  • HD44780-compatible 1602 LCD
  • Two push buttons
  • Two pull-down resistors for the push buttons
  • Breadboard or PCB or whatever similar to connect everything above properly

The left push button is connected to D8, while the right push button is connected to D9. Both push buttons are pulled-down. For other connections, please refer to the schematics in the tutorial.

Turning an Alphanumeric LCD into a Graphical LCD

HD44780-compatible LCD driver supports up to 8 custom characters. By carefully defining those 8 characters, it's possible to subdivide each character into multiple "pixels". That can effectively turn the alphanumeric display into a graphical LCD display.

My design subdivides each character two rows. Each row on the character can be either empty, snake, or apple as shown below:

Custom characters defined in HD44780

There're two "pixels" in each character. Each pixel can have three possible values. Therefore, the total combination is 3^2 = 9. Since one of these combination is visually empty, a space character were used to represent that. At the end only 8 custom characters are needed. So the 8 available characters in CGRAM of HD44780 are just enough for our purpose.

To reduce RAM usage, each pixel is represented by 2 bits. So a byte can store 4 pixels. Everything is cramped into a uint8_t graphicRam[GRAPHIC_WIDTH*2/8][GRAPHIC_HEIGHT]. At width of 16 and height of 4, only 16 bytes of RAM are taken for the graphic! Had I used a uint8_t for each pixel, 64 bytes of RAM would be required.

After the completion of this project, I've found other designs like spliting each character into three rows, or try making use of all pixels by generating the CGRAM on-the-fly. I'll consider using these techniques for my future projects.

Randomization of the Apple Position

To make the position looks random, we need to somehow seed the random number generator. For computer programs, we usually seed it with the current time of the machine. However, this couldn't be done on Arduino because it doesn't have a real time clock.

My solution is to make a menu screen of the game. When the user start the game, the time of the moment that the user pressed the button is used to seed the random number generator. The micros() method of Arduino Time library were used. This has the equivalent effect of using system time.

Funny Failure: Bug Went Unnoticed for Hours

I was having fun playing with this game. I thought that it was reasonably bug-free because I had played it for a while. I've also asked one of my family members to try it out. I swear. We haven't spotted any bug.

Until I tried to record a video of the game play, something funny happened. I realized that I haven't implemented self-collision detection of the snake. I was like "Wow. How come no one had notice that earlier?". Hah. What a terrible failure!

Upon the discovery of the bug, it was fixed in no time.

Future Development

Seems that using alphanumeric LCD as graphical LCD is promising. I'll consider going for this solution for the portable game console project. Of course, I won't be using Arduino for that. Arduino is good for prototyping. But it isn't as efficient as lower-level C/C++ programming.

I've played this game for many times. While it's technically possible to win, I haven't managed to do so. And I haven't tested the code of winning the game. I doubt that anyone could beat it anyway. I guess I'd just leave the code there as it is. :P

Game Over photo of Arduino 1602 Snake showing the text "Boo! You lose!" and "Length: 14" in the other line

Alright. That's enough fun for today. Gotta sleep.


Global Game Jam 2018 Post Mortem - Being an Audio Engineer for 48 Hours

Jan. 29, 2018, 8:51 a.m. Behind the Scenes Gamedev Product Release

This year, I have done another Global Game Jam. I did it in Hong Kong again. Mainly because I was being too lazy to try out other jam site for this year. :P This year I had done something different. I did music instead of programming.

Link to the game - Carpe diem

Pre-jam

I had spent quite a while for practicing using Musical Palette - Melody Composing Tool, LMMS, LabChrip, sfxr and Audacity. I've figured out an efficient method to produce music. That is to come up with melody and chord harmonization by using Musical Palette, then import them into LMMS to further process it. I managed to produce a few pieces of good quality 1 minute music, each of them was produced within 24 hours.

For the LabChrip and sfxr, it's nothing more than about using the randomizer and manual fine adjustment of the parameters. And Audacity is even easier. It's just useful for noise cancellation and applying effects.

First Day (26th Jan 2018)

Just like the previous years, I came to the site without a team. As I planned to do music this year, it isn't possible for me to do it alone. So I sought for a team right after I entered the jam site. I tried requesting joining a random team by asking them and got politely rejected. Then another team with three existing members waved at me and asked if I was alone. I answered yes, told them that I made music and got accepted into the team. Then I had a dinner provided by the organizers. Here's a pic with more than 300 jammers begging for free food:

A photo showing a lot of people queuing for food

In the midway of our game design discussion, two of the team members had left their seat temporarily. Since I had no idea about the roles of other team members, I asked the remaining member about their role. He told me that he did art, one of the other team member did programming, and when he tried to explain the role of the last team member, his was like "uhm... uh... he's... uh... good at coming up with, uh... uh... ideas and presenting, uh... the ideas". :P Then I ended my question with "Ah. He does marketing. That's good." What I thought was that "He gotta be an idea guy!" :P

When all of the members were back to the seat, we ended up with a consensus on the game design timely.

Then we started connecting to the internet with WiFi. It was very unstable. Then I tried using mobile data by USB tethering with my smartphone. Surprise! Even mobile data is stabler than the WiFi connection provided by the organizers. Since I had a data cap, I had to use my data wisely. So no youtube for me.

I had started to draft a piece of music in the first day. Musical Palette were used for drafting the music.

A screenshot of Musical Palette - Melody Composing Tool showing a few musical notes with chords

Second Day (27th Jan 2018)

In the second morning, I managed to caught the shuttle bus provided by organizers and arrived at the jam site early. I had breakfast. There's some open area in my jam site. It's rather interesting to see those people standing and eating outside. Some of the jammers had a bit distance in between possibly because they don't know each others.

A photo showing people standing and eating

After the breakfast, we got back on working. I gave the on-site WiFi another shot with no luck. And I used my mobile data again.

Then I was sitting along with the marketing guy. I sporadically took a peek on what he's doing. That was funny. Most of the time he had his Mac laptop playing youtube video, surfing facebook or chatting with instant messengers. At the same time he was holding a smartphone playing games on it. That was impressive. He was taking multitasking to the next level. To be fair, offering critical opinion requires playing others games. Anyway, he did spend a bit of time to look for info about how to make an awesome trailer for games, and studied about the good indie games.

Then the real fun begin. I continued making the music and completed composing with Musical Palette. Then I started working with the same piece of music with LMMS. However, it didn't went as smooth as I thought. In the midway of making the music, I asked my teammates to review it. Then the marketing guy complained that. He demanded a piece of music with abstract wordings that I couldn't understand. :P As you know, musical stuffs is difficult to be described by words.

After a while, he provided me an example of music that he's interested in. That was the BGM of Plants versus Zombies. It was a piece of music with drums without melody.

Then I toss away the old piece of music, made a new one and came up with this in Musical Palette:

A screenshot of Musical Palette - Melody Composing Tool showing no musical notes with chords

I had never made this sort of music before. Using the same chord over and over again for 16 segments (or phrase in that program). Chord variation techniques were used. It isn't the sort of music that I like. The music sounds extremely stressful like playing airport traffic control games. But it does fit into the theme of the game. Then I mastered the piece using LMMS:

A screenshot of LMMS showing notes of chords

That's crazy. The same chord is played for a long time as shown above. I had added some sidechaining to it. Then I showed my teammates this piece of music. And they're ok with that. It seems to me that it isn't perfect to the marketing guy. But apparently he compromised and told me that this music is ok. That's possibly because of worry of time constraint.

Then I started working on the sound effects. That was rather easy to me. Depending on the sort of sfx, I used LabChrip, sfxr or remixing recorded voice with Audacity.

Working with LabChrip and sfxr was easy. Just click on those randomization button until I get a sound that's close to the one that I want. Then I adapt it a little bit and that's it. Using Audacity is still easy, but it has a bit different workflow. For the sound effects that's simple, I just performed noise cancellation and reverbed it. For sound effects that has like having many people saying the same something, like wow, or laughing sound, what I did was to record the sound for multiple times myself. Then performed noise cancellation, overlapped those recorded sounds, and reverbed it a bit and here we have it.

Speaking of noise cancellation, I'm rather surprised at the noise cancellation capability of Audacity. Behold a screenshot showing the power of the noise canceling effect:

A screenshot of Audacity with two sound tracks showing the noise cancellation function

We were in a noisy room with a lot of discussion from parallel teams sitting right next to us as shown below:

A photo showing with a few teams working on their tables

The result was brilliant. I seriously thought that I had to get out of the room for recording the voice. I'm not sure if it's solely Audacity, or it's that I was using a headset (Kingston HyperX Cloud Core) that allows me to put the microphone closely to my mouth for clear recording. But still, considered the environment noise, the result of the noise cancellation was very impressive.

At the end of the second day, I went back to home. All of the teammates claimed to stay overnight.

Third Day (28th Jan 2018)

In the third day, I woke up a little bit late. So I couldn't get on the shuttle bus. I arrived the jam site by myself. After arriving at the site, I've found that our programmer had got back to home last night. And he would be doing remote working for our team for the day.

The third day was relaxing. There wasn't much for me to do. After goofing off for a while, our team had started producing the promotion video for our game. The rule of our jam site is to make a one minute trailer for the game. So I had make a piece of music dedicated for the trailer. The art guy did the video and synchronized the text with the music. The resultant video was quite good. The programmer had uploaded the game and our team members were happy about the game and the trailer. I haven't had time to try out the game that our team made, tho. That's because I was on linux, which is unsupported by the game.

After that, the marketing guy had come up with a story written in the description of the game. Then I extended the story with better wordings. Right after the game submission deadline, the artist and the marketing guy left because they were exhausted of staying overnight. At the end the marketing guy didn't do much other than giving critical opinion and discussing the game design. It seems to me that that guy is more like a quality control guy.

I had got a bit of time to chat with a few interesting jammers on the site. Before I had the time on socializing with them. presentation session had started. It mainly comprised of playing those 1 minute trailers. When it was my turn, I was rather surprised that the volume of our trailer were so low. I don't know if it's the audio of the vid itself, or the staff had set the volume level to too low. After that, the sponsors gave awards to some well-performing teams. And that's the end of the Global Game Jam of 2018 to me.

GGJ Venue with a big screen showing a Powerpoint slide with the words "WE DID IT, AGAIN!"

We took shuttle bus to a major metro station and got back to home.

Post-jam

After getting back to home, I tried playing the game that our team made. I was rather disappointed with the game. It was severely bugged and it isn't even remotely playable. Despite that the trailer looks good, the game itself sucks. Then I tried out other games produced in our jam site. They had similar problem. Super buggy. Not playable. Good or mediocre trailer, but no fun to play with at all. Wow. Seriously?

I guess now I've finally figured out the truth of Global Game Jam in Hong Kong. Almost all games here sucks with funny or semi-interesting trailer. Many jammers are just interested in getting an award. That's something that I truly hate because it isn't what a game jam about. If you like 48 hours game development competition, you could have just joined Ludum Dare!

I don't know. If I have enough spare time, I should seriously consider joining Global Game Jam elsewhere next year. The Macau one seems to be feasible because the guys there speak Cantonese, so there wouldn't be any language barrier to me. And the bridge connecting Hong Kong and Macau should be completed by next year. That'd make it easy for me to travel to there. :)

What Went Well

  • Finally I have a normal game jam collaborating with others without running into major disagreement
  • Everyone in the team are willing to compromise a bit
  • The music and sound effects I made were up to par. Considered that I haven't tried making music in a game jam before, I'm rather satisfied about what I did
  • Made a piece of music in a genre that I've never made before!
  • Having adequate sleep
  • Every team members are happy about the event

What Went Wrong

  • The game is buggy
  • Should have spent more time on socializing with others
  • The WiFi internet access provided by the organizer is bullshit

Notes to Future Self (May not be true for everyone)

  • Try not to join the Hong Kong site
  • Try out other roles in the team (like making graphic or video)
  • Try to get some random internet friends to form a cross-site team
  • If I'm to make music for the trailer again, make the background music LOOOOUUUUDD!

Despite that this jam isn't perfect, it's good enough. I'm happy about it. :)

Beyond the Game Jam

Now I've a few pieces of music laying around. Some of them were produced for practicing making music before the jam. One of them is incomplete and was produced during the jam. Perhaps I can write a few songs with those music in the future.

And I also have some sound effects produced. Maybe I can create an asset pack with them.