Weekly Content Blog #15: “Not Invented here”
Particle effects play a huge role in modern video games. Not only do they look fabulous and really add that extra juice to a scene, they are trivial to build… at least on paper. The tricky part about a particle engine is optimizing the creation and destruction of the particle objects, in addition to making those particle objects render fast within your rendering pipeline. The requirements Tim had for a particle engine were pretty standard (Basically, everything the Starling game engine could do. See an example here: http://onebyonedesign.com/flash/particleeditor/). I am also going to try presenting this post mostly in images (And GIFs) to show the progress from the beginning to the final product with some short spiel, so beware! Lots of images and GIFs!
The first step was to flesh out our emitter and particle classes. It obviously doesn’t look like much, and chances are the thumbnail appears only as a black box. (Click the thumbnail to enlarge it). The performance at this stage was incredibly poor; we achieved a meager 300 particles per 3.00ms. If we want to hit a frames-per-second rate of 60FPS, then we need to cram collision detection, drawing, particles, scene composition, pathfinding and entity processing in sixteen milliseconds. Having to allocate 1.00ms per 100 particles of our 16ms budget isn’t good enough. So the next step is to add an object-pool. If you’re not familiar with object pooling, what we do is create a large ‘pool’ of objects and then recycle these objects for our particles. Whenever we draw a new particle to the screen, we request a blank particle object from our initiated pool of particles, set the desired attributes and push it to our draw list. The advantage this has is then we do not have to create a new Particle class everytime a new particle is created. Constantly creating and destroying the same thing repeatedly is both expensive and wasteful. Once a particle is destroyed, instead of marking it for memory clean-up, we maintain a reference to it and add it back into our object pool.
Another bland looking thumbnail image. It will get better, I promise! With our object pool in place, our particle engine now performs at 1,000 particles per 3.00ms. Compared to some powerful particle engines that can push out millions of particles with ease, ours is terrible. But 1,000/3ms is good enough for our needs. Further optimization can be done down the line when we get closer to release. The next step is to be able to support multiple particle textures, so we can have a special fire texture that turns into a special smoke texture when the particle is destroyed. So let’s do that now…
(Click image to view the GIF) Now we can support multiple textures. But I look at what is finished compared to the requested features list and I groan. There is still lots of work to go, and we want to get this game finished. So what options do I have? Instead of maintaining a “not-invented here” mentality, let’s open Google and see what I can find…Well, hello Proton.
After discovering Proton and diving into the examples and some of the source, I ask myself an interesting question: “This does almost everything we need, is fast, looks fantastic and is easy to implement. Why am I re-inventing the wheel?” Less than thirty minutes after setting myself on Proton, I had it integrated with our game engine and had some simple but cool looking effects being rendered.
I greatly respect developers who build their own engines from the ground-up, it is a monstrous undertaking but choke full of rewards. But I’m of the opinion where if you’re not a successful developer with a large runway of cash saved up, you should drop the idea of building your own engine and use middleware; unless of course your goal is to create an awesome engine. But if your goal is to develop a game, pick an engine and create that game. There are no “best engines”, pick one and use it. Work around its flaws and keep pushing forward.
Trying to build everything yourself will only add to your development time, and although it is greatly rewarding if you can pull it off, the time expense in order to develop all of these engines and components can push your small project into an area where it becomes significantly harder to break-even or even make a profit. If you want to develop for the long term, you have to find a balance. Of course, we all have different goals. Some people are not motivated by economic rewards, and are happy in knowing that they completed something of substance. But if you are starting out as a small developer, drop the “not created here” mentality and instead focus on creating the game you want to make. Don’t waste time picking the “best and greatest” engine, choose one that you understand and clicks and work around the flaws; even the biggest game engines will have its quirks.