Since the spring I've been working on a game engine with SDL1. I wanted to do an adventure game with an emphasis on puzzles, and the map systems of classic Legend of Zelda games inspired me a lot.
The basic building block of this engine is the Room. Behold above, the first room in the test map. It has two floating computer-chip thingies that spin with a cool animation and cannot be walked on. It also has warps to three other rooms.
This header file for the room class shows that it's composed of a few simple things:
- a background spritesheet (composed of four frames for ambient animation)
- a vector of obstacles (invisible rectangles you can't walk on)
- a vector of fg objects (spritesheets with animation loops)
- a vector of warps to other rooms
- a vector of pointers to people
- a vector of pointers to event threads known as HyperKaos
Everything else in the room is about keeping track of and manipulating these things.
You may note that the vector of pointers to people points to "Players." Right now, they just have a default constructor used by the special Player "hero", but shortly I will add a more in-depth constructor to build NPCs with.
In addition to the data stored in rooms, we have some global data generated in chunks by the function bufferData() on demand, and stored in arrays for use on the map. These include rooms, textboxes, and event snippets. bufferData() and unloadData() both take arguments for the chunk of data to buffer/delete. After you have warped to the room in the buffered chunk (automatically buffered because warps have to know what chunk they are warping to), the old mapData array is deleted, and the buffer is pushed to mapData. The savestate is a product of unique prime numbers. When a special event happens, its kaosID is multiplied onto the savestate. By checking if the savestate is divisible by a certain prime nubmer or product of primes, we can dynamically change the game depending on if certain conditions are fulfilled by the player.
Setting up a map is elementary, if not a bit tedious because of all the numerical values. unloadData() has to delete the rooms, the dialogueData, and the kaosData. Destructors keep track of all the other stuff when we delete the rooms.
The HyperKaos system is extremely flexible and allows you to declare a whole bunch of Kaos elements, or little events, and chain them together in a HyperKaos. The HyperKaos has an associated rectangle in the room. They come in two types: passive and active. A passive HyperKaos will activate when you step on it. An active HyperKaos requires you to press the action button while standing on it to activate it. Right now I only have a few types of Kaos as proof of concept, but many more will be added as I continue to work on the engine. The possibilities are near endless for what can be done with this, and I plan to use a special data segment of HyperKaos chains as magic spells for solving puzzles.
The textbox system, as you can see in the above screenshots, allows us to just generate it as a static element when a chunk is loaded and store it in the global dialogueData array. It can then be added to a HyperKaos as a Conversation.
The engine supports (as of yet) a single save file, which works as you would expect, and stores the player's exact location along with the current savestate number.
We'll see where it goes from here. I still have to add sound effects, music, and lots more Kaos types to the engine, not the least of them magic spells. I've been slowly fleshing out the game world in my head, too, and will be excited when I can shift my focus from coding the engine to producing content for the game.