Friday 15 July 2016

Lenk's Quest part I: Game design

Not all those who wander are lost 
J. R. R. Tolkien

A good adventure doesn't require a map but at times one can be quite handy. Especially in the case where one is building something complicated out of components that are not. In order decrease the likelihood of finding Lenk's Quest deep in a swamp populated by spirits of never finished projects, I present thee the Document of Design.

Project's roadmap, artist's interpretation

Hardware limitations


Programming microcontrollers differs somewhat from programming a personal computer. With computers the question I repeatedly ask myself is how can I do this? Whatever I want to do they have the juice for it.

Microcontrollers, on the other hand, are not steam engines that can push through everything. They are more like low-profile Segways that get stuck on the first pebble they come across. More appropriate question is what can be done? The programmer needs to turn their brain into the Haiku-mode and try to come up with creative solutions to squeeze the most out of the scarce resources and stringent limitations. I find this a refreshing challenge.

So, what do we have? First of all, I want to use my 16x2 character display (LCD1602) which needs two pins for I2C communication. If I had similar I2C I/O expander chips like the display has, I could connect as many buttons as I wanted (8 per chip) and still use the same two wires as the display does. But I don't, neither do I have any other sensible mean of serial communication.

Thus using ATtiny85 I have 3 free I/O pins for buttons, one per each. Not too bad. I only get half a D-pad but considering that my screen has only two rows of text, I think I can cope with that.

What about sound effects and music? I have a few ideas but I haven't tested them yet. There are some technical complications that I'll go through in a separate post. Getting an earworm infection from a suitable tune has suffice for this project.

Program flow


The program structure is similar as in The Torment of Alfred McSilvernuts. In the main program I'll first initialise everything, like configuring the pin directions and setting up the counter. Then the execution moves on to the infinite loop that does nothing.

The loop is interrupted by a timer that overflows approximately every 16.7 ms, aiming for the frame rate of 60 per second. All the action happens in the Interrupt Service Routine where the chip reads whether the buttons are pressed or not, executes the next of the game logic, and draws stuff on the display.


To make the game more interesting, I want to have more than just a one level. I also want that my game has a title screen that pops up at the start-up, and an ending screen that tells the player whether they have won or lost the game. I think the best way to do this is to break the game logic section into separate pieces for different states, like this:


What comes to computer games, I believe it's a common practice to separate the graphics from the game logic. However, with my hardware updating the whole screen takes a relatively long time that makes the display flicker. Not a good thing for the game play experience.

Fortunately I don't have to update the whole display every frame as normally only small portions of the screen change. I wouldn't want to mix the graphics into the logic but, for now, it seems to be the smartest solution to update the part of the screen immediately after the corresponding part of the game logic (e.g. character moves a step) is computed. I'm not completely happy with it but this way I don't have to think how to store and pass the information to the separate update function.

Game mechanics, objective and dungeon design


As a Legend of Zelda ripoff inspired piece, the 'camera' will be viewing the game area from the bird's perspective. Since I have only 3 buttons and two rows of text on the screen, it is best to limit the rooms (or levels) to a single dimension: the horizontal one. This way I need only two buttons, left and right, for the moving. The third button can be then used for different kind of actions, like attacking with the sword. I'll call it, not very surprisingly, the action button or the A button for short.

As the movement is limited on the one line, the other one on the screen can be used to present the wall of the room. There are some positions on the room where pressing A will make the player switch the room instead of attacking. These spots are indicated to the player by placing a door on the wall right next to them.

To make the game a game, we need to add some challenge. Let's say that the objective of the player is to escape the dungeon. This can be done through a locked door. The player has to get the key but it is guarded by a ferocious werewolf who tries the kill the player. To get the key, the player needs to slay it first.

Putting all these ideas on the paper, the dungeon turned out to look like this:


I decided to settle for two rooms. This way the middle row (one with the open door) is visible all the time: on the top row of the screen when in the lower room and on the bottom row when in the upper room. This gives the player a sense of the shape of the dungeon. If the wall was always on the same row, the player would have hard time to get a grasp of the geometry as the camera would appear to turn 180 degrees around every time they pass through a door. This solution is not limited only to two rooms. I could add an arbitrary number of rooms like this:



I just don't have any real content to be put into them. And nothing's more frustrating in video games than doing something totally worthless. It's like taking The Hobbit and stretch it into three movies.

The rooms are short so they fit into a single screen. This way I don't have to implement camera scrolling. It would not be very complicated, but certainly more than my game needs.

You can see that the door is positioned in the middle of the screen, two tiles away from the player's start position. This way the player can test and get used to controls before entering the second room. There's also a suitable distance between the door and the werewolf, so the player won't get their ass kicked immediately at the doorstep.

The last thing I want to mention about the dungeon design, is the bottom left corner of the screen. You may have noticed that the lower room is a bit shorter than the upper one. That's because I need a place for the health counter. It is nice to have all the counters at the same position on the screen at all times, so I made a part of the level impassable, so the player can't step on the counter.

---

Now, with the roadmap of objectives established, we're ready get our hands dirty. I think the best way to continue is to get started with graphics. After all, the easiest way to make sure that the things are working is to see them in action.

No comments:

Post a Comment