I just graduated as a composer and have just started as a developer, the principles of motivation and efficiency in finishing a project are essentially the same. Reading your blog has inspired me to keep my head down, good timing seeing as though i had a doozy "stuck" day.

The thing with "engines" is, that one must find the right relation between abstaction and implementation.

A too abstract/general gameengine/framework and the game wont finish or blow out of proportion.Too "hacked" and direct, and the game might die from the inflexibility to change anything later.(especially when continuing on the code months later)

It's a good post! I'd like to throw in a small (or so I thought >_>) tip on why it's okay to hack together solutions and how making small test programs can make it easier to find bugs...

I've never been a fan of quickly hacking something together just to get some results quickly. That's probably the one thing I hate most in life; redoing things because my first attempt wasn't good enough. I always tried to write a perfect object handling system, a perfect graphics system, e.t.c in all my games, and granted I pretty much never got anywhere. Of course I learned a lot about coding (the usual excuse) but the most important point is that it was never perfect, and I always kept on re-coding those perfect systems/modules when I realized the puzzle pieces didn't fit together in the end, or I wanted a feature that I had failed/forgotten to consider in the first place. Therefore it's important to not spend too much time on individual parts of the game, because there's a big chance that those things will have to be changed as the development progresses, either just with minor changes or complete rewrites.

For example I was working on fog of war for the RTS game I'm developing and I used a 2D lighting system as a base for it. It relied heavily on frame buffer copies and geometry for the vision "shadows", produced very ugly shadows, ate CPU clocks like no tomorrow and had massive tile overdraw on the GPU for shadows, and did in no way satisfy my goal of 1000 units at the same time. However, despite my perfectionist nature I decided to not try to optimize it too much. I could've spent tens of hours adding shadow culling, shadow geometry batching and threading, but I DIDN'T, and I'm proud of it. Instead I focused on other parts of the game, namely my entity system and unit stats, vision ray-casting and started working on scripting when I suddenly came up with an awesome solution. Instead of drawing shadows as geometry I uploaded the wall data as a texture and did some ray-casting in a pixel shader instead. The result was close to 0 CPU load and almost no overdraw, and performance was through the roof without any optimizations that destroyed code readability. Even 1000 units took only 1-2ms of GPU time while the CPU didn't do almost anything at all, and even better I also had perfect soft antialiased shadows now. If I had focused on optimizing my original algorithm, I would have less than 50% of the game parts I have completed by now, and still worse performance. And mentally I would have a lot harder accepting that all my optimization was in vain when I eventually came up with my new algorithm.

Never treat your code as final. You never know exactly how to implement your whole game for even mildly complicated ones, because if you did you'd be a Vulcan. I'd also say that this is 10x as true when working with other programmers. You never know which things won't work out performance-wise, what you've forgotten to keep in mind and what simply put ends up being impossible before you actually start coding it. Coding is not like constructing buildings. You don't have an exact blueprint, perfectly chosen materials and stress simulations proving your building will stand once you complete it. The base of your program isn't a foundation in the same sense as in construction; it's 99% of the time temporary, and just there to give you a better picture of how the higher floors will look like. Once you start coding the individual floors it'll be much easier to see where and how the floors don't fit together. If you've declared your current code "completed" you'll have to adapt every other part of the game to that completed part, and in the end the pieces probably won't fit together.

I'd say game making is like ice sculpturing or maybe even any art form. You wouldn't start with making a perfect nose on your ice sculpture. You'd start by roughly cutting out the shape of the whole sculpture, and then polishing each part without focusing too much on each individual part. The same is true in drawing/painting. You wouldn't start sketching on a single part of what you're drawing, and then instantly proceed to filling in lines, coloring and correct lighting. You'd sketch out all the important places before moving over to more detailed drawing to ensure nothing looks weird.

Let me just tell you again: I hate this so much. I want to just code something once and then leave it forever, but I've simply had to accept that that doesn't work out in practice. However, I have been trying to reduce how much I rewrite code by simply creating lots and lots of test programs. Whenever I have something new to implement into my game that require even just minor integration I make a test program for it. I started doing this pretty much naturally when I started using OpenGL since it's so easy to break all rendering in your game with just a simple one-line mistake or two. This gives you lots of advantages over trying to integrate it straight into your game:

- You'll be able to catch the really bad ideas very early, and you won't have to vivisect your complete game to get the new code out if it simply doesn't work out at all. Less potential frustration! - It's much easier to connect your game with your new code if you have two separate parts to connect rather than trying to connect the loose ends of a tumbleweed, and again, you can focus on solving bugs in the new code before also having to deal with integration problems. - You'll (hopefully) create less dependent code, since your small test should only contain the bare minimum to run and show relevant data for your new game component. Not allowing yourself to create spaghetti code is a better solution than thinking "Just this time..." every time you link together your entity system with your terrain rendering.

Writing the test should be fast, and obviously take less time than fixing both integration issues and bugs in the new code at the same time. For each big new component I usually create at least two test programs: one to test the idea and one to test my working code. Going back to my fog of war example I first did a small vision circle rendering test. I noticed all the problems I listed above (CPU performance, GPU performance and quality) and I did some performance test and tested some ideas for improving the quality at the cost of GPU performance. I also tried to estimate the additional cost of a full implementation, and could already see which problems I could be encountering when implementing a complete fog of war system. Note that the test program was very small and pretty much only drew shadowed circles and didn't support overlapping vision circles. Since the idea still worked but "just needed some optimization love" I decided to go on and implement a full system. The next test was even smaller and just rendered the texture produced by my new FogOfWarRenderer class to ensure that my implementation was working. Only when all OpenGL scissor test related bugs and off-by-one-pixel errors were fixed did I try to integrate this into the game.

Fog of war requires heavy integration into my map renderer so that not seen places are grayed out. This required changes to the pixel shader of the terrain renderer, and also some OpenGL calls to bind the texture, e.t.c. Consider the potential catastrophe of trying to do all these 3 steps at the same time. I wouldn't have a clue about the performance problems before everything was done. At that time I wouldn't know if that was because of a bug and I'd have to start cutting in my own game to benchmark the different parts. I would pretty much have had to start with editing the map renderer to be able to show the fog of war texture since I wouldn't be able to determine if the fog of war rendering worked unless it appeared on the screen. If a bug then caused nothing to be rendered, it could be anything from a bug in my shader, a bug in my texture setup code, a bug in my frame buffer code, a bug in my light rendering code, a problem with leaked OpenGL state from the rest of my game that had gone unnoticed, the list is almost endless. By testing on different levels I could easily eliminate these possibilities one by one instead of having to go psycho surgeon on my whole game to solve the new bugs.

TL;DR / continuation:On average I'd say that my new extensive testing habits have reduced the time it takes for me to get results a lot, even though in some cases it might have been unnecessary to do the amount of testing I did. The main point of testing like this is not to reduce the time it takes to write code; it's to reduce, or rather, to normalize the time it takes to debug code. By doing this you'll never get into a hopeless situation where something's not working and you have no idea where the problem(s) is/are. Take small steps when programming so you don't ruin the game you're making with too many new hard-to-track-down bugs, make sure all the new code you write is working and bug-free BEFORE you integrate it and add it to your game, and don't be afraid to replace your code when you realize it didn't work out as you thought.

On the other end of the rewriting spectra, if you realize that everytime you want to add a feature you have to rewrite a big part of your game, you're doing something wrong. I've been there and done that so many times, and it kills projects faster than you can say "F*ck this sh*t!" and go back to WoW. This is usually because of spaghetti code though, so it's kind of unrelated...

Okay, now it seems like I'm trying to steal the show from Kevglass here, and nobody will probably bother to read this through... Don't worry about my punishment though, I have a kanji test tomorrow... Hopefully I can score 40% or something on it...

Well put.To emphasize your first bullet point, look at Duke Nuke-em Forever. They started with the Quake Engine then changed to the Unreal engine. And look how long that took to come out.Focus. Stay focused.

It looks like it implements its own GLSL interpreter targeting a software framebuffer, so it's bound to be slow as sin and won't replace eyeball tests entirely. Still useful for testing logic though, so it would be nice to see a java port of it if anyone was up to the tedium of doing it.

It looks like it implements its own GLSL interpreter targeting a software framebuffer, so it's bound to be slow as sin and won't replace eyeball tests entirely. Still useful for testing logic though, so it would be nice to see a java port of it if anyone was up to the tedium of doing it.

@theagentd sounds similar to TDD? heard lots of good things about that but never got around to actually trying it yet.

It sounds like an informal version of TDD (and a very sensible approach). The way he describes it, the tests aren't automated. I suppose that is a fairly important distinction from what advocates would call 'proper' TDD. Also the features he describes are relatively large and complex; one might combine the approach he describes with even smaller unit tests precisely defined aspects: for example, he might have specific tests for things like 'off by one pixel' type errors in his fog of war system as well as the program he can run to eyeball test the whole fog of war system.

Personally, I've flirted with unit-testing and indeed found it quite useful at times... I could see the benefit of doing it more properly, but haven't quite gone that far. Maybe on the next project...

@theagentd sounds similar to TDD? heard lots of good things about that but never got around to actually trying it yet.

It sounds like an informal version of TDD (and a very sensible approach). The way he describes it, the tests aren't automated. I suppose that is a fairly important distinction from what advocates would call 'proper' TDD. Also the features he describes are relatively large and complex; one might combine the approach he describes with even smaller unit tests precisely defined aspects: for example, he might have specific tests for things like 'off by one pixel' type errors in his fog of war system as well as the program he can run to eyeball test the whole fog of war system.

Personally, I've flirted with unit-testing and indeed found it quite useful at times... I could see the benefit of doing it more properly, but haven't quite gone that far. Maybe on the next project...

Truly. Even having a handful of tests that require eye-balling for correctness can be a big help.

Don't let perfection get in the way of the good!

I'm trying to write a test for a bit of code that processes real-time events (usually GUI generated, but here, they will be generated via a separate thread where I will create some specific test sequences) and converts them into actions on a per-audio-frame basis. It is a bit gnarly for me, but am making progress. I think having it will be a big help in trying to profile & improve some of the audio processing I'm working on.

Great blog post, also! Looking forward to more.

"We all secretly believe we are right about everything and, by extension, we are all wrong." W. Storr, The Unpersuadables

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org