Subscribe to Personal Log via RSS and find other blogs to read in my blogroll.

The retro game development bible

Cover of the book

The cover of the book

Some time ago Juhang Park contacted me to say thanks for ubox MSX libs –which is always nice–, show me some work in progress games and ask for my permission to write a book about game development in C for the MSX using my libraries.

That was interesting. I don’t think anybody needs permission for that –even without considering the licence of the libraries–, so that is what I told Juhang. I wished them good luck and kind of forgot about it.

Well, the book has been published now in Korean: The retro game development bible. Which is very cool!

Apparently the book was rejected a few times because it was “only MSX”, so Juhang had to cover more ground by including MS/DOS and other “retro” targets –the site selling the book lists a lot of systems, but I can’t tell how deeply they are covered–. And there is something unexpected: Juhang wrote a translation layer so my API can be used with SDL1, SDL2 or Allegro as backends.

There is a reimplementation of King’s Valley 1 using ubox MSX libs –that I’m guessing it is used in the book–. It can be played on the browser thanks to WebMSX. There is also a repo with some info about the different chapters.

Juhang offered to send me a copy of the book, but I can’t read Korean, and told me that there are two MSX games that hopefully will be released soon: Galkave (a horizontal SHMUP) and Bomberman Special (a Bomberman clone).

Cross-compiling Haskell

It is complicated. May be my games aren’t that good or interesting, but if you can only play them if you compile them from source –and besides, written in Haskell–, that is perhaps too niche even for me.

This weekend I put some time into researching it, and there’s some documentation (for example: Cross Compiling GHC), but things don’t quite work. The most interesting issues I have found:

  • Haskell is written in Haskell, so you need a Haskell compiler. Apparently 9.2.5 won’t compile 9.2.5, or I did something wrong. Using 8.10.7 seems to be OK.
  • The cross-compiler is hosted in Linux and the target is Windows, yet the compilation of stage1 tried to include windows.h; which is not available in Linux. I must confess don’t quite understand what was going on, but I couldn’t get past that.

It is slow to try and repeat. Besides, once things fail, there isn’t much I can do.

So I shifted my focus to a different approach: can I run the Windows binaries in Linux using Wine?

It is possible, and I have put together some docs and scripts in cross-compile-hs-wine.

The first part was easy: getting GHC –the Haskell compiler– and Cabal –one of the Haskell’s tools to build Haskell projects– to run using Wine. I mean, is not trivial, but is not too hard. At least for pure Haskell projects, because if your dependencies need a C compiler, or even worse, are bindings to C libraries –like SDL2 and SDL2_Image–, things get very fiddly.

So at the end I had to get everything running in Wine, which includes:

  • Cabal for Windows.
  • GHC for Windows.
  • MingGW-W64, a port of the GCC compiler suite to run in Windows.
  • SDL2 and SDL2_Image development for MinGW.
  • pkg-config-lite, a version of pkg-config for Windows.

Looking around, seems like installing Haskell on Windows (and SDL2) isn’t that easy.

For the second part, because Cabal is awesome, I only had to write a wrapper for it so it can find everything it needs when running from Wine, and after that it was just a couple of issues to get the sdl2 to compile. First I couldn’t get Cabal to find pkg-config, and second I think it might be a bug in sdl2-image –I will open a bug report–.

The compilation is slower than the native Linux versions, and the generated binary doesn’t quite work in the Wine version shipped by my Debian 11 (stable) –tried with unstable from a container, and Wine 8 runs it perfectly–, but this makes things OK: I can build and distribute binaries for Linux and Windows –even if the Windows part is a bit awkward–.

So now I can stop procrastinating and keep working on the game.

Gamedev in Haskell?

So at the moment I have a couple of 8-bit projects on hold, or what we could call my TODO list, but I also have a couple of ongoing projects in modern systems. As I mentioned, there are some ideas I would like to implement before I can do it in a 8-bit microcomputer (you learn by doing it wrong).

At first I thought about finishing my little Canvas 2D engine that I wrote refreshing my Javascript. And it all was going well, until I met again an old friend: I’m not sure if what I’m doing is correct, and the performance of Canvas 2D in Linux is just not what I was expecting. It uses too much CPU, and after a bit of profiling my code and comparing with other games online, I got to the conclusion that it wasn’t me.

Rendering with Javascript

Using a CC tileset

I probably should release that engine “as is”, although I don’t know why anyone would use it.

I didn’t like the result –that could be an issue in Linux, or a recent regression–, and it didn’t matter if I was using Firefox or Chromium. I tried PixiJS, that is a nice framework that wraps all in a 2D API, so you can use WebGL instead of Canvas 2D, and it didn’t get better.

And to not make it a rant on the state of the web browsers on Linux –or in Debian, for me it doesn’t make a difference if I doesn’t work well enough on my system that means it may be like that or worse in other systems–, I also tried LÖVE, although my experiences with Lua in the past left me a bit cold.

Turns out LÖVE is great, despite spending with it only a couple of days. Good documentation, the poor performance I was experiencing with the web browsers is gone, and if you fancy going functional you have Fennel –which is a lot of fun!–.

But then –and this is my own fault– I decided to look at some libraries for LÖVE, and that didn’t go well. I should have done all myself, and I would have saved time fighting those libraries to get to something that was not really inspiring me. So I run out of energy, but I think LÖVE and Lua are worth revisiting. After all my time doing gamedev in Python struggling with performance, this felt great!

Then I remembered that I had a code base that I prepared to use C and SDL2, but never used it for anything. “This is the time!”, I thought. And that is one of my “projects to learn”, a simple JRPG that is progressing nicely –I’m currently working on some formulas and you could see my JRPG design notes (not anymore)–. I should write a post on how I’m integrating fe –a tiny Lisp-alike scripting language–.

And as I keep writing good old C I was looking for something else to do in Haskell, because I have done a couple of things, but my last project was too big and I was learning too many new things at the same time. So why not a simple gamedev project? That would limit the scope.

I have nothing interesting to show yet, because I’m still struggling to have some graphics or even an idea of what I want to do, but the SDL2 bindings for Haskell are excellent. The API has changed a bit to make it more high-level and closer to Haskell, but it wasn’t too hard to understand those changes –taking into account that I’m not an SDL expert!–.

The idea is to make something simple, closer to what I would produce in a game jam, and make it public to get some reviews and tips from friends.

So far my main struggle was around parsing JSON files –for tiled maps–, which I wouldn’t say is too gamedev, and it was a good learning exercise. At the end it was easier and cleaner than my C code using cJSON –that is pretty good–.

Anyway, I’m looking forward to have that small game ready. I’m using ReaderT + IORef and so far the functional and no variables bit hasn’t bothered me at all!

At the end this post is not that much about the title. Oh, well. As an example, this is how my map renderer looks at the moment.

-- | Renders a map.
render :: SDL.Renderer -> Map -> IO ()
render renderer (Map mapData tex) = do
  mapM_
    ( \layer ->
        mapM_
          ( \(x, y) ->
              renderTile x y $ tlTiles layer !! (x + (y * mWidth mapData))
          )
          index
    )
    (mlayers mapData)
  where
    mw = mWidth mapData
    mh = mHeight mapData
    index = [(x, y) | x <- [0 .. mw - 1], y <- [0 .. mh - 1]]

    firstgid = tsFirstGid (mTileset mapData)
    cols = tsCols (mTileset mapData)
    tileWidth = tsWidth (mTileset mapData)
    tileHeight = tsHeight (mTileset mapData)

    renderTile :: Int -> Int -> Int -> IO ()
    renderTile x y tile
      | tile < firstgid = pure ()
      | otherwise = do
          let tx = (tile - firstgid) `rem` cols
              ty = (tile - firstgid) `div` cols
              src = U.rect (tx * tileWidth) (ty * tileHeight) tileWidth tileHeight
              dst = U.rect (x * tileWidth) (y * tileHeight) tileWidth tileHeight
          SDL.copy renderer tex (Just src) (Just dst)

Considering that it is two functions –plus another one to get the SDL_Rect, but that’s not strictly necessary–, I’m quite happy with it!

Playing Persona 4

This is not my first contact with the Persona series, because I tried “Persona 2: Eternal Punishment” on the PS1, but I didn’t really connect with it. The graphics were cool, for a PS1 game though.

Then this Christmas I remembered that one year ago we were really into Final Fantasy IX and I checked again to confirm that there’s nothing like it in the PS1: the previous entries in 2D didn’t work for us –playing with my sons, lots to read– and the ones starting with 3D on the PS1 look way worse than FF IX (e.g. the models on FF VIII are just LOL).

So, what about the PS2? I have to confess that I had never tried to emulate it, and turns out that –without being perfect– the emulation is pretty good in my modest PC!

I don’t really understand how the emulator can play for example Final Fantasy XII without breaking a sweat, and when I run anything remotely 3D native, it uses a lot of CPU and the fans are on all the time –so my PC doesn’t melt–. Same happens with anything running on the browser, including Canvas 2D.

But then we tried FF X and FF XII on the PS2 and, for different reasons, we didn’t connect. So, what about Persona 4? I recall a friend really enjoying Persona 5 on the PS4.

Nice anime graphics

Discussing with the party

And I have fallen in love! The game is just plainly cool. It has a mix of social simulator and JRPG that is very a appealing –even if sometimes you would prefer to go and fight, but instead you have to go to school and care about social interactions to get your stats up–. The graphics are pretty good, and the voice acting is outstanding!

It is a long game and I’m not sure how far I’ll stay hooked, because I have other things to do in my free time and the game is not always OK to play with the boys around.

The combat is fun

Chie is my favourite character so far

The story is complicated, as you may expect on a JRPG, and after enjoying watching Summer Time Rendering early this year –that quickly jumped to my top 5 anime series ever–, this “Persona 4” reminds me of the mood perfectly.

I’m about 13 hours in, and its depth is sometimes a bit overwhelming. Fortunately it includes some “quality of life” features that I would have loved in FF IX –for example: it has contextual help for all the items, so no more using items in combat to see what happens–.

The game has been OK so far, we will see when things get more challenging!

Hyperdrive is out!

Yesterday I finally released Hyperdrive, with very good reception.

So far there are a few short YouTube videos with a bit of gameplay, which was expected: getting to understand the game and get further of the first boss requires some time. Hopefully later on we will see longer videos with people completing the game.

The YouTuber Xyphoe featured the game in his AMSTREAM last night, and it was very fun to watch and participate on the chat. Some takeaways:

  • People like the game, appreciating the technical part.
  • In general, they expect a regular shot’em up and the chain base power-up system is a bit confusing at first.
  • Once it clicked for Xyphoe, he got hooked.
  • When the weapon is not powerful enough –until level 3 or so–, is better to use “precision” by pressing fire when needed; later is OK to keep pressing fire and use a more “burst” approach.
  • When a life is lost, the weapon is downgraded; if the player doesn’t go back to “precision”, the game ends pretty quickly!
  • Xyphoe collected bombs, but he never remembered that he could use them to save tricky situations –probably because getting chains requires a lot of focus–.

In a way, this feels quite a lot like play-testing, although it is happening once the game is finished.

Other than that, I have fixed a small bug related to timing in the menu screen. I have three reports, including myself, of people playing the game on a real CPC not experiencing any issues –I’m assuming that CRTs can be quite permissive–, but the person reporting the issue explained it with a lot of detail and I agree that there was a problem (I was generating 304 lines instead of the expected 312 in a 50Hz output). Anyway, it is fixed now and version 1.0.1 is available to download.

My notes

I was commenting recently the idea of digital gardens, and a bit after that I realised how easy would be to have my own.

This site is already some markdown files on a directory, so I added a sub-directory and some templates to make Hugo render them pretty –with a table of contents, for example–, and that was it.

So you can go to the notes section, and see how it looks. Currently there are a couple of things over there:

So is not that different to what I had when I was using vim-wiki –although I ended not using that one–, with the main difference being that when I update this website, the notes are made public.

The core idea behind a digital garden is learning in public, but in my case I think it is going to be more like an easy and quick way of publishing some work in progress content –a bit like a personal wiki–, or for those things where a blog post is not really the best format.

Time will tell if I keep using it!

Digital gardens

From Digital Gardening Tools and Resources, what is “digital gardening”?

A garden is something inbetween [sic] a personal blog and a wiki. It’s a collection of evolving notes, essays, and ideas that aren’t strictly organised by their publication date. They’re inherently exploratory – posts are linked through contextual associations. They aren’t refined or complete - posts can be published as half-finished thoughts that will grow and evolve over time. They’re less rigid, less performative, and less perfect than the personal “blogs” we’re used to encountering on the web.

I have read about this a few times already, and every single time I find it interesting and makes a lot of sense.

I have always had a personal website. I started around 1998, so for me is pretty much always. Recently I celebrated 20 years of usebox.net, in a way my last personal website. And it kind of felt like that already.

If a wiki is a self-editable website where anybody can contribute, a digital garden could be just a wiki where the owner is the only one editing it, perhaps? I don’t feel like the focus should be in the lack of publication date but in the fact that the content is a work in progress that may be finished at some point, or abandoned in current state.

I like the blog to dump ideas or comment on things that I find interesting, because that helps me to solidify my thoughts –like I’m doing right now–, but it is true that the blog posts eventually disappear to never be seen again –down deep the archive–. There are tags that can help to find content that is related, but there is no further refinement: things get published and are final.

Let’s look for example to my post on bank switching. I think it is a blog post in which the date when it was published is not important and instead refinement of the content would be better –that’s why I transcribed the content to CPC Wiki, so it doesn’t get lost–.

I was looking at mkdocs last night, because I like it and this was the perfect excuse to put something together, but I woke up today undecided. I already have this website, and it could work as well to keep my notes –call it work in progress or digital garden–, I just need to find a way to make that information accessible.

Further info:

Fediverse, Adverse and Necroverse

From Alex Schroeder on Mastodon –not linking the toot because Alex deletes them after some time–:

The Fediverse is Mastodon, Pleroma, Diaspora, Friendica, Hubzilla, Osada, and all their friends, federating. 👍

But what do we call all the silos, the ad-based family of Facebook, Twitter, Reddit, and friends? It’s the Adverse! A universe founded on ad serving. And a reminder that they offer plenty of adversity. All the adverse silos stand alone, like rocks, like islands, like Alcatraz. 👎

And what about Orkut, Google Wave, Google+ and other networks that have come and gone. This is the Necroverse.

Sometimes networks that seem alive today slide into the necroverse. Let’s hope we keep our network alive. Here’s to many happy years in the fediverse! 😁🥳

I have been on Mastodon since May, and it has worked for me. I still have my Twitter account, because I have a good number of followers and that is useful to promote my games –and also some friends that are still there and they are not really into Open Source philosophy and couldn’t care less about the Fediverse–, but I haven’t been very active. Funnily enough, my number of followers keeps growing now that I don’t post.

Why does Mastodon work for me? I’m building a small network of friends –well, not everybody is my friend; not yet–, which is the same I did on Twitter. It doesn’t matter how many followers I have or how many people I follow, I always end interacting –and caring– about a dozen or so people, and you can have that on the Fediverse, federating and without ads.

What about you? Are you still in the Adverse?

Hyperdrive is almost ready

Hyperdrive is not completely finished, I still need to write some music, but the gameplay is complete and it is being tested by a couple of good friends. I tend to incrementally test my games, so there is not much work left for the testes, but they almost always find something. This game may not be the hardest to test, but it won’t be easy either.

There are also other things to do before the game is released. For example: preparing a dedicated website. I may try to make a teaser video –very difficult and not essential–, and write some blurb of text for the press.

I don’t plan to make a physical release, at least from the start, which should reduce the levels of stress associated to the whole process. The main change is that, in case a bug is found after release, is not that bad. Later on I may consider a Dandanator (or DES) release, not sure.

Despite all that, there is some pressure. This game is using cartridge as media, which is not very common in the Amstrad CPC world, so I may have some backslash because of that. Which is fine, because some people always complain –with good intentions–, not matter what you do. I guess at very least some Amstrad fans will ask for a disc version for the 128K models, and a cassette version for the 464, and basically any combination in between.

The music is not finished yet, but let’s look at some numbers:

  • 11 months of development –I rewrote the engine 3 times until I got it where I wanted–. It moves at 25 FPS (most of the time, at least).
  • 9 levels of weapon for the player, with different speed and sprite (some share sound effect).
  • The enemies have 2 different types of bullets, and one of the bosses have a custom one as well.
  • 5 stages, with different enemies and end boss; that is 8.5K per stage, a bit over 42K in total.
  • 17 different enemies (different sprites, and behaviour), which including the bosses is 30K of compiled, relocatable sprites.
  • Over 15K of background tiles and misc graphics.
  • 16K for the music player, sound effects and songs (planned, I don’t think I’ll need more than that).
  • Over 26K of code, split in two 16K banks –with no bank switching support in the compiler, it was interesting to implement–.
  • Over 15K of RAM used for buffers, variables, etc.
  • The type of gameplay I like, trying to not let the technical part limiting the fun part; which is not easy aiming to get smooth and constant 25 FPS on the CPC!

It is using 12 banks of 16K of the 32 available on a cartridge (up to 512K), so it could be bigger! And all without loading times, and working in all CPC models (and the GX4000), independently of the amount of RAM they have. Sure, it won’t be as easy to load on a real machine without add-ons, but we are in 2022 and most aficionados have those anyway.

So I think it pays off. I wrote in a blog that I think cartridges are a cool media for the Amstrad CPC, and I decided to use it in this game. Could I have done the same with multi-load? Probably, but it would have been 128K models only, and it would have been quite different –likely with some limitations and compromising on some things–. All in theory, of course, because clearly that ship has sailed.

My plan is to allow a month for testing –so I can write the music as well–, and then have a release early December.

The Hand of Fate

My younger son is pretty good with the mouse already, and he is getting better and better at reading, so I have been thinking that there are a lot of good old games that we could play together, and he could drive.

An obvious genre is point & click adventures –or as we called it back in the day graphical adventures–, as long as the interface is not too cumbersome (no SCUMM for now, the verbs are a bit too complicated for a 5 year old), and ideally it should have voices so I don’t have to read all the texts. So there are a few years of point & click games when they where still popular and the CD-ROM as media was perfect to add content like digitised voices (and some video, often looking awfully bad today).

My wife is playing Shadowrun Returns –the tactical RPG based on the table-top game–, and discussing how many games I have in my GoG library that I have never played, and that most of them were given for free at some point; we checked if there was any new free game.

Although we didn’t find any that I didn’t have already, we saw that the The Legend of Kyrandia games were less than £2 (each). I never played them back in the day, but I remember that they were big in the magazines of the time, with full walk-through of both. The graphics are good, of the time and style of Lands of Lore –in fact, the evil Scotia is mentioned in The Hand of Fate as a joke–, and after a quick search I found that the interface wasn’t too complicated and it had fully digitised voices. So we decided to give it a go.

In the game

The game looks fantastic in glorious VGA

We have been playing The Hand of Fate –which is the second on the series– for a few days, and we completed it yesterday. My son was thrilled, even if we needed a guide for a lot of the puzzles. This game is a showcase of most of the problems of the genre, and then some. But if you have some help when things get extra-obtuse, you can enjoy the cute graphics, the excellent synth-FM music and the nonsensical story.

The game has good humour –although one joke has aged so-so–, and the voice of Zanthia gives a great personality to the main character –even if sometimes, to show the urgency of the situation, it will interrupt the action to tell us that we should hurry up–.

The potions we need to make during the game are a good excuse for puzzles, and I liked the mechanic: find a page of your potions book, find some weird ingredients, make and use the potion to remove a blocker and advance on the story.

And then there is the story, which is not great. It doesn’t matter, because the important is the puzzles, but you spent two thirds of the game to get to a location to basically realise that it was all a waste of time. Then a character exposes the actual plot, and we do the last third of the game –and it didn’t surprise us who the baddie was–.

In the game

Zanthia changes clothes often, and that's part of the charm

You definitely need guide to complete the game, and I guess it makes a lot of sense now that the magazines published those in-depth walk-through back in the day. Even with the guide, at one point we got to an unwinnable state, because we flushed our cauldron too soon and then we were short of one skeptic potion to complete the game (fortunately we had a recent save and we only lost 30 minutes of progress). And there is a “Towers of Hanoi” puzzle that it doesn’t matter if you have a guide, to not mention the final scene where we died around 20 times until we got it right –because you can die in this game, even if is more a joke than an actual mechanic–.

So I would say it is a hard game, but we had fun, and I can think of worse introductions to the genre. Besides, it is the first game we complete!