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

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!

usebox.net is 20!

20 years ago I decided that I wanted a stable identity on the Internet. I had used free email accounts and web hosting for a few years but, specially the web hosting, was fragile and could change any time. Besides I had seen in my main email account at RocketMail that free services could change in ways we don’t like –RocketMail was acquired by Yahoo!–.

So it was time. I wanted to have a website that didn’t change, without ads, that depended solely on myself. I asked a couple of friends if they wanted to be part of it, I guess a bit in the tilde spirit.

They didn’t really care, and I can’t remember if they ever contributed any money to help with the costs, but this is how the website looked on the first day (in perfect Spanish!).

welcome to usebox.net

The front page. It was a good day!

Later on some more friends had email on the server –for a while, at least–, and the services have been online since then. It all started with an hosted service in Arsys, then a small server in OVH –can’t remember if it was a VPS–, then a miniserver in Memset –just a VPS with Xen–, and today a droplet in Digital Ocean –just call it VPS already!–.

At some point there was even sub-domains, like the old blackshell.usebox.net, where I hosted my personal weblog in Spanish, but the main website had different uses over the years. At some point it was my business card for my freelance job, but at the end is just a redirection to my personal website; because that is what usebox.net is basically.

My infrastructure has grown a bit in 20 years, and the prices have gone down. Never has been this easy –and cheap– to have a personal server on the Internet, yet every time some business ask you for your email on the phone there is surprise because it isn’t an email address on one of the big providers.

Anyway, here we are and hopefully here we go for another 20!

CAS support in ubox MSX libs

I made a maintenance release of my ubox MSX libs back in April, which updated one dependency and the docs after I run some tests with the newest SDCC. It was the first release of 2022, because the project is mature and stable –although there’s interest to make changes–.

Since then, I made another round of dependency updates, with special interest in rasm, because this excellent assembler has changed the way it builds, and it required a bit of work to move to the latest version. So yesterday I thought I would make a release, to not keep those changes in the main branch without being “official”; and I found a small bug that needed fixing.

It was an interesting one. Some of the python tools that convert PNG images to different data formats used on the MSX was using a set, and looks like in the python version coming with my current Debian (3.9.2), the order of the elements have changed. Long story short, the sprite of the player character in Green –the demo game– was not green any more. It was easy to fix, and I decided to make some changes to the project website to look marginally better and give visibility to the fix.

And then I was checking some files randomly and I ended reading the TODO file, and without noticing I started implementing CAS support.

The CAS files are a representation of cassette data used by most emulators. You can load them on your emulator, or convert them to WAV –if not play them directly– and load them on the actual hardware. Most MSX aficionados will have more sophisticated ways of loading software, but if you don’t, the CAS files are the easiest –and cheapest– way of loading homebrew games.

The official take of the community is that “cartridges are best”, and I agree; but it is also true that by releasing my games in CAS format –as well as in ROM format–, more people had a chance to play them –including some extreme cases of models with 16K of RAM and two memory expansions so for example Uchūsen Gamma would load–.

Some time ago I released as OSS my mkcas tool, that I wrote to generate the CAS files of my games, and in the case of ubox MSX libs it was just matter of adding the tool to the build pipeline so the user could get the ROM file –just a cartridge image– and, optionally, a CAS version of the same code. Including a loading screen, of course.

The CAS file uses a multi-stage loader:

  • Firstly, a short BASIC program is loaded that will load and execute a binary loader.
  • Then the binary loader loads two blocks, using the BIOS functions and some fancy code to show multi-colour loading bars.
  • The first block is the compressed loading screen, that is decompressed and uploaded to the VDP, so there’s something nice to watch as we wait.
  • The second block is the ROM itself, compressed as well. It is uncompressed and setup like it was running from ROM, but in RAM.

The only tricky part is configuring the slots so we have ROM, RAM, RAM and RAM; and that’s why I made this optional, because it will not work in machines without enough memory.

To start with it requires more RAM than the cartridge, like 32K more –which is the size of the ROM–. There are also other limitations –like the compressed ROM being less than 24576 bytes–, but all in all I think having a CAS file as an extra is totally worth it (based, as I say, on my experience with my games).

I spent way too much time reviewing the code because I forgot that any MSX model with disk needs to boot pressing the shift key to disable the disk BIOS or the BIOS will use some memory that the loader needs, but it wasn’t too complicated at the end. I’m happy with the result!

Two compiler implementations

I think I was reading about Oberon –the programming language, not the operating system– because a post on Hacker News, and I ended in the page of Niklaus Wirth.

Wirth was the chief designer of the programming languages: Euler (1965), PL360 (1966), ALGOL W (1966), Pascal (1970), Modula (1975), Modula-2 (1978), Oberon (1987), Oberon-2 (1991), and Oberon-07 (2007) –from the Wikipedia–, among other things.

That is truly remarkable. So I was looking around and I found that his website has PDFs describing the implementation of two compilers:

The code is very readable, and is not because I had to write some Pascal back at University –and Oberon is a descendant of that language–. There are things missing, but is mostly refinement of error reporting and things like that. Everything that is important, is there.

For example, the code generation of the multiplication for Oberon-0:

PROCEDURE MulOp*(VAR x, y: Item);   (* x := x * y *)
BEGIN
  IF (x.mode = Const) & (y.mode = Const) THEN x.a := x.a * y.a
  ELSIF (y.mode = Const) & (y.a = 2) THEN load(x); Put1(Lsl, x.r, x.r, 1)
  ELSIF y.mode = Const THEN load(x); Put1(Mul, x.r, x.r, y.a)
  ELSIF x.mode = Const THEN load(y); Put1(Mul, y.r, y.r, x.a); x.mode := Reg; x.r := y.r
  ELSE load(x); load(y); Put0(Mul, RH-2, x.r, y.r); DEC(RH); x.r := RH-1
  END
END MulOp;

It even shows constant folding –both operands are constants–. The resulting code may not be super-optimized, but it is a full example in an easy to understand size.

I skimmed through the “Compiler Construction” book during my holidays and is not too long. I’m looking forward to read it properly when I have some time.

Reading off-line

Last night I was finally reading a Scheme Primer, after weeks open on a tab in my phone. Firefox for Android reloads the tab every time I select it, so I thought: why not having a local copy that I can read even if I’m offline or the page is not available?

Well, turns out that Firefox can’t save the page. Not as HTML, not as a full website, not as a PDF; it basically lacks the functionality. Which is a trend with Mozilla, to be honest. Chrome is terrible from the point of view of privacy and I don’t want to play into Google’s hands, but Firefox is great at keeping things working just about to ensure they are never successful, which is a real shame.

I looked around and I found a developer saying back in 2012 that the functionality would be added, but they hadn’t had time yet. I’m not holding my breath.

So I tried Chrome, that allows saving the page, but then when I try to open it using the “Files” app, it doesn’t know how to open the file and wants to search for an app to install. Brilliant.

You can print to a PDF –with Chrome, in Firefox I can’t find how to do it, so it may not be possible–, but the PDF reader is not ideal as the text doesn’t flow using the phone screen efficiently. There must be a better way, isn’t it?

It isn’t a solution out of the box, but this is what I ended doing:

  1. Download the page as HTML in my desktop (using Firefox).
  2. Convert the page to epub format using the always powerful pandoc:
 pandoc --from=html --to=epub 'A Scheme Primer.html' -o scheme-primer.epub
  1. Install ReadEra –that is free, but I’m considering buying the premium version because it is a great reader!–.
  2. Copy the epub, and now I have the Scheme tutorial to read off-line anytime I want.

I don’t know if it is that the website is striclty following standards without much CSS, or pandoc being amazing, or the ebook reader being great, but the result is much better that I was expecting. Feels like an actual ebook.

When I’m away from my desktop PC I already have two apps from the public library to read magazines, ebooks, listen to audio-books, and whatnot, and I don’t use them much because… I guess what I wanted is to read about Scheme instead. I’m not a heavy app user, other than Podcast Addict and email, I tend to use the browser for everything else.

I’m glad I still have some options, but in reality, the ideal would have been that Firefox on Android was a better browser.

Playing The Minish Cap

Shortly after I blogged about playing Pokémon, we stopped. We got some Pokémon to pass level 20, but the kids lost interest –I guess the combats are a bit samey–.

So we started something completely different, or may be not that different because is not an RPG but Lenna’s Inception –from our pile of unfinished games– gets a lot of inspiration from games like this. We are playing ‘The Legend of Zelda: The Minish Cap’, and looks like we are close to finish it –according to an online guide, at least–.

This is one of the Capcom Zeldas from 2004, and it is heavy on puzzles. The gimmick of this one is a magical talking cap that can shrink Link to the size of the Minish, a type of tiny magical creature that only children can see.

Boss

I didn't know how to deal with this boss

The game is your proto-Zelda game: introduces new objects to solve new types of puzzles that allow you to investigate new areas to progress on the story. It also has a good number of small side quests that can be unlocked by “fusing Kinstones” with the inhabitants of Hyrule. And it also includes rescuing Zelda from a curse, of course.

The game looks fantastic on the GBA and we are playing it emulated on a big screen. The bosses are interesting and fun, and considering that this is probably the further I have got on a Zelda game, I would say is not too difficult –even if sometimes it is very obtuse, but in those cases I would suggest checking a guide; we look at the screenshots and that’s enough to give us a spoiler free experience–.

A new key

This key included a mini-puzzle later on

In general I would say the game has aged pretty well. I recall some complains about swapping objects too much, including in the sequence to defeat some of the bosses and sometimes is not clear at all what or where, including using a bomb in specific place –how classic!–, but considering Minish Cap was designed to be played on a hand-held and we have the Internet to get unstuck, in my opinion this game is very enjoyable by today’s standards and I totally recommend it.

Hopefully we won’t lose interest and we will finish it, for a change!

New project: micro2

Since the repo is not in GitHub, and that basically wipes completely any chance of anyone discovering the project accidentally –at least it would pop-up in my followers’ feed-, I thought I would use this blog to make it “public”.

I’m learning Haskell and I have decided to use the same project I used to re-learn Go, which again is huge and it is unlikely I will finish it, but there you go! I’m focusing on the compiler part, as I already scratched the interpreter itch.

The public repo is accessible at micro2-lang and the usual disclaimers apply –specially as I’m a Haskell newbie–. I know the name isn’t great, I may change it later on.

So far it has been a lot of fun. I’m using parser combinators via parsec and it is amazing the amount of functionality I have with a tiny fraction of the code I wrote in Micro. There are some downsides, though. For example, the errors messages are a bit less good.

For example, this program has an error:

1module main
2
3// just add two numbers
4def add(a: u8, b: u8): u8 {
5    return a + b
6}
7
8add(3, 2); // 10

The statements in Micro2 are delimited by semicolons, so the compiler reports:

error: "add.cr2" (line 6, column 1):
unexpected "}"
expecting statement

Which is not terrible, but is not great either. Serviceable I would say. Considering the objectives of the project, this is absolutely fine.

I am currently working on the type-checking and semantic analysis, which is really parsing, but can’t be all implemented using parsec (it will know how a “return” looks like, but can’t tell if it is used inside a function and returns the right type).

As I did it already in Go, is not too complicated, but I’m getting comfortable with Haskell and its Monads. The harder part I suspect will be the code generation, and I’m looking forward to it!

Tomato, Pomodoro, Tomate?

I tried to learn Haskell about a year ago. Which was basically ordering a book (“Programming in Haskell” by Graham Hutton) via the training budget of my employer, to rage quit after reading about 100 pages. It was probably not the book, but I wasn’t really focused, so I moved on to other things.

Since then I have returned to Go, and wrote a non trivial amount of code, and it was alright. At some point I stopped thinking about the language and wrote code fluently, and that’s a good thing, even if I found Go itself a bit boring.

So in my search of adding a new exciting language to my toolset, I was reading a bit about Scheme –again, I know–, and long story short I decided to go back to Haskell. I’m reading now Learn You a Haskell for Great Good!, that has the advantage of having a free version that can be read online, and it is more direct that the other book I have. And I’m enjoying it!

I’m still on chapter 5 (of 14), so it is a bit early, but so far I’m finding it very similar to Scala –with the Typelevel stack, see Cats and Cats Effect–, and you can tell that Haskell has been a great influence –assuming it is not the other way around because in some cases, Scala seems to get the features a bit further–.

Reading technical books is hard because, at least for me, it feels like it is a lot of information that I don’t seem to retain, until I need to apply that information and then it surfaces –most of the time at least–. So now that it felt like I knew some Haskell, and following the Scala similarities, I wrote a small command line tool: Tomato.

It is a very simple Pomodoro tool –in reality is just a timer–, that is inspired by pomo in Go by Rob Muhlestein. I think I saw it in one of his streams and I thought it was neat. It is a simple tool, but it has already some meat to it, including input/output, which is perfect to practice some of the tricky bits from Haskell.

And the experience was very nice. Most of my problems were with some syntax I don’t know yet, and specially with a couple of libraries I had to use. They are documented, but perhaps I missed some examples.

For example, I spent way too much time to figure out how to add minutes to an UTC time.

Let’s look at this function:

doStart :: String -> Integer -> IO ()
doStart stateFile mins = do
  currTime <- getCurrentTime
  let deadline = addUTCTime secs currTime
  writeFile stateFile (show deadline)
  putStrLn ("Started, end on " ++ show deadline)
  where
    secs = secondsToNominalDiffTime (60 * fromInteger mins)

It creates the state file with the UTC time adding the deadline for the timer, I had initially the minutes as an Int –and not an Integer; the difference is subtle– and secondsToNominalDiffTime requires a Pico type to produce the NominalDiffTime instance required by addUTCTime. Sometimes you can have this same problem in Scala, which I call type-matching bingo. The solution is clean, but oh it wasn’t easy to get there!

The library to deal with the program arguments gave some trouble as well, even considering the docs has two good examples. But in that case, it was only me to blame, and when the function signature clicked, then I understood how the defaults for the options worked. It was all because for the state file I’m using XDG_CACHE_HOME, and the function to get that directory returns an IO, so I couldn’t use exactly any of the examples.

The similarities with Scala are definitely a good thing: Option is Maybe (with Some -> Just and None -> Nothing), Either is the same, pattern matching is very similar –although Scala seems more flexible; it could be me not knowing all the tricks in Haskell though–, the IO Monad in Cats Effect is modelled after Haskell’s IO, etc.

The LSP support via haskell-language-server is good, although I tried to do a rename and it wasn’t supported. The docs are good, and I specially like that on hover you see the docs and a link to a local HTML file with the full docs of that package.

Perhaps the discoverability of Haskell is worse than in Scala, because of the syntax. In Scala you have a value and you can inspect methods with the help of your editor and LSP by just using value., but in Haskell syntax it seems to me like all are functions, so the dot trick is not possible. So at the end it is a bit overwhelming having all that API, but not really knowing it, so good look finding secondsToNominalDiffTime to start with!

You can see that the book intro to lists includes a lot of functions that you probably need to learn, eventually, and this is also a bit of a problem with Scala. You are trying to solve a problem, and the cleanest and most elegant solution is on a method you don’t know about.

All these are just first impressions, and I’m sure that I wrote some code that is a bit over my current knowledge of the language, but it wasn’t too frustrating and it only took me a bit longer that it should have. I found myself thinking about Scala native, because of those bits that feel a bit less flexible in Haskell than in Scala, but I have to say that I’m interested and I’ll keep going!