Roguelike 10 and Basic AbbreviatorPrint page
It exceeded my expectations that Roguelike 10 game written for the 2023 Basic 10-Liner competition end up at 5th place in PUR-80 category. Yes! And the 2nd place considering Commodore 64 computers only! Thus this
short article to celebrate!
Since 2021 I create games for Basic 10-Liner contest. I also participated in ASCII BASIC GAME 10Liner. I just love writing those tiny programs, so with no exception, I wanted to submit something also this year! Writing a game in BASIC that fits in 10 lines is not an easy task. But, this is where the fun begins! I have a few unfinished games from the previous year that didn't match my expectations, including a puzzle game called Pairs 10, but I decided to go wild and create a roguelike game instead!
Let's be realistic. Roguelike games are quite complex. It's not a secret that to create a 10-liner, I needed to drop a lot of features like gaining experience, having a variety of weapons or different creatures and plethora of other things you might find in roguelikes, like magic spells, shops etc. I have only 10 lines to fill with the code game, 80 characters per line. So, as long as exploration, rewarding and fighting - all these essentials could remain - it's still a roguelike by the pure definition. And one more thing, there are no "permadeaths" in Roguelike 10, however, in the end I tweaked the way creatures move so game might be unforgiving at times. And this is a good thing, because it's a roguelike game. But let's talk about it later.
I started working on the world generation algorithm first. Thankfully, it didn't take me too long to create a decent dungeons generator. I found an easy idea to draw consecutive chambers of different size one after the other. The end result turned out to be surprisingly good considering the code space it took up. The project started to look really promising!
Writing code for player's character movement where surrounding area is revealed was an easy task. Writing creatures movement procedures much more difficult though. Initially I wanted to throw into dungeons a random number of creatures that could move towards player's character autonomously. Adding an array of creature positions and controlling their movement took too much space though. I needed to make the first game design decision that only a single creature can wander per dungeon. Was it satisfying? Definitely not. But this is a 10-Liner. It's fine, right? Not too great though... The good thing is that I needed to revisit it later. Anyways, program started to shape into a game!
The challenge started to increase as the freedom of having a decent number of free lines (or rather characters!) didn't last too long. At this stage project didn't have any interaction with level objects like stairs, gold or health potions yet! Not mentioning the whole attacking mechanism. Editing and redesigning the code started to be a real headache.
The beauty of the Basic 10-Liner contest is that in PUR-80 category ("pure" 80 characters per line), BASIC keyword abbreviations can be used. If you're not familiar with this concept, take a look at the list of all keywords that can be shortened: https://www.c64-wiki.com/wiki/BASIC_keyword_abbreviation. If you're thinking I used e.g. to write PRINT, THEN and GOSUB then it's not the case. Instead of writing PRINT, I used "?" character, in place of THEN you can shorten it to "tH" and write "goS" instead of GOSUB. This is the beauty about abbreviations - more characters can fit per line! The downside though is that abbreviations are not preserved when program is listed. Unfortunately they will be unwinded. As the consequence, while editing these lines, they might take more than 2 rows. Each row has 40 characters, so 2 rows for 80 characters. When line consists of more than 2 rows, if you try to store the line back in the memory, the third row will be omitted! In practice, it means that you have to rewrite the whole line using abbreviations again to fit it in 2 rows. Practically speaking, any changes to lines mean you have to rewrite everything with abbreviations over and over again. I wrote 3 games this way. For my first 10-liner ever, Mimizuku Saga 10, I actually didn't use abbreviations at all. But for the next ones, I did! And I didn't want to write yet another one in this manner.
Basic Abbreviator to rescue
What if there could be a way to list programs with abbreviations? BASIC understands abbreviations, but why is it not built-in to list them back in a program? What if there could be a tool for it? I decided it's time to write one! By disassembling a program stored under $0801 location, I deduced how BASIC lines are stored, and I knew what to create. Interestingly enough, BASIC stores keywords not as words but as tokens. So, equipped not with the sword or a bow, but with the gained knowledge - in a single day - almost a fully functioning Basic Abbreviator was created. In the current version it's quite a simple tool that resides above BASIC program memory location. It's still unstable at times that's why I didn't release it, but does the job most of the time. How? With F1 key, BASIC program is listed with abbreviations. Simple as that! With F3 key, program can be run.
While working on the Basic Abbreviator, a small bug sneaked into the code so while listing with abbreviations, it produced rather impressive side-effect. A tiny entertainment for anyone who loves such glitches: https://youtu.be/WYECsIGmGm0. No one like bugs, but you have to admit the beauty of some glitches really makes development more fun.
A lot of ideas came to my mind while using this tool, however I knew that I am sitting in front of computer not because of Basic Abbreviator, but for the sake of Roguelike 10 game, our main hero!
The first gameplay tests went smoothly, no bugs, no weird behaviours, it's done! But after playing it for 5 minutes, game started to become just dull... Do you remember the design decision I made? To throw only a single creature into each dungeon? This one started to bite. Not the creature whatsover, but the dullness... The game balance was just off. Avoiding a creature was a cup of cake. But hey, it's because I didn't have any free space left! Remember? And this is the part that surprises me about 10-liners the most. There is always (well... not always-always) some space, somewhere, somehow... And with my main weapon - Basic Abbreviator - it must be easier to play with code now! What if I could add more creatures? They could surround the player, so the game difficulty could potentially sky rocket. But I didn't have space for any arrays to control each creature, and no other tricks seemed to resolve it at all!
Not keeping you too long in a suspense, let me say straight away that it didn't take me too long to have an eureka moment. What if creatures' movement would be part of surrounding area reveal when player character moves? What these two things have in common? Nothing! But then, code doesn't even need to store position of creatures at all. That position is already known - is just under the field that was revealed. So, code just needs to check where to move that damn unholy creature. In order to save more space, I also wrote tests for this part, so I could simplify equations and still be certain that code does the math properly. With tests it was way quicker to validate that creature will move towards player's character as expected.
And believe me or not, thanks to this, I was able to display HUD as the improved method of creature movements freed the necessary space in the program. Yes, HUD, the statistics about player's HIT POINTS, dungeon LEVEL and carried GOLD. I almost forgot about it. This is also essential for roguelikes, right? Here you go, anything else to add? I managed to add RIP (Eng. rest in peace, Lat. requiescat in pace) in case of the game over. And to be honest, I don't think anything more could be squeezed into the code. In the end, 15 free characters left but spread in several lines. Eventually, there is a limit for 10-liners.
Basic 10-Liner contest results
To sum up, this is my 5th finished Basic 10-Liner game. And I hope you will have a lot of fun! In the overall PUR-80 category, Roguelike 10 end up at the 5th place out of 37 games which is really a great result for me! Among the games for the Commodore 64 only, it took 2nd place, losing the first place to the very nice Lumberjack by Roman Werner, the creator of such great Amiga games as Traps 'n' Treasures or Leonardo.
You can find all the results on the official website of the Basic 10-Liner contest: https://gkanold.wixsite.com/homeputerium/results-2023
Basic Abbreviator - from a tool to a toolbox?
I am not certain if I would finish this game on time if not my dear companion, Basic Abbreviator. It was a great adventure to create this tool and use to create a game. Not the last one for sure, so I am considering to extend the functionality of that tool for future projects. To make a powerful and complete toolbox from that tool. Listing with abbreviations is a big thing, it removes most of the burden with rewriting into BASIC abbreviations. But while working on the game, I missed a lot of other features that would definitely make life even easier. Searching for variables through a tangled code, or rewriting part from one line to another takes time, and effort. And it's a big distractor. Copy & paste, smart command shuffle to the next/previous line, searching - those are only a few things I really foresee as great tools that should be part an integral part of this toolbox.
Let me know if you're interested in the future development of Basic Abbreviator, and if you would like to try it out! I might consider even a cartridge release as it's a lot of fun to create these crazy projects!
Hail Basic 10-Liner contest for the inspiring challenges! See you the next year... in the next competition!
Where to play Roguelike 10?
Feel free to download it, or play in your web browser from here: https://commocore.itch.io/roguelike-10
Enjoy surviving in the dungeons... in 10 lines!