Sunday, December 16, 2012

Room (or scene) loader for games with non-linear storyboard

In a game with linear storyboard when the player completes the tasks in the current scene/room (henceforth: room) then the loader reads the next record from the rooms-file where all rooms are stored and the core engine of the game designs the next room.

This is the case in almost any platform, arcade game, like it is Pac-Man, Solomon’s Key, Bobble Bobble, Bob Jack etc.  But this is the easy case, the good one.

Recently I have uploaded my new game for java-phones called Vampire. You can find more details and how to install it on Liknongames - Vampire. It is a platform, multi screen game where the main ghost-like character walks inside a complex castle searching for the vampire.  On his path there are a lot of unfriendly creatures and lethal traps.

Here is a part of the huge map of some rooms in the castle including the starting one. Every rectangle with white border is a room of the castle.

Picture 1
As you can see there are rooms with one, two, three or even four openings that lead to another  room in other floor or in other side, thus it doesn’t make any sense to speak for “the next” or for “the previous” room.

Let us see now how I store every single room and how I implemented this navigation system. It will help.

This is a screenshot of the room at the right side of the starting one. 

Picture 2
You understand now that It has no meaning at all to say “…this is the second room…” because from the starting room he may either fall into the (trap-)room or exit from the right edge of the room.

And this is exactly what I am going to explain in this post: How to make an automated navigation mechanism that is responsible for the transition from one room to another in such a game world where there may be openings in all sides of the current room.

Vampire is a tile-based game. Every room is a grid of 16 cells along the horizontal and 8 cells along the vertical direction. So there are 128 tiles in each room.


Picture 3
There are (and will be) about 200 different objects (tiles, enemies, goodies, etc).  Each kind of object is given a numerical code used also for the storing into the file. So, I need values from 0 to 200 (0 is the value for an empty tile).  As we know, one byte is enough to keep such a value since a byte can keep 256 different values.  It means that each room can be considered as a sequence of 128 bytes.

Inside the rectangle is the part of the binary file with the values of the bytes of the room of the screenshot in hexadecimal system.


Picture 4
How ugly is it, isn’t it? Let’s remove the 00’s and we get a friendlier and already known picture:



Picture 5
Yes, this is the same room in picture-3 seeing it through X-rays.
Short F.A.Q. about this actinography:
Q: In the upper row I see only green tiles. The values however are different: 0x42, 0x43,0x4D, 0x45…
A: The tiles are different too. Stare at them carefully and you can see slight differences.
Q: What is the “74” in the middle column?
A: This is an almost hidden canon that throws arrows if the player is in its height and on its side.

Q: I see a “97” in the middle column under the “83” but nothing is it to be seen in the screen:
A: This is an completely transparent tile. Its value is out of the range of the tiles the player can collide with, however it belongs to the range of values that the enemies can collide with.  It forces the bird (62) in the same row not to reach the blue wall at the right, but to bounce earlier.

At the upper left side of the rectangle there is a value, 00000180h. It is the position in the room-file where this screen is started from. This is in hex. 0x180=384.

From the 384th byte begins this room. How many rooms are stored in the file before it? Since every record that represents a room has a constant length of 128 bytes, we have 384/128 = 3 rooms.

After the player has passed the right edge of the starting room the loader knew that it has to spring to the 384th position of the binary file that keeps all rooms and read from there the next 128 bytes.

How did the loader know this?

For this reason I had to split in tiles not only the room but the entire map of the game and use a coordinate system to specify the location of a room into the castle starting from the room 00x00 to be the leftmost room in the lowest basement of the castle.  The first coordinate is increased by +1 from left to the right and the second coordinate is increased by +1 when climbing in a room on the ceiling of the current one.

By this addressing the rooms in the part of the map in picture are assigned with the coordinates as in the picture


 Picture 6
Oh! I have just given away that by the starting of the game you are already in the 7th floor !!!!

Now that we always know the exactly coordination of a room in the map of the castle that is going to be visited it is easy to know from which position in the rooms-file to start reading from.

One thought would be to extend the record that stores a room from 128 bytes to 130 bytes,  keeping in the first two the coordinates of the room.  Then every time the player touches an opening the loader would scan the entire file with the levels trying to identify the possibly “next” room with the values of these first two bytes.

However I decided for a more clear solution.  I introduced another file that correlates map-coordinates into positions in the rooms-file. The first idea was to store in it records of a length of 4 bytes. The first two are the map-coordinates and the last two a short value of the position in the levels-file. 

Finally I decided to keep for the position only one byte since the position is always a multiple of 128. Thus, I multiply the value of this byte with 128 and I have the position where the pointer in the levels-file has to be spring and read from there.

I hope I didn’t ruin your mind.

If you like it please leave a comment, share it, or give it a "g+1".

In a “coming soon” tutorial I will describe how to design rooms with a freeware tile editor and how to produce from the xml (its output) the room file and correlation file.

No comments:

Post a Comment