Today I’m going to talk about tilemaps and why I choose to use them in Praedium
Firstly, let’s talk about why I’m going to use tilemaps within a text based game. Doesn’t that seem a little bit odd?
Well, by the first glance it may seem strange but the fonts are actually images too!
If you recall my post about refactoring the Malison library to support different fonts, you may have noticed the spritesheets for the fonts.
The reason for that is the fact that this approach is much more flexible and reliable for cross-platform support (we avoid any font rendering disparities - which, trust me are, are a common thing across different OSes or web browsers). The characters are simply small chunks of a bigger bitmap that works a spritesheet.
So now that we think about our characters as parts of a spritesheet, tilemaps don’t sound like a bad idea.
We can conveniently design areas outside of the game engine, add metadata to different tiles, export the map as a single file and then parse that at runtime.
Praedium will be all about farming and taking care of your farm - which results in creating buildings, tiling soil, cutting, gathering and planting crops.
That sounds like quite a dynamic environment but having even a simple skeleton to seed the initial farm from and then apply some procedural generation to create a starting farm is a much easier process than just completely generating that from the scratch.
Also, I plan to have more static areas such as the town, or maybe nearby farms where the player’s ability to destruct or create is very limited.
But tilemaps are not only about the visuals. As I have already said - we can add various meta-information to given tiles, or tile layers and even define some objects placed on the tilemap which then will be properly interpreted by the game itself.
Tiled Map Editor
For all those features I decided to choose the quite convenient Tiled editor. I also had some previous experience with it so it felt like an obvious choice.
Tiled supports giving many different meta-information to our tiles along with tile layers, object layers and objects themselves.
Example of properties I have set for some tile
For all of my tiles I have set the following properties:
Code- which is the CP437 character code.
Collideable- which decides if the tile blocks the player’s movement.
Background- background color in hex format.
Foreground- foreground color in hex format.
Now, the colors and code may seem strange at first. Why do so if the tile already shows a character we want?
Well, here is the thing - the terminal API provided by the engine expects from us to directly pass the code and colors. On the tilemap though we would only have the information about what tile from given spritesheet was used. No color, no code, no fun.
I’m not sure if Tiled has a feature to support coloring of the tiles within itself but I haven’t found it so I had to manually import different characters on different backgrounds and supply the meta-information by hand. A little bit of work but worth it in the end to easily design levels.
Still, if you have any better idea on how to work with it more gently feel free to drop a comment, I’ll appreciate it.
Now, having made a sample map, I exported it to the .tmx file and what was left was to parse it within the game code to create and render some objects.
To do so I have decided to use the TiledSharp library.
TiledSharp is a very convenient library for parsing and working with the .tmx file structure. We can easily access all the layers, tiles and custom properties we set inside Tiled to create some objects to render.
I’ll leave the technicalities of the tilemaps for the next post as I’m still shaping them up and refactoring the code.
Meanwhile have a look at the results, also including a font size change example:
Wrapping it up
As you may have noticed I’m trying to keep the posts shorter. Not sure if that’s for the better? But I had a hunch they are a tad too big. Hence the idea to split this one into two.
This allows me to focus more on the code too, long posts take me a while because I really care about the quality.
Well, if you rather would like less posts but richer in the content feel free to share your opinion!
Also, speaking again about Praedium - I have implemented some logic to act upon window resizing so the user decides how big the game screen should be and we act upon it correctly.
Other than that, I might be onto changing the rendering part and switching to MonoGame or optimizing it a little bit hence a giant number of tiles re-rendered each frame really eats up CPU mostly inside code related to the bitmap operations.
Well, that’s it for today, see you next time!