One of the things I like to do when developing software is fail… fail fast, fail early because it means you’re not going to pursue an idea that is less than optimal. Well… ORE has failed, or more specifically my approach to it has failed.
When I originally started ORE back in 2006, I was using unDelphiX and whilst it suffered some rendering performance issues when using alpha blending, it did seem to cope quite well in every other regard. Fast forward 13 years and using a similar approach with OpenGL and it’s clear that if I continue the whole thing will just grind to a halt.
So what’s gone wrong?
There are two main things I believe that are causing the performance problems.
The first is simple a case of volume. The original version of ORE used a 32×32 tile grid and whilst this was OK, I wanted greater control over placement so elected to use an 8×8 tile grid which would render any size tile from 8×8 to 128×128 (and any multiple of 8 in between e.g. 32×64) with a standard tile size of 64×64. The net result is that for one typical ground tile, there are 63 wasted iterations through the same visual space that do nothing.
For any decent sized map, this is going to mean a shed load of wasted time.
The second I believe is the fact that I’m having to bind lots of different textures during the rendering process which is causing performance issues. Because I may need to switch textures for each tile, the rendering of a tile is wrapped in a glBegin..glEnd. Having done some reading it’s clear this is not the way to do things.
To get the best performance I need to start using the ‘atlas’ concept where all the textures you’re going to want for a particular rendering pass are in one texture. This allows a texture to be bound, one glBegin to be issued and then all required quads to be rendered before the glEnd.
I did think I may be able to solve these issues by pre-rendering layers to textures, but there is still a massive rendering overhead during the pre-render process, so sure I could muddle along and put up with a slow editor or I can fail this method now and move on.
Other side issues… the number of tile layers… just not needed. Take a look at Factorio… you can create great looking maps with the ground lay, and then a detail layer. And there’s me thinking about having 6 feature layers… totally unnecessary I think.
So where does that leave us?
Well, like I said… fail fast, fail early so you don’t waste too much time. At this moment, I’ve not lost too much time if I write most of it off, so that’s what’s going to happen.
I’m also going to change my approach… I want all the content to be easily configurable via Lua and a users ability to put images etc. in the right place and have it accessible to the game. To that ends, I’m actually going to write off the idea of having a dedicated stand alone editor and simply put the required editing capabilities straight into the game play engine.
For now, I’m going to fake up some data structures to contain some sample data and then focus on writing a renderer that has decent performance. From there, I’m going to start making an editor within the play engine.
So what lessons can we take with us?
Well, for one… accept that sometimes you’re going to make bad decisions that mean your code won’t yield the results you want. When I started on the map editor I was screwing around with meaningless things, like worrying about getting the cursor outline I wanted working… why? What benefit is that? There’s a mouse cursor for that. If I’d have carried on down that route I’d have implemented all the editor features so I could get data into my map and then I would have found out that it’s just not going to work. How much time would I have written off then? As it is, I’ve spent a couple of weeks working through stuff most of which I’m about to throw away, but that’s not a problem. I’ve not coded seriously and for any length of time for more than 3 years so I look at this as a bit of a warm up 🙂
Don’t re-invent the wheel… this may seem a bit hypocritical given I’m writing a game engine 🙂 but what I mean by that is take a look at existing products and learn from them. Much of my inspiration for how I’m going about implementing this is coming from Factorio. It provides maps similar to what we want (though their maps are for the most part random) and performance wise, they have it down. Their use of Lua and simple PNG images for all game content means users are free to create content. I spent some time last night looking at Factorio, specifically their excellent debug information, and I think I’ve worked out a plan to get similar rendering performance.
Smaller cells don’t necessarily means better looking maps. Factorio uses a tile layer for the land only. Everything else is stored using fractional map coordinates and is just placed on the map. So I’m going with 64×64 land tiles with fractional coordinates for everything else.
And so concludes this recap. Only time will tell whether or not I’m making the right decisions, but one thing is certain, I’m going to try and fail fast and early so if I need to rethink I’ve not wasted too much time.