Ordmonster

Spurred on by the mattemonster (maths monsters – it is available in English and Swedish) app that I created to make my sons homework a bit more exciting (everything is more exciting on a screen), I’ve decided to create another app. This time it is about basic reading and words. The title is ordmonster – swedish for word monsters. As this is work in progress, you can find it on my github. I’ll try to get the alpha play store listing done this week – but with fosdem coming up, I might run out of time.

The game can be run in two different modes – one word / many pictures, or one picture / many words. You can also select if you want four or nine items of the many category. Turns out nine images or four words seems ok. Right now reading nine words is a bit too tedious.

The first thing I’d like to point out that my fluency in Godot as a tool is starting to show of. I’m more happy with the code structure of ordmonster, and I start to feel that I don’t continuously bump into the sharp edges of Godot, but use the engine as it was meant to be used.

I also learned a couple of things. The first one is the Control::mouse_filter property. The GameButton nodes (the ones showing a word or a picture) consists of a Button with a Label for text and a TextureRect for holding the picture. The TextureRect sits inside a MarginContainer. It turns out the MarginContainer stops all mouse events from passing through, effectively disabling the Button. This took a while to figure out.

The second half has to do with how resource files can be traversed on Android. Resources are embedded into the executable produced by Godot. The words available in the game are stored as the filenames of the images, so that I don’t have to create a table and keep it in sync with the file names. Really smart idea – right? This smart idea cost me quite some time.

First up, it seems like you cannot have non-ASCII characters in asset filenames when building apk files for Android devices. Really annoying. The fix was using English for the filenames and having to add the words to my translation tables, so now I have a table to keep in sync with the filenames anyway.

The fun did not end here. Now it worked on desktop (both Linux and Windows), but my Android builds simply crashed on me. It turns out that the Directory::list_dir_begin and friends do not seem to work on Android, or the assets are not included in the apk. I’ll spend some time figuring out what is up, then I’ll probably file a bug report. In the mean time you can follow the current forum discussion. The code in question, including my Android hack (yet another list – sigh) is shown below:

func _init() -> void:
  if OS.get_name() == "Android":
    # TODO This is a really ugly HACK
    _words = ["ant", "apple", ... , "zebra"]
  else:
    var dir = Directory.new()
    if dir.open("res://assets/images/words") == OK:
      dir.list_dir_begin()
      var filename = dir.get_next()
      while (filename != ""):
        if filename.ends_with(".png"):
          _words.append(filename.left(filename.length()-4))
        filename = dir.get_next()

When working with internationalization of Godot apps, I really miss the Qt tools for extracting text needing translation. lrelease/lupdate – please come back, I forgive you and regret all my harsh words!

In other news, next week if fosdem. I’ll be there, so make sure to let me know if you want to meet and greet. Drop a mail at hello -at- e8johan.se, or ping me on twitter or mastodon.

Also, foss-north is approaching. The Call for Paper is still open – closing soon. Make sure to mark the dates March 29-31 in your calendar. Ticket sales will open soon.