MSXdev'21 will have its deadline on August 31st, 2021, and I wanted to add in my entry as well. This year, I didn't manage to make a brand-new game from scratch. Instead, I chose to just update my previous adventure game engine and write a new game using it: Step.
Game title screen.
My previous entry had been little more than a tech demo. This meant the game was a short one, something that I could easily handle by writing the contents files by hand. It still took most of the ROM space I had available for it -- almost 32KB, including the code.
Since that game was deemed short by the reviewers as well (also in Retro Format 2020 Annual), this entry would be a longer one. I'd split the game into multiple chapters, since I haven't sorted out the on-the-fly swapping of ROM pages yet... and also because the game still lacks save option.
To briefly elaborate what that means: the memory address space is made of four 16 KB blocks (total of 64KB). The last 16KB is for RAM (I can change values there), the first 16KB is for BIOS (computer's built-in routines to read joysticks, send data to VRAM, etc.) and the middle 16KB pages are such that they can be swapped in and out. In my case, the second page (memory addresses from 16KB to 32KB) contain the game code and content shared by all chapters. The third page (addresses 32KB to 48KB) contain the episode-specific stuff. When the player starts a new game, I swap the corresponding page to that and carry on.
MSXdev did not restrict the ROM size in 2021, which works fine for me here. In total, the ROM is 128KB in size (despite many of those pages being empty).
In-game graphics in chapter 1. Yes, compass directions on a spaceship don't really work.
Thankfully, this also meant I'd develop each chapter independently. The game content files quickly became unwieldy.
To summarise the insides of the game engine, it has:
Each direction or item with an action (such as go, take, look) have a script for that.
The previous game had 32 objects, 97 script pieces and 16 locations. That is about one third of what the new game had, although the number of locations isn't really comparable due to a new trick I could use. The first chapter alone had 41 objects, 115 scripts, and 12 distinct locations.
Let's focus on chapter 1 as an example. All texts, locations and items were defined in one text file with 664 lines (comments and empty lines included). All scripts were in one text file with 628 lines. Editing these quickly became unwieldy. Take the definition of an item, for instance.
The name in the inventory, nameRepressurisationLever, is stored in a bundle of other strings under [text] in the same file. location=Hallway states that the object starts at a location specified in [location_Hallway], still in the same file. The two scripts referred are defined in the script file. Neither of these files are structured on the larger scale, and have to be edited manually.
All 11 location graphics for chapter 1. There are in total 427 different tiles (out of 2156) and there were 92 defined ways to colour a tile. The "overrepresentation" of two shades of blue and one black was deliberate to keep the latter number low.
With chapter 2, I came upon a problem: when trying to fill in the chapter with something to do, I added so much fluff that I ran out of space that I had to massively simplify the graphics. A lot of this was easy -- reuse the horizon tiles, in the flashback sequence have the exact same blurry outline tiles that don't really show anything through.
The end result actually reminded me of old shareware games: the free first episode was often frontloaded with the best the game has to offer, and the rest of the chapters have less effort put into them since the publisher/developer already had got the user's money.
If I ever reuse this engine, I may want to make a custom GUI for editing these files. All in all, this showed me how important it is to have proper content-creation tools.
In short, the premise of the game is an uneasy one and a topic I might've been better not trying to write about.
Basically, in the game humanity has got Earth in such bad shape that we're sending first a small, faster ship to prepare an out-of-system planet for colonisation, without first making any check if the planet already has life of any sort. Whereas in real life, there's Lake Vostok in Antarctica under a thick layer of ice. Researchers have been very careful to not introduce organisms from above the ice to the lake, which is presumed to have been sealed from the the rest of the world for millions of years. Likewise, Martian probes have been thoroughly sterilized to avoid contamination of Mars or the samples.
So now in the game's world humans have sent a ship with the express intent of introducing terrestrial life onto another planet, completely disregarding the possibility of the planet already having endemic lifeforms. (Just because it'll look in game like there's no life, it doesn't exclude the possibility of microscopic life based on, say, chemosynthesis.)
I was planning to have some commentary on this subject in the second chapter, after the contamination has already taken place and there's a bit more time for reflection and regret. As it happened, though, I ran out of space in that chapter. Instead, I chose to include this topic in the final chapter as a preachy monologue, when the survivors are making their way to the camp of the generation ship. (I ended up running out of space in that chapter when I attempted to retouch the graphics in the end as well.)
Given the hurry I was in when making the game, there isn't really a typical narrative arc or a hook that would keep the player interested. The three chapters aren't really typical acts in a play.
In the first chapter, the ship arrives in the new solar system and the crew sets up the ship for launching adapted cruise missiles that would spread plants of various kinds to all around the planet.
In the second, the player has a flashback to the past and goes through the day they were drafted for this mission. This happens as the ship is landing; after that, the player has to help in setting up an underground base on the planet. The flashback was intended to set up the player's character a bit.
In the third, the crew have been in cryosleep for an indeterminate amount of time, and they need to find their way to the human colony that has since been set up. In here, I was badly running out of time to wrap up the game, so this chapter is far shorter than the other ones.
There is no character arc, since I don't think I even specify the player character's gender or name. There's no antagonist either, and the gameplay is more like snippets of a project diary.
The points where the chapters begin and end make sense, as they're obvious breakpoints in the narrative but also in player's options. There are no tasks that could be performed both before and after the breakpoint in my opinion, so they are also automatically checkpoints.
The gameplay, though, covers only a part of what the chapter contains: there wasn't enough room in that 16KB to fit in the whole chapter as gameplay. At least half of what would otherwise happen in the chapter is explained away in a few sentences.
Ideally, I could've had twice as many chapters in the game, but did I mention I was in a hurry to get this done? I also didn't have enough puzzles planned, which would've made it closer to a virtual installation instead of a game.
Oh, where the name of the planet came from? Steppes. Plus my goal is still to give games ungoogleable names. Maybe next time I'll pick a proper stop word as the game's name.
Reusing the existing game engine significantly reduced the amount of work I had to do. The ASM files I had written by hand for this engine had only 2300 lines or so, including comments and empty lines. The scripts I used to build the game binary and data ASM files from text files and PNG files were less than 2000 lines of Python. The actual data files? Less. The configuration files had 1500 lines, the script files 1300 lines.
I've sometime previously commented on how the ratio between executable game code and game content has shifted towards more bytes of content per byte of code. Of the games I've made for the MSX, this probably has the most data compared to the lines of code. In part, that's because I didn't count the scripts as code. But even then, the scripts take only a fraction of the space compared to the graphics.
A rough, not completely accurate distribution of actual game content. (Other data includes some text, code includes the single sound effect the game has, location tilemap selection isn't included in these numbers, ...)
By heart, I'm a programmer first. I wish to implement fancy algorithms, to make the computer do what I want it (and tell it what I want it to do). Content creation itself is not something I particularly enjoy.
Maybe that is why my favourite part of the project was in implementing a palette optimiser. If you recall my earlier (now deleted) blog on the game engine, I had a limit of 256 distinct palettes for the tiles displayed in the "viewport" to create the full image in the whole game (now in one chapter). Two tiles have compatible palettes (i.e., I can use the same palette for both of them), if the total number of colours on each line of the tile is at most two. The question was how to find the best collection of palettes that is as small as possible.
This is related to set cover problem, which is a classic NP-hard problem. In short -- we don't know of a "fast" way to solve such problems of arbitrary size, or if one even exists. But that's not what you're interested in. Too bad that I am.
(Thankfully, I could implement my solution in Python and not assembler. That would have been painful.)
After my and Retrofraction's earlier game project was not progressing due to time constraints, I decided to drop that and just write new content for my old engine. I still didn't have much time, and the idea of the plot had been around in my head for a year or two by then. The issue was that I had only the vague outline of the narrative, and the main focus had been in what amounted to the first chapter. This is reflected in the last chapter's length -- or the lack thereof. I managed to nearly finish the game in a month and a half.
On one hand, knowing how to create "space-optimized" graphics already in the drawing phase for the game helped. On the other, having to optimize graphics by hand didn't. In short, the more tiles I reused in the chapter, the better. The more tiles used a limited set of colours, the better. If a tile was already a unique one, other than possibly the colouring, it took the same amount of memory (9 bytes) no matter what it looked like, so I could put more effort into these tiles.
Despite this, I ended up having to optimize the graphics in chapters 2 and 3 to fit everything in one ROM page.
The game is still somewhat short. While I tried to make some puzzles harder, it's still somewhat easy to run through. I made a playthrough of the game on Twitch, and while I read the location descriptions aloud, it took about one hour to finish all three chapters, when I knew everything what I had to do in advance. As such, it's longer for new players.
The game has in total only a bit over 5300 words, so maybe two blogs' worth. Beside that, the 16KB I had reserved for each chapter turned out to be too little.
In novels, telling should be showing, and in games, showing should be playing. Or something like that. That's where I failed. A lot of the worldbuilding was left incomplete.
For a game whose content I made when I was in a hurry, it's passable. I'm not aware of gamebreaking bugs, it's a complete story and it's got a decent amount of content.
The limitation of having to fit a chapter into 16KB has to go for the next version of the game, and so does the lack of passwords for resuming the game later.
I'm reasonably satisfied with the graphics. The graphics in the first chapter look IMHO decent and don't take as much space as one might think. That is in part because of reusing tiles when drawing. With all unique tiles and no compression, the graphics in the first chapter would've taken 34496 bytes, twice the room for all of one chapter. Now, the data took about 6800 bytes. Still, I reused some images from chapter to chapter (because they were of the same room), and some images I originally meant to be placeholders ended up staying in the final version (despite them being rather poor).
The thing that has reasonable potential but doesn't use it to its full extent is the flashback section in chapter 2. The graphics are clouded and simplified (too far, but I had to simplify them because I was running out of room). I'd like to think I got the lonely daily rut conveyed well, with the train trip passing only by examining and re-examining the train stop chart. I really should play more Heavy Rain, since I think this was inspired by the second(?) chapter in that game.
A scene in the flashback. If you see where the water pipes and mirror outlines end, the tiles closer to the edge are all identical in the flashback locations to reduce the space spent on graphics.
The game has no music and only one sound effect. One big reason I write ASM games is because I want to write them myself. Using a pre-existing player code is at odds with that. Beside that, I don't know much about music, so I'm not too intested in learning more of that. This means I'm OK with the game being mostly silent.
In the end... well, I made it, and I don't think it's worth putting more effort into it. It's a new game, bolstering the number of entries in the compo by one, and while it may rank last this year (I don't know if there has been a single bad entry this year yet), that's enough for me.