Saturday, September 16, 2017

Making MSX Games

For as far as I can remember, making games or computer games have been a very important part of my life. I learned how to code very early in my life. I think I was a bit over 10 years old when I started copying BASIC programs from the computer manual onto my first computer, a ZX Spectrum +2. Of course at that age I barely understood some of the key concepts, which only became clear later on, but I could write simple programs that I called "games". A year later (around 1988), we acquired an MSX computer (a Philips VG8020), and I became obsessed with programming. I remember my parents would convince me to go out of the house with the promise of buying me a "new programming book" (I own dozens, but a few that I scanned can be found here).

So, I programmed games on my MSX, then on the Amiga 500 (using a BASIC-like language called AMOS), and then on PC. I remember I took a C++ programming book to a summer camp when I was 15, which I almost completely read there, and I could not wait to get back home to start coding!

But in any case, anyone who knows me knows that if you ever asked me "what are you up to these days?", I would always answer something like "Oh, I am making this new game that...". I always was thinking of a new idea for a new game. But of course, since that was before the Internet, I've lost almost all of the early games I did. However, making games came to a stop around 2007 when work became too intense and I could not find time to dedicate to coding games...

About a year ago, I was so overwhelmed with work (trying to get tenure) that I needed a way out. So, I decided that I would dedicate at least a half an hour a day to code games again. Looking around I saw that the "new thing" in the retro-games community was to actually code games for old 8bit computers, even releasing them in physical format, with box, cover art, etc. as if we were back in the 80s! That sounded extremely appealing to me and I decided to learn how to code for one of my favorite retro computers, the MSX

Although I knew it had been there for many years, I finally became active in the MSX community once again (even after about 35 years after the MSX computer was released, the forums at www.msx.org are still super active, with new posts every day!). When thinking about which game I would make, the choice was pretty obvious, since one of the games that I have coded again and again is a little game inspired by the classic Thrust arcade called Transball. I coded the first version of Transball for MS-DOS in about 1995, and have remade it since many times (Transball 2, Super Transball 2, Transball GL). So, I set out to create Transball on the MSX!

The MSX computer was a very powerful machine back in the day, but compared to modern computers is extremely limited. It features a Zilog Z80 CPU at 3.58 MHz (which is basically an extension of an intel 8080), 16KB - 64KB RAM (the one I owned had 64KB), and a screen resolution of 256x192 pixels with 16 colors. Games were loaded either using cartridges or using tapes (I swear I must have had in the order of about 100 tapes with games back in the day!). When I was thinking about it, just the title image of Super Transball 2 was larger than 64KB, so, how the hell can we fit a complete game in that space! (and leave some RAM space to actually run the game!). Later MSX machines (MSX2, MSX2+, etc.) were much more powerful, but I was going for the original MSX1!

Basically, the answer is that to make any decent game, it has to be coded at a very low-level, directly in assembler. So, I set out to learn Z80 assembler! At the beginning I thought that was crazy. I had heard that the Z80 wasn't even able to multiply! it could just add and subtract. So, If you wanted to multiply or divide, you would need to write your own routines! It sounded daunting initially, but it turned out that that was an advantage! The assembler language of the Z80 is so limited that it can be learned very quickly!

After trying different assemblers, and programming environments, I settled for just editing using Sublime Text, and compiling using the Glass Z80 compiler, which is a cross-platform Z80 compiler. The most complicated thing was how to start! How does one write the simplest possible assembler program for an MSX, compile it, and load it into a real MSX, or an MSX emulator to run it!

After searching for many alternatives, I settled for creating my game by compiling it into a ROM file (which is the emulator equivalent of a cartridge). A ROM file is literally just a file containing the bytes that would be stored in a cartridge that you would plug to your MSX. So, after seeing this example online of a "hello world" in assembler for the MSX, I figured out how to compile it, and run it in an emulator (I use OpenMSX, which is by far the best MSX emulator; some people like BlueMSX since it looks easier to use, but it's not been updated for years, and it's not as accurate as OpenMSX...):

CHPUT: equ 00a2h
    org 04000H
;-----------------------------------------------
    db "AB" ;   ROM signature
    dw Execute  ; start address
    db 0,0,0,0,0,0,0,0,0,0,0,0
;-----------------------------------------------
Execute:
    ld hl,helloWorld
Loop:
    ld a,(hl)
    and a
    jr z,Done
    call CHPUT  ; call the MSX BIOS to print a character on screen
    inc hl
    jr Loop
Done:
    di
    halt

helloWorld:
    db "Hello world!",0
    ds 8000h - $

If you want to try it, just type that into a text file, call it "hello-rom.asm", for example, then download the Glass compiler, and from the command line type:

java -jar Glass.jar hello-rom.asm hello-rom.rom

Open the generated hello-rom.rom file in OpenMSX, and there you go! you will see that in the screen the text "Hello World!" appears right below the MSX intro text. Exciting! Of course that call to the BIOS is ugly, and you are not going to get anywhere by drawing graphics calling the BIOS (if you want any speed, you need to do things a the lowest level, controlling every byte that is moved around), but it's a start!

Over the next few weeks I started learning all the stuff necessary for coding games for the MSX. How does the graphic system of the MSX work? How does one produce sound? How about input from the player? reading the joystick? etc. It was a long learning curve, that took several months, but before I knew it, I had it! I had a version of Transball running on a real MSX!!

The experience was amazing! Programming a game at such a low level in such a limited machine is like building a puzzle. When creating a game for PC, in my experience, the game is never finished! There is always one more thing that you want to add. On an MSX that is not the case: once you run out of memory, that's it. Game done. Adding one little visual effect there or one more sound effect is out of the question! And the memory fills up VERY fast! So, you basically have to figure out of how to fit everything you want to fit into the tiny amount of memory that is available.

For example, maps in Transball are usually 64x64 tiles in size, and each tile is stored as one byte in memory. So, to store a level, that's 4KB right there! I wanted to have 16 levels in the game,  so that would have been already 16*4KB = 64KB! The whole memory space of the computer for maps... However, the first 16KB of the memory is reserved for the BIOS, so that leaves you with 48KB only, and you also need to leave some free RAM to run the game. Usually the top 16KB are reserved for this, leaving you only with the middle 32KB of memory to store your game. So, 16 maps was not looking possible...

But, luckily, there are many tricks we can use to save memory space. And one of them is using compression (e.g., like when you compress a file as a ZIP). I used a very simple form of compression (which is technically not even considered compression in computer science, but "encoding"), called "run-length encoding", and with that I could reduce the space required to store all the maps to a reasonable amount.

The next problem were the graphics. You see a lot of people talking about "pixel art" on the Internet, thinking that the graphics they are creating are "like those in a NES console", or like a "ZX Spectrum". But when you actually need to draw graphics in the real thing (in this case on an MSX) you realize that it's much more complicated than using low-resolution and few colors. The MSX computer (and all computers of the 80s) had such a limited amount of memory for storing the graphics, that even if it can display 16 colors in the screen, you cannot arbitrarily choose the color of each pixel. In particular, in the "Screen 2" graphics mode, the MSX can only display 2 colors per each block of 8x1 pixels (and that's the most powerful one!). So, that turned out to be a huge constraint (and all the graphic artists of the 80s gained a renewed respect from me when I tried to recreate what they were doing back then!). And that is just one of the limitations, another is the limited number of "patterns" that can be stored at once in video memory, or the limited number of "hardware sprites" that can be displayed at once... but I won't get into the details!

And I will not get into how to create sounds for the MSX! Forget about samples! I will just say that to create a sound effect, you need to figure out the series of commands that you will want to send to a series of hardware oscillators and a white noise generator so that when they all act in combination, what comes out is what you expect! A lot of fun, but pretty hard at first! 

Since I was doing this for fun, I did not advertise my game at all until the day it was complete. When I had a fully-playable, reasonably tested version, I posted it on the MSX forums, just to see if people would play it, and that was the beginning of a ride!! I got a flood of messages with feedback, feature and bug requests, some people even went over the code and helped me optimize parts of it to save space for new features! The final product was a decent game (for being my first on MSX!) that looked like this:



Of course, graphics are terrible, and there is no in-game music, but the game is a lot of fun once you master the controls of the ship! (being a Thrust-like game, it's pretty hard to learn at the beginning if you have not played Thrust before!). Also, think that this is running on a computer that was released in 1983! 

A few weeks after that, I was contacted by the people of repro-factory to create a physical edition of the game (and that was something I wasn't expecting!). An amazing artist (Cesar Rincón Nadal) created a cover art, and the final product looked like this:



Which is amazing if you ask me!!!

So, there you go, that's the story of how I decided to code games for the MSX once again, after nearly 30 years! After Transball, I've now completed two more games for the MSX: Tales of Popolon and XSpelunker. Of which Tales of Popolon also has an amazing physical edition created by Matra, and with cover from Sergio Cabanillas! I am now considering which will be my next "retro game" project, another MSX game? an MSX2 game? perhaps a Spectrum game? who knows! :)

All of my MSX games are open-source, and can be found on my github page: https://github.com/santiontanon?tab=repositories

Next time I would like to tell you about how to Tales of Popolon and XSpelunker work under the hood!

santi

4 comments:

  1. Fantastic story and grat games (specially XSpelunker!) hope you can continue to develop for msx (maybe for MSX2? or MSX with V9990/PowerGraph?)

    ReplyDelete
  2. What journey said! A joy to read. It’s always great to see new people coming to the MSX scene, and doing awesome stuff. And XSpelunker is such high quality! I’m also a bit jealous to read about you learning all those things for the first time. That must’ve been a lot of fun I think. Luckily there will always be more things to discover. Like the MSX2 VDP, which is quite different to code for... I would be curious to see an MSX2 game from your hands! :)

    ReplyDelete
  3. Thank you guys! and haha, I am indeed curious about learning more about the MSX2 VDP. I am currently working on a non-MSX game (just for variety, haha). But as soon as that one is done, I'd like to start looking into the MSX2!

    ReplyDelete
  4. Your story is pretty much the same as mine (and most of the folks on MSX community). Congratulations for your games and well written blog posts explaining the technics. I'm full of new ideas for my next project.

    ReplyDelete