Skip to content

New Website

I added a new spiffy website for Tank Frenzy. It has a brief overview, some screenshots, and hopefully a video and a download soon.

Screenshots

Finished

We are done with Tank Frenzy. We demoed it and it seemed to be well received. I spent the last week on performance. I got to play with Intel’s VTune profiler, which is pretty cool. Turns out most of our slowdown was from using the standard template library. No surprise there. After all that I can definitely see why one would want to write their own data structures if doing anything serious. By the end of the week we were rocking a solid 90fps in release mode.

We will be getting a website with screenshots and video up at some point. Right now everyone is on vacation or out of town.

The Last Week

Today begins the last week of development. Four more days to get this presentable. We are getting close. I spent the last week working on improving performance, mainly in the collision detection area. We finally had to implement a partitioning system, and even though I ran into just about every headache imaginable, we finally got it working and our framerate hovers around 90fps. Now to work on making this actually a game and fun to play. AI still isn’t quite there, and our mission isn’t fully realized, making it difficult to play, but things are starting to come together. I still want four more weeks to playtest though.

Week 9 Render

A screenshot to let you all see what our game is looking like these days. The smoke particles are still being tweaked. Check out the lighting on the terrain and the player tank’s headlight

Week 9 render with lights and semi-working explosion particles

Week 9 render with lights and semi-working explosion particles

Deferred Rendering Issues

I’ve been spending the last week and a half working on my deferred renderer that I wanted done in the first couple weeks. Other stuff had higher priority and it has been pushed off until now. It took me a while to figure out how all the render target stuff works; I’ve never done anything like that before, but I think I have it all figured out now and wrapped up in a nicely organized DeferredRenderer class.

There is a lot of resource creating and management to be done in a system like this. I have to create three Texture2Ds to store the G-buffer data from the first pass and then three RenderTargetViews so I can write to those textures from the shader, and three ShaderResourceViews so I can read from those textures in the other shaders. The second, shading, pass needs its own texture, render target, and resource view, and then one final set for the output of the renderer that gets passed to the device which combines all incoming render targets like the one being sent from Colin’s GUI system.

I quickly got a directional light up and running and then proceeded to add more lights and more types. First up: point light! Unfortunately, I was getting all sorts of weird artifacts with my point lights; very strange horizontal banding. After much debugging and much anguish, and help from some fellow students and my professor, I’ve figured out that the problem is with the world position of each pixel during the shading pass. The first pass correctly outputs the depth map, but somewhere in the unproject of the screen x, y and depth, the position of the pixel is off. It is somehow related to the near and far clip planes and the position of the camera; something in the projection matrix or the view matrix? I can’t figure it out, I’ve been over the code and it should work. It has been suggested to me to try and use a different approach to recreating the world position, instead of using an inverse view-projection matrix, use the coordinates of the far frustum plane and store positions relative to that. Maybe it is faster since it doesn’t involve a matrix calculation? If it works I won’t care.

Here is the resource I’m going to be using to help me with this new technique.

Pathfinding

The ants go marching…

I’m feeling good about the pathfinding implementation we’ve got running for Tank Frenzy.  In our AI proof-of-concept, pathfinding was horribly slow (although it wasn’t designed for speed in the first place).  Therefore, our pathfinding in the real game has been heavily optimized:  The terrain heightmap is used to construct a nav mesh consisting of quads (the colored regions in the screenshot), which we run A* on.  Performance is much improved: it took 3-4 seconds for one unit to path on our demo 192×192 terrain; now, pathing is unnoticeable on an 1800×1800 terrain.  Even when 50 units spawn & path at once, the performance hit is only ~1/4 sec. (and we’ll just avoid doing that).

There are some issues left: navigating on a mesh is more complicated than pathing on simple waypoints.  We’re going to need some sort of string-pulling alg. to clean up the generated paths.

pathfinding

Threading the AI (Part 1)

I haven’t spent time lately writing to the blog, so there are a lot of additions I have made. Mainly I have added units, unit manager (added, removed and then added again), bullets, player, buildings. I also created the Lua interface for loading materials.

Since I am working on splitting the high and low level AI to at least 1 thread the functionality of the unit is important. In order to remove as many conflicts as possible the unit essentially has two control structures for the actions it can take. An example of this would be accelerate: Accelerate(DIRECTION dir) and Accelerate(float dt). The first of these is called by the NPC, player, etc. This function sets the direction to be used in Accelerate(float dt). During the update of the unit, in the main thread, the Accelerate(float dt) function is called to do all of the actual work. Updating the controlled unit, is not the objective of the AI, which is why it can be done during the main thread.

In order for the AI to have access to add new units to the game world a unit manager was created. Initially the NPC manager kept track of the units. Once this was split off on to a separate thread it caused issues. This was mainly due to a unit being halfway updated and then being rendered in the main thread. To counter act this the unit manager loops through all of the units during update in the main thread. Additionally when the NPC manager needs a new unit it grabs one from the unit manager.  The unit does not get added to the scene until the next update of the unit manager. This removes issues with adding or removing units in the middle of an update cycle.

When I started to write my threading system I immediately went off track from my initial plans. Mainly this was due to a realization my current method makes much more sense to me. My current system revolves around a scheduler, thread, task and task manager. The scheduler is my control for the rest of the systems, it controls when the threads stop, start, pause, get tasks, and where they recieve the tasks. It sits on a separate thread allocating work to worker threads. Upon initialization the scheduler determines the processor count of the system and allocates processors – 1 threads. Each thread is given wake, sleep and terminate events which allow for control by the scheduler. When the scheduler runs it loops until it is asked to terminate. During the run period it tells each thread to wake up and complete the set of queued tasks.  Once this is complete the threads go back to sleep and the scheduler allocates new tasks.

Threads created by the scheduler complete tasks set in the task manager. A thread is awake and completing tasks as long as the task manager has a task available. Once all the tasks are complete, the task signals it is sleeping, and waits for the scheduler to signal there is more work. The ITask interface can be implemented by a class, allowing for it to be added to the task manager. Tasks are added to the manager through the scheduler.

As this is a work in progress I will add more information later. On the upside, currently I am seeing a nice frame rate improvement: 100-120fps (threaded), 40-60fps (non-threaded).

Render Pipeline

I just finished cleaning up and pulling together the important classes for the render pipeline I wrote for Tank Frenzy. Zipped those up and wrote a brief overview. If you are interested in checking this out, feel free to download it.

AI

Base AI should be up and running.  It doesn’t do anything interesting right now: Pursue the player, shoot him and run back to base.  This is using a preliminary form of the behavior tree infrastructure, with the targetPlayer, Aim, Fire, Go and Wait behaviors implemented.  As opposed to the original design, the actual movement of units is executed asynchronously from the behaviors.  This was done to counter the proliferation of “Move and ___” behavior types, although it makes it harder to coordinate movement with other actions.

trivialpursuit2

NPC units chasing down the player