For my real-time strategy game Zyrtuul I need to be able to load different landscapes at run-time. A fundamental part of this is loading terrain heightmap data from script. I implemented this last night. I noticed that many people have been asking how to do this online, but I did not see any complete solutions presented. It turned out to be significantly easier than anticipated. This implementation allows you to save your heightmap using any image format (I assume it is saved in Assets/Resources/Heightmaps). Simply attach this script to your terrain object and it will load up the specified heightmap automatically.
Wednesday, February 19, 2014
Sunday, February 16, 2014
Experimental Art and Design Work for Zyrtuul.
Posted by
Damien Classen
Work has been busy at the moment and I was feeling a bit worn out, but I still felt like doing work on Zyrtuul. So I decided to take a break from programming for the weekend and focus on the artwork instead. I started off searching for source material and looking for inspiration online, in an effort to settle on an overall look for the user-interface, splash screens and overlays of Zyrtuul.
For a while I was attempting to take rendered images of various vehicles, super-impose them over a background and then modifying them in Photoshop to fake a hand-drawn / painted feel. I was initially happy with the results, but after comparing them to other games' splash screens I realized that, while they were okay, they weren't great.
After that I decided to stick with my original plan, using more generic spacey images, which are much easier to make (there is a lot of good source material out there that you can combine to get a unique-looking, visually appealing final image). The image below is still experimental and not final, but gives some indication of what I'm thinking the overall look and feel of the splash screen will be.
I had already designed the look of the mission select screen, but I wasn't 100% satisfied with its current state so I spent some time tweaking that as well. I still don't think it is perfect yet, but it will suffice for now. The current mission select screen can be seen in the image below. It may be too dark to see, but there is a square spot reserved for a top-down image of the map near the top right of the screen. I haven't implemented that yet though (the game is still in the rough early stages).
As the artwork starts to look more polished, elements that I previously liked no longer seem as good as they did. This was the case with the in-game overlays (which I put together sometime last year). These include the minimap border and the 'command panel' (that is, that panel where command buttons such as 'move', 'attack', 'stop' and 'patrol' would appear). In addition to that, I felt it was time to change the way resources are displayed (previously I just had placeholder text at the top-right of the screen). I have put all three in-game overlays into the image below to show what they currently look like.
At the top is the minimap border. The minimap would appear in the square black region. Below that is the resource display panel. When in-game, a number will be shown for each resource type. Below that is the command panel. When in-game, if a unit (that is, a vehicle or building) is selected, buttons will be displayed in the command panel. These allow you to issue commands to the unit.
I was happy with the way the terrain looked, but I felt that some textures looked better than others. I spent a few hours making new terrain textures yesterday. I wanted uber-high levels of detail, and so I composited various images together for the diffuse maps (I've had a lot of practice so I'm getting pretty good at it). I then manually constructed normal maps in Photoshop. Ordinarily, converting the diffuse maps to greyscale and then using that as a heightmap will, although a cheap hack, do the job when using it as input to construct a normal map. However, I wanted a very specific look, and so I instead (painstakingly) constructed the height and normal maps. It is difficult to clearly see the results from the screenshot, but they look very good when viewing the game at full size (especially when combat is occurring, due to the way weapon lights interact with the normal maps).
The final bit of work on Zyrtuul for the weekend was done this morning. I wanted to settle on the game factions and their banners / logos. This took surprisingly long (it took me many hours to do the banners). This is what I'm sitting with at the moment (the logos at the top-right of the image).
Deciding what the factions would be was difficult -- it often feels like most of the good ideas are taken already, and so coming up with something genuinely original seems impossible. They say that most stories are just variations on a few common themes, and so I consoled myself with that thought and decided to just settle on something.
The idea of an empire vs rebels is very cliched for obvious reasons, but Star Wars wasn't the inspiration for that (although now that I have made that connection, I'm wondering if I need to change this). Anyway, I may end up changing this, but the inspiration for this was actually Spartacus.
I thought the idea of designated slave planets would make for a good story -- entire planets whose populations are automatically born into slavery. Groups of slaves are periodically 'harvested' from these planets and brought to work on the elite planets. And, of course, such a situation would inevitably result in rebellion, which would then require those in power to quickly squash it to prevent other slave planets from joining in.
As for the Smugglers' Guild, well they have no interest in such conflicts but occasionally get involved when it profits them. The Smugglers' Guild is amoral and neutral, but if they can get away with attacking either side so as to benefit from the spoils of war, they will not hesitate to do so.
Tuesday, February 11, 2014
Implementing Fog of War
Posted by
Damien Classen
Last night I began implementing fog of war for Zyrtuul, and made some decent progress. Tonight I spent a few hours and got it working properly.
My implementation uses render-to-texture functionality, and involves the following steps:
- Create an orthographic camera that renders the scene from a top-down perspective. This camera does not render any of the usual objects. It will only render special objects called 'fog of war revealers'.
- Attach a quad to each unit in the game. This is simply a flat upward-facing rectangle positioned just above each vehicle or building. I call these 'fog of war revealers'.
- Map an image which will control the way fog of war is revealed for units. I initially used a simple black image with a blurred white circle in the middle, but then experimented and am currently using the image below (made it in Photoshop). This simply makes the fog of war boundaries more interesting. Basically, each unit will be surrounded by an area of 'transparency' with the following shape (completely arbitrarily chosen at the moment and definitely subject to change).
- Create a render texture. This is a surface that the fog of war camera will render to. That is, instead of rendering to the screen, it renders to a separate image in memory. Set the fog of war camera to render to this texture.
- The first time the camera renders it clears the image to black. It then disables its clearing behaviour so that for subsequent frames the image is not cleared. This allows the fog of war state to be permanent. If we wanted the fog of war to re-appear at locations where there are no longer any units we would skip this step and have the camera clear the render target to black every frame.
- Set the blend mode of the fog of war revealers to be 'additive'. This means that wherever the unit moves, the image above will be added to the black background. The following is a visualization of what the render texture might look like if there were four units in the scene.
- Render a large plane at the height of the terrain. This will cover the entire scene. This plane will render in both the main view and the minimap view.
- Map the render texture to this plane's material. What we are doing here is having the render texture control the alpha state of this plane. Thus, the white areas will be transparent but the black areas will be opaque.
- Set the depth buffering behaviour of this plane's material to 'no z-test' and 'no z-write'. This will make the plane always render on top of anything (so that we don't have to concern ourselves with situations where objects are above the plane). Also modify the render order of the plane so that it renders after all objects that must be obscured.
- Set the depth buffering behaviour of this plane's material to 'no z-test' and 'no z-write'. This will make the plane always render on top of anything (so that we don't have to concern ourselves with situations where objects are above the plane). Also modify the render order of the plane so that it renders after all objects that must be obscured.
Below are some screenshots of the game with fog of war enabled. The turrets do not currently have fog of war revealers attached to them (so they can currently be obscured by fog of war, which I'll fix later).
Sunday, February 9, 2014
Zyrtuul Screenshots.
Posted by
Damien Classen
I put a lot of work into a new pet project toward the end of last year -- a real-time strategy game that is currently going by the name Zyrtuul. I took a break for a few months but recently decided to do some more work on it.
I've added various new vehicle types. At the moment I'm focusing on getting the art in and looking good rather than on implementing specific vehicle capabilities. I quite like the new harvester. As it gathers red suphur (visible in one of the screenshots, the red stuff on the ground) a heap of red sulphur gradually grows on the back of the vehicle, until it is full.
I'm experimenting with a darker, more grim sci-fi look. I've taken out the trees and water and have put in rocks and lava instead. I've also removed the grass terrain textures and replaced them with dark rock / dirt textures. The look I'm going for is that of a barren planet. To further promote that atmosphere, I've subdued the lighting and given it a bluish tinge. The vehicles themselves are quite detailed, and when combat happens there tends to be a lot happening on screen, so I thought it best to keep the terrain dark and unobtrusive.
Thursday, November 7, 2013
Implementing Path-Finding in Zyrtuul
Posted by
Damien Classen
In this post I discuss my implementation of path-finding in the real-time strategy game I'm currently building (the working title for the game is Zyrtuul, though I might end up changing that).
A commonly used path-finding algorithm in game development is the A* algorithm (pronounced 'A star') which is an extension of the older well-known graph traversal algorithm called Dijkstra's Algorithm. I coded up a C++ implementation of various path-finding algorithms back in 2005 (as part of one of the demonstration applications that accompanied my CompSci master's degree), so I chose to re-use my old implementation of A* rather than re-inventing the wheel.
I started off coding the game as well as the game engine in C++ because, at the time, my main interest was in developing the underlying technology. But as it progressed I started wanting to focus on the actual game rather than the technology. Coding the engine and game simultaneously was simply taking too long (and I wasn't really learning anything new, having done so much engine work over the years already). So I decided to switch to the Unity engine for the game.
Unity doesn't support C++, instead you write scripts in C# or Javascript (edit: apparently Boo and their own language called UnityScript are also supported). I am therefore now coding in C# (simply because I have more experience using C# than the others).
Converting the code from C++ to C# was initially pretty straight-forward until I realized that C# does not provide a priority queue (a fundamental component of the path-finding algorithm) as part of its library. With my initial C++ implementation I was using the STL priority queue, but I now realized that I would have to find an implementation online or else write my own.
A priority queue is a data structure that keeps its elements sorted based on some user-specified criterion, in our case based on the path node cost / distance when conducting a path-finding query. In short, a priority queue is the most efficient way of performing path queries because of the fact that it automatically keeps itself sorted when you add or remove items.
It seems that the Microsoft C# team decided that a priority queue was too niche to be included in the .NET foundation library, so I was out of luck. Fortunately others had encountered this problem as well and so I was able to find a priority queue C# implementation online that, with some minor modification, suited my needs. Once the priority queue was done the rest of the graph traversal / path-finding code came together nicely. So I ended up getting a task that would ordinarily take a significant amount of time and effort done in about a day due to code re-use.
Path-finding solved the macro-navigation problem (navigation on a large scale), but micro-navigation was still a problem due to the fact that the pathing grid has limited resolution and also due to the fact that the grid is not static -- moving entities can invalidate previously valid routes. A vehicle could easily determine that to get from one side of the map to the other it needed to move around a lake or large obstacle that was blocking its way, but it still had issues on a smaller scale. For example, if vehicle A was told to find a path to some point and then vehicle B was instructed to move to a location that blocks this path, vehicle A would eventually encounter vehicle B and need to determine how to deal with it.
For this game I could get away with very simple collision detection and collision response based on bounding spheres and having vehicles 'pushed away' from one another when they are colliding. This partially solved the problem of vehicles coming into contact with one another (they would simply push one another out of the way), but was far from perfect as it could lead to 'jostling'. Also, it just made them look downright impolite. If two vehicles were headed directly toward one another, they would simply push head to head with neither able to get past. Alternatively, if you told many vehicles to move to a single location they would all mass together, jostling and pushing one another in an attempt to settle at that location.
One attempted solution was a "frustration factor"... when a vehicle was too close to another vehicle it had a frustration factor value that represented how 'frustrated' the vehicle was, with the idea being that it would eventually decide to simply find a new path to its destination it it became annoyed enough. This was simply a floating point value that increased over time when the vehicle was too close to another vehicle, and decreased over time when it wasn't. If a vehicle's frustration factor rose beyond a certain threshold it would request a new route to its current destination. Unfortunately I spent far too much time trying to get this to give the desired results and I found it to be too unpredictable. Eventually I decided that the moment a vehicle encounters another vehicle, one of the two vehicles must immediately find a new path. I arbitrarily decided that in the case of path blocking conditions the unit that was created first gets to keep its current path and the more recently created unit has to find a new path.
Quite a few other rules are also in place to handle various conditions and edge cases, but I think I've already written too much and so won't go discuss these here. The navigation behaviour of the individual units is fairly solid at this point, but not quite perfect (it's close though, better than some commercial RTS games I've seen). However, it will suffice for now -- I can hone it further later on, when polishing the game up.
Quite a few other rules are also in place to handle various conditions and edge cases, but I think I've already written too much and so won't go discuss these here. The navigation behaviour of the individual units is fairly solid at this point, but not quite perfect (it's close though, better than some commercial RTS games I've seen). However, it will suffice for now -- I can hone it further later on, when polishing the game up.
Wednesday, November 6, 2013
New Real-Time Strategy Game
Posted by
Damien Classen
I've been working on a real-time strategy game for the last while. I've kept it quiet until now, but it is getting to the point where I actually have something worthwhile to show. It is still in the very early stages, but here are a few screenshots of what it is looking like so far. I have developed a mini-map but disabled it for these screenshots.
I've decided to go the open source route and so will be releasing the source code for the game eventually (I'll only be releasing the C# code itself, not the content).
I'll probably talk about the development of the game in a separate blog post later.
Note: some of the art content is just placeholder art that I threw in to make what was initially just a fun AI experiment easier on the eye. I just realized that it's about time to replace it (I have acquired 3D models and have a friend working on more, just need to put them in). Rather silly of me not to think of that before posting screenshots.
Edit: I have modified the screenshots and blurred out the art that I know I'll have to replace. I'll post updated screenshots at a later stage.
I've decided to go the open source route and so will be releasing the source code for the game eventually (I'll only be releasing the C# code itself, not the content).
I'll probably talk about the development of the game in a separate blog post later.
Note: some of the art content is just placeholder art that I threw in to make what was initially just a fun AI experiment easier on the eye. I just realized that it's about time to replace it (I have acquired 3D models and have a friend working on more, just need to put them in). Rather silly of me not to think of that before posting screenshots.
Edit: I have modified the screenshots and blurred out the art that I know I'll have to replace. I'll post updated screenshots at a later stage.
Friday, August 2, 2013
Voxel Collision Heightmap
Posted by
Damien Classen
One of the unexpectedly challenging aspects of getting our voxel systems integrated fully into the engine is achieving stable and efficient collision detection and response, and decent vehicle behaviour when driving over portions of the world implemented using voxels.
Currently, the voxel system collision detection system I have in place works correctly. However, if you dig deep enough into a large voxel volume so that much of it has been eaten away, the optimization steps I can take to keep the number of intersections against individual voxels lessens. To put it another way, when you’ve dug into the voxel system sufficiently, the voxel data has been expanded a lot and so many calculations need to be performed. In my stress testing I had a vehicle driving through a large voxel tunnel where most of it had been dug away, with all of the vehicle collisions volumes / lines enabled (there are a lot). I encountered two problems.
Currently, the voxel system collision detection system I have in place works correctly. However, if you dig deep enough into a large voxel volume so that much of it has been eaten away, the optimization steps I can take to keep the number of intersections against individual voxels lessens. To put it another way, when you’ve dug into the voxel system sufficiently, the voxel data has been expanded a lot and so many calculations need to be performed. In my stress testing I had a vehicle driving through a large voxel tunnel where most of it had been dug away, with all of the vehicle collisions volumes / lines enabled (there are a lot). I encountered two problems.
The first problem was that the performance dropped significantly, to the point where I started to become very concerned about where to go next. However, I gave it some thought and have some solutions planned (and partially implemented). I am optimistic about these, and will elaborate further in a moment.
The second problem I had was that if we had pursued the more simplistic method I had in mind initially, the wheels would be moving over a relatively blocky surface when you’re digging up or down an incline (which we do need to do). This would give erratic behaviour, and we’d need to find a solution to this. Smoothing it out by using a greater number of smaller voxels helps the dynamics behaviour but would compound performance difficulties. This got me to thinking that converting the 'ground layer' of the voxel system into a collision heightmap that you drive on top of would be a better alternative.
What I mean by this is that when performing wheel collisions tests I sample a collision heightmap instead. This heightmap is constructed using the voxel data (it essentially reduces a 3D problem to a 2D problem so as to improve vehicle driving behaviour).
I have been hacking away and have a significant portion of the collision heightmap code implemented, though it is still a work-in-progress and so more work will need to be done before it is useable (I'm estimating a day or two). A benefit of this is that I can eliminate sharp jumps in height (i.e. the surface beneath the wheels will appear to the dynamics to be smooth rather than blocky).
I have been hacking away and have a significant portion of the collision heightmap code implemented, though it is still a work-in-progress and so more work will need to be done before it is useable (I'm estimating a day or two). A benefit of this is that I can eliminate sharp jumps in height (i.e. the surface beneath the wheels will appear to the dynamics to be smooth rather than blocky).
I will achieve this via interpolation. So, for example, if you sample the collision heightmap beneath the wheel, I will also sample surrounding height values and filter the results. I have recently implemented exactly the same functionality in the D3D11-based engine / demo I have been working on at home (see previous blog entries), and so I can just bring in and re-use that code, which has been honed and works well. Basically it makes use of hand-coded bilinear interpolation.
Note that this technique makes certain assumptions about the intended usage of the sim -- it assumes a single 'layer' of empty space. You couldn't, for example, construct a bridge out of voxels with this feature enabled and expect it to behave as expected. But for our current purposes the limiting assumption holds true, and so this is not a concern.
To summarize, using a collision heightmap will give smooth, stable behaviour when driving over a surface or tunnel represented by voxels, and will also yield performance benefits.
Here is a screenshot of some debug lines used to visualize a small portion of the underlying heightmap data. It is difficult to see from this picture (perhaps I should use tiny boxes instead to show heights), but these lines extend from the base of the heightmap to the first section of empty space directly above them.
Subscribe to:
Posts (Atom)
.png)
.png)
.png)
.png)
.png)
.png)
.png)







.png)
.png)
.png)
.png)
.png)
