Why I spent almost a year building an RPG game for a fantasy console

Bruno Oliveira
13 min readJul 4, 2019

This article is about why and how I built Shadow Over the Twelve Lands, a retro RPG for the TIC-80 fantasy console.

[Where to play: itch.io or the TIC-80 site. Either way, I recommend downloading the game rather than playing online.]

When I started programming, 286s still roamed the land, floppy disks were still floppy and Windows was something you launched from the MS-DOS command prompt every time you wanted to use it. I remembering being flabbergasted when my cousin showed me a BASIC interpreter. He wrote some weird-looking commands in it and suddenly a game came to life. “What is this dark magic?” I thought. I was 12 at the time, and that year I started programming.

The very first game I wanted to write was an adventure/RPG where you’d explore a world, talk to its denizens, venture into dungeons, fight monsters, etc., but my programming skills were extremely limited. It wasn’t that easy to learn programming then: I was in Brazil and Internet access was an expensive luxury that cost several dollars a minute using dial-up ISPs in the US (the first Brazilian ISP was still a few years away). So we had to rely on books people brought from abroad and more than once I made a phone call to my cousin to ask him if he remembered what parameters a particular function took. No such thing as autocomplete back then: you either knew it, or you didn’t.

So I kept putting off making this game, first because of a lack of skill, and then also because of a lack of time. At some point it didn’t seem to make sense any more. The mid-90s arrived with its flood of elaborately produced games in shiny CD-ROMs, each game requiring a team of dozens and a budget of thousands of dollars to make. It was discouraging to think that whatever I, a high-school student, could ever come up with would be laughable compared to those titles. But I always had it in the back of my mind to build this game anyway just for fun.

Fast-forward twenty-five years. Now fantasy consoles happened. Pico-8, TIC-80, Voxatron, Liko-12, an army of retro-sounding names bringing back all the nostalgia of a bygone era when games were simple and could be entirely created by just one person. None of these “retro consoles” actually existed in physical form: they are modern inventions that try to bring back the joys of that simpler world. I, of course, jumped on this boat right away.

I started making some action/shmup games like 8-bit Panda, Pilot-8 and FPS80, but then decided it was time to build that RPG game that had been sitting on the back of my mind. So one day (September 6 of last year, to be precise — because my temporary name for the project was PI906), I sketched out (using pen and paper) the basic math for a simple “fake 3D” engine inspired in the look and feel of such games as Might and Magic* (the good ones, I mean — MM1 to MM5), Eye of the Beholder*, Dungeon Hack*. After the engine was working (that is, not crashing immediately), I went on to build the UI, the battle system, dialogues, etc.

(*) All trademarks are the property of their respective owners.

One of the great pleasures of fantasy consoles is building everything from scratch, and creating this whole stack from the ground up — starting from the details of matrix computations all the way up to composing music — was a ton of fun and I enjoyed every bit of it. Why? Because it’s not something one gets to do in “real life”: professional programming, for better or for worse, is more about combining and reusing than it is about creating. In fact, implementing something from scratch is often risky and viewed with skepticism; reusing is almost always safer and more productive.

Fantasy consoles, on the other hand, allow you to indulge in the guilty pleasure of reinventing the wheel, and you learn a lot in the process.

So for the remainder of this article I will talk about the several technical and game design aspects that went into making Shadow Over the Twelve Lands.

Overall Design

Like most games of the kind, the core gameplay revolves around exploration, battle and advancement. The idea is that the player will spend some time roaming the world in search of quests, then will perform those quests and get rewards (in the form of XP and gold) and then level up and upgrade their equipment. A subset of these are the “main plot”, which is a series of linked quests that culminate in the final battle and the end of the game.

The world is full of monsters but towns are safe spots where the player can stop and rest, buy supplies and upgrade equipment. This is the peaceful town of Riverside, the first city the player encounters in the game:

Town of Riverside

Towns have helpful merchants where you can buy equipment:

Blacksmith’s shop in Riverside.


Like a lot of RPGs, the game world consists of a large world map and smaller maps for towns/dungeons. In my case, the world map is 180x136 tiles and there are an additional 35 secondary levels. This gives the player plenty of room to roam around and explore, and just getting from place to place is an interesting part of the experience as the player is likely to encounter new terrain, new monsters, new hazards, etc.

World map (left) and town/dungeon maps (right). Large rectangles delimited in gray are “map pages”.

The lines in gray divide the map into regions (“pages”) which are used to determine what sort of monsters appear and other game effects.

Each region has a different look and feel and different challenges. There are grassy plains, forests, tropical beaches, deserts, wintry lands full of ice monsters, dark areas where it’s always night and, of course, the poisonous swamps (an unavoidable trope of RPGs).


The combat system is turn-based. Each character in the party can choose what to do on their turn, like attacking, firing an arrow, casting a spell, using an item, etc. There is also movement, which allows characters to move in closer to the enemies or father away from them, to create the possibility of different strategies.


The party has an inventory that allows them to carry up to 80 items, apart from equipped items of each character:

Items may be identified or unidentified. Unidentified items might be cursed and have adverse effects. There are several item types: weapons, armor, shields, boots, helms, amulets, rings, scrolls, wands, potions, …


A lot of RPGs give the player full control over character creation so they can put together a party of whatever types of character they choose. I thought about doing that, but decided that I wanted to create the characters myself so that I could interweave them more closely with the plot.

Alex, Leon, Lyla, Vic
  • Alex, the main character. He and his brother Leon are orphans and arrive in Riverside with a pretty vague motivation: fame and fortune. Alex is a warrior whose main role in the party is to deal massive amounts of damage.
  • Leon, Alex’s brother, is a paladin who starts out as a weaker version of Alex but soon learns a few spells that allow him to heal and protect the party, and gets more and more powerful spells (and hence a deeper strategy) as the adventure progresses.
  • Lyla joins the party later, helping Alex and Leon escape from jail. She is an archer and later reveals her secret identity (see Plot, below).
  • Vic is the last to join the party. He is a wizard who starts out with pretty weak spells but grows a lot in power very quickly. He wears a pointy hat. How original for a wizard.


An RPG can be “on rails” or “open world”. Most games fall somewhere in that spectrum. “On rails” means the player has little to no choice, and just gets “railroaded” from one scene to the next by an inexorable force, powerless to change the course of the story. “Open world” RPGs emphasize the ability to freely explore the world and accomplish things non-linearly.

For Shadow Over The Twelve Lands, I wanted a more “on rails” approach but I also didn’t want to completely constrain the player to playing it in a particular order. So what I did was design the world in such a way as to encourage, but not strictly enforce the progression I had in mind.

One of the ways to do this is to design the layout of the world and place obstacles and difficulties such that the player is naturally led, through the principle of least resistance, to follow a certain trajectory. In this case the quest begins in the Riverside area, a cheerful and grassy island with plenty of hints and easy battles. The player is then encouraged to proceed to Blossom Fields and the more challenging Serpent Island (any guesses as to what sort of enemy they will find there?), until they make their way to the town of Sun Port and get joined by a new party member, which makes them powerful enough to access more and more of the world, and so on and so forth.


Caution: this section is full of spoilers! If you want to play the game without these spoilers, skip this section.

Act I: The Great Mistake. Alex and Leon start out in Riverside and their first quest seems pretty straightforward: go into a cave and rescue the town’s governor. Simple, run-of-the-mill errand, right? Well, they find the governor but he is dying and gives them the four crystals, asking them to deliver them back to Markus, the vice-governor. They do so, and that’s when things start to go wrong! Instead of helping them Markus is corrupted by the power of the crystals and concludes that Alex and Leon killed the governor to steal the crystal, so the pair is thrown in jail and they stay there for ten years. Meanwhile, Markus uses the crystals to open a portal to a cursed city and becomes the Sorcerer King.

Act II: Let’s Fix It. After ten years in prison, Alex and Leon are visited by a hooded figure that turns out to be Lyla. She offers to free them from prison if they help her in her quest. What is her quest? Well, she wants to fix things: the idea is to find another set of four crystals and go defeat Markus to fix the great evil that Alex and Leon have unleashed upon the world. They start their adventures in Riverside and from here the quests can be done in different orders depending on player choices, but at some point the party ends up in the town of Sun Port, where they are joined by Vic, the wizard. They get the first crystal from the Old Tower, then explore many regions and towns and end up in Castle South, where we discover that Lyla is, in fact, princess of the South Kingdom. After that, onward to the dark side of the South Kingdom (where it’s eternally night) and that’s where they find the Ancient Monastery and defeat a demon there, obtaining the second crystal. After that, they walk through the Great Desert to explore the ruins of an ancient town, defeat another guardian and recover the third crystal, then return to find the mysterious North Keep. That’s when they learn of King Vahn, who, a thousand years earlier, sold his kingdom to the Sorcerer King (a different one back then, not Markus), in exchange for power. Belatedly realizing that selling one’s kingdom to an evil villain isn’t a very kingly thing to do, King Vahn repents and goes on a quest to defeat the Sorcerer King. Things don’t go too well for him, and he gets killed and buried in the Night Island. So our party of heroes ventures there to find his grave, picks up his armor, and proceed south to the Frost Lands, where it’s eternally winter. That’s where they start to hear more and more about King Vahn and they start to notice a striking similarity: Alex looks exactly like King Vahn. What an odd coincidence, right? They learn that legend says that King Vahn shall return, wearing his crown and ring and wielding his sword, to rule again. You guessed it: Alex finds these items, puts them on, and voilà, the king returns!

Act III: The King Returns. Well that’s great, your majesty, how nice of you to return after a thousand years, but the land is still in ruins because of the Sorcerer King and all, remember your mistake from a thousand years ago? Now, after finding the fourth and final crystal, the party of adventurers enters the portal to Ignis, the evil city, and survives its many perils until they finally come face to face with Markus.

Act IV: Showdown. Markus is actually quite surprised to see them, as he didn’t think they were competent enough to get that far, so he doesn’t have a very good speech prepared. Instead of talking, he just turns into a demon. The demon form seems more knowledgeable than Markus and says that King Vahn has already tried to defeat him 30 times, so that makes it unlikely that the king will succeed on the 31st. That’s incorrect statistical reasoning on the part of the demon, and in fact he is defeated… but wait, what just happened? Well, Alex defeated the Sorcerer King, therefore, according to the rules, he is the new Sorcerer King. Another plot twist. Alex turns against his companions, who he now views as obstacles to his power. The end the game depends on whether Alex surrenders or kills his companions… if he surrenders, everyone lives happily ever after (despite his friends mildly resenting Alex for trying to kill them and such). If Alex does not surrender, he becomes the new Sorcerer King, much more evil than Markus and will be in power forever… or until some other party of adventurers finds another set of four crystals.

Writing Style

One of my main conflicts when writing this game was the choice of writing style. It’s easy to be too cliché in RPGs and use excessively poetic language, making each little interaction into an epic feat of legendary bravery sung for ages untold. It gets old quickly. I also thought of an entirely humorous tone which constantly pokes fun at traditional RPGs, but too much of that and it reads like a satire rather than a game, which I didn’t want either.

So I settled for something in the middle, trying to make it serious enough to be believable but with some humor so as not to make it too dry.

Implementation: Rendering

The rendering engine was the first thing I implemented, because it was the riskiest part: I didn’t know if it was going to work or not, or if I was going to be able to figure out the math to do the “fake 3D” effect efficiently enough to run on the TIC-80’s simulated hardware. So first I used a good old-fashioned notebook to do the 3D rendering math, imposing a series of limitations to make the calculations easier:

  • Floors and ceilings are flat.
  • No stairs, no ramps, etc.
  • Walls are all upright (no slanted walls).
  • Sprites are billboarded, that is, they always face the observer.

With the shortcuts afforded by these carefully chosen limitations, I arrived at pretty simple formulas for rendering, which gives the game its early-90s pseudo-3D look.

Implementation: Virtual Machine inside a Virtual Machine

Here’s an interesting thing that caught me off-guard in the middle of development: the 64K of code allowed by the TIC-80 were not enough to store all of the game logic. I severely underestimated the complexity of the game at the beginning, so I thought I’d use ~32K for engine code, plus another 32K for the game’s actual quests, etc. But I ended up using ~62K just for the engine, and now I needed to write the actual game’s logic (quests, dialogues, etc) somehow. The remaining 2K were not enough.

That’s when I decided I needed to (ab-)use TIC-80s other ROM areas. In particular, a TIC-80 cartridge has space for 8 large maps. The entire world and all of its dungeons fit in just 1 map. Some other maps were used for UI graphics, etc, but there were 2 maps remaining (banks #6 and #7) that were not being used for anything.

So I decided to use the ROM space of those 2 maps to store something that was not a map at all: I’d store bytecode for a virtual machine that I’d write. I wrote the VM in Lua, squeezing it in the last ~2K I had available.

And how do I generate said bytecode? I wrote an assembler in perl, which took (barely) readable assembly instructions that look like this:

…and converted this into bytecode that got spliced into the cartridge as “maps”:

For lack of creativity, I called the assembly language “XL” (eXtension Language) and the virtual machine XLVM.

Apart from logic, I used XL to encode game data as well such as the item database. Here is the XL entry for the Battle Axe:


Writing this game was a ton of fun and it’s something I had always wanted to do since I started programming. Build it in a fantasy console was a good choice because it put the art style within the reach of my (very limited) artistic skills, and the limitations were pretty fun to work with. Plus, the fact that consoles like the TIC-80 already have a thriving community of users helped me quickly get to users who were interested in this type of experience. This channel for discoverability was much more efficient than what I would have accomplished if I had just launched this game on a random website.

I hope you have as much fun playing this game as I had building it!