This is the first in an (N) part series of articles based upon a small spike in the traffic to my blog. One of the more frequently sought for and read pages on this blog is Seven Essential Elements of a Tile Based Rendering Engine. This was an article I wrote over a year and a half ago as a crib sheet for the concepts put forth within my first book, with the equally unwieldy title: Isometric Game Programming with DirectX 7.0. Oddly enough, the original title I had for it was Isometric and Hexagonal Game Programing. The “and hexagonal” part was ripped out by the publisher as making the title “too long”. The “with DirectX 7.0” part was put in there at the behest of Microsoft, who was busy putting out DirectX 8.0 at the time.
My overview article states things in a rather editorial and sweeping manner. It seems relatively obvious that the folks looking to that page are seeking more in-depth coverage, and so here we go:
For brief review, so that you don’t have to go to the summary page, there are seven essential elements to a tile based rendering engine. These are:
- Visual Asset Manager
Having listed them, we shall now deal with the “zeroth” element, which precedes all others. The zeroth element is: Planning.
In planning, I do not mean that every last aspect of the rendering engine needs to be planned out in the minutest detail. Generally speaking, this sort of thing will not be helpful. In the same vein, however, not planning at all will give you a very nasty mess eventually.
Having said that, I’ve also done my rendering in CGA, EGA, VGA(all under DOS), GDI, DirectX versions 5-9, VB PictureBoxes, C# Winforms PictureBoxes, the HTML DOM using <IMG> tags, OpenGL, SDL, XNA, Flash, Silverlight, and doubtless others I cannot remember. Each method has its own peculiarities, especially with dealing with Z-order, which is a common issue. Each of these manners of rendering I tend to call a “rendering environment”. They fall generally into two categories: those that deal with frame buffers, and those that deal with visual elements on some sort of persistent “stage”. Managing each has its own concerns, but still, the principles remain the same, even though the strategies dealing with them differ. You must develop skill with the rendering environment.
Another important concept is what manner of rendering are you looking to do? Do you need a square/rectangular grid? Do you need an isometric grid? Do you need a hexagonal grid? I look into each of these when the differences between them are enough to warrant more exploration. However, generally the principles are similar.
For the purposes of these articles, I will primarily be using C#, for three reasons. One, it is sufficiently like most of the other imperative languages so that the syntax won’t get in the way of understanding. Two, with C# and the express editions of Visual Studio, one can target Windows desktop, the Web (through Silverlight), and XNA, often with little to no code change. Three, garbage collection. In a non-GC language, the code would be cluttered up with a lot of memory management hoo-hah that is really unnecessary for illustrating topics.
Part of planning is organizing the project. For the moment, we will assume a project that will target Windows(WinForms), Silverlight, and XNA. We won’t use WPF on the Windows client, as it would make it too similar to the Silverlight client. In order to do this, we need to have all of the tools installed and ready to use.
Also, we need some sort of image asset editor. Paint .NET is a really good choice for this, but I’m not here to tell you what to use. I’ve done projects using nothing but MS Paint. I suggest Paint .NET because the price is right. Inkscape is a pretty cool drawing program, too, with the same price point.
Games by their nature are abstract simulations governed by rules. While we often think of a game as being the images on screen or the tokens on a board, in reality these are just markers to represent the state of the game. As a result of this, I almost always split out a game’s logic from the game’s representation on screen. In languages like C#, this is most easily accomplished by having an assembly .dll that stores game state and provides an interface for manipulating that state, with a separate executable that consumes the .dll and does the rendering. Most languages and platforms support some sort of method of keeping these items separate. The big rule here is that there is *NO* rendering allowed in the game’s backend, and *NO* game logic allowed in the front end. Keep this rule.
Finally, after developing a game idea, have a decent idea of what sort of capabilities your rendering client will need. It doesn’t have to be perfect, but the basics should be there.
Let us say, for example, that we were going to make a game of Reversi, which I figure many people are familiar with. If not, check Wikipedia for the basics.
One of the first things we need to know is what sort of tile grid would we like to use. If we go with a square grid, then we don’t really have to worry about images that overlap. With an isometric grid, we probably do, although it could be constructed so that the pieces did not go outside of the bounds of the rhombus. If we decided to make a strange hexagonal ruleset based on regular Reversi and went with a hex grid, we again would not need to worry about overlap of tiles. Overlap of tiles is highly important for the rendering. If there is no overlap, then it doesn’t matter what order things are rendered in.
So, the basic idea is to try to get a little perspective beforehand, and do a bit of planning in order to maximize your work on the other portions. Do not, however, overplan. Software development is an iterative process. You will make some sort of mistake along the way, and some bad decisions. Yes, they are more expensive(time and effortwise) to fix the later in the project they are found, but if you attempt to plan everything, you never get started.