Times, trials, and turbulence.
Monthly Archives: November 2007
It was a fun adventure, but I’m going to draw my little tangent-of-a-project to a close. I learned a lot while writing this voxel renderer, but I don’t really think that it has too too much potential as an engine for a full-blown game. Irregardless, I present you with one last screenshot, and a download link:
The Linux version was built on the latest version of Ubuntu, and with my limited Linux experience I’m not entirely sure if it will nicely run under other distributions without modifications. Fingers crossed. 🙂
Controls are the mouse for looking left/right/up/down, the up/down arrow keys for forwards and backwards, and the “a” key will spawn a sprite object at the location the mouse is pointing at. L, M, and H will change the quality betwen Low, Medium and High, respectively. Fun for the whole family!
The voxel renderer now has three quality settings, low, medium and high, which essentially skip vertical rows of rendering and roughly interpolate the results. Going from high to medium doesn’t result in much of a quality hit, but the speed boost is quite noticeable. The ‘low’ setting doesn’t look that attractive, but gives users running on low-end computers a good chance. I’m estimating that computers as low as 1.0ghz will be able to run the game at 30+ frames per second. I’ll have to find some folks with old computers to help me out with some benchmarking. 😉
So, with the voxel engine now rendering at an acceptable speed, it was time to move onto the next stage of the engine: sprites. Terrain is fine and dandy, but we’re going to need foes to vanquish and particles to spruce up the scenes. Two obvious problems came to mind when deciding the best way to implement sprites: a) How will I decide where to draw them on the screen based on their world coordinates, and b) how do I ensure that the sprites appear behind/in-front of the terrain properly?
The first issue wasn’t too bad. It was a matter of reusing the transformations I was using in my last renderer attempt (the one with the nice quadtree screenshots), where were really just simplified regular 4×4 transformation matrices (since there is no Y axis rotation), and then scaling based on how much the point from the world had to be scaled to be projected onto the viewing plane. Lots of jargon for those of you not inclined toward 3D graphics. 😉 On a more simple topic, the layering of the sprite was done by creating a ‘depth buffer’, which stored the distance from the camera every pixel is while the terrain is rendered. Using this data, sprites that are drawn can gauge which pixels it can overwrite given its own distance value.
(..Which are actually the powerup sprites from Magma Duel, a previous game :P)
With sprites now working properly, the final step before starting the actual game will be implementing a map editor of somesort so that I can create maps for missions/tracks/whatever. Still no final decision about what exactly the game will be.
More news as development continues!
Another year older, another year wiser. Another year of fun and games, of studying and learning and growing. Another year of experience under my belt, and another year of game development to look forward to. 🙂
I’ve been pretty busy lately with schoolwork, plus a long trip from campus to home for the weekend. Despite this, I’ve managed to keep myself motivated on getting a sufficiently fast voxel renderer working so I can develop this mini-game.
Having only my laptop with me (which runs on Linux) I was curious if I could manage to get the renderer working on a non-Windows platform. It worked without a hitch, aside from myself getting better acquainted with g++.
The method that I’ve (hopefully) settled on works by casting out two rays from the camera (one along the left side of the viewing frustum and one along the right) and stepping along them incrementally. For each step of the ray, the renderer linearly interpolations across the screen and world simultaneously, drawing vertical line strips to represent each voxel it comes across.
It’s not a very complicated algorithm, just like any of the others I’ve tried, but I think this route has the most room for speed enhancements. I feel like I’ve been working on this forever, but my goal is a steady 30-40FPS on my low-end-ish laptop before I accept the performance and start actually writing the game itself.
(The heightmap/detailmap belongs to this fellow, whose article provided me with some good general ideas about voxel rendering.)
I more or less restarted the renderer today. I spoke to a professor at my university who is teaching the 4th year Graphics course about my project, and he advised me to take a different approach. I realized that rather than casting out rays from the camera to detect voxels, it would be more efficient to process the voxels and transform them to screen coordinates for drawing instead. This is analogous to how 3D hardware also works: you hand it all of the geometry, and it renders it.
From a brute-force perspective, this is far slower, since you need to process *every* voxel in the map, which can be well over a million voxels. The trick is to implement optimizations such as spatial space subdivision (read: quadtrees or BSPs) and LOD (level of detail). Right now the renderer is at the point where I can hand it a point in 3D space of the world, and it will transform it to a pixel location on the screen. Additionally, I am now implementing quadtrees, which will allow large parts of the map that is not visible to the camera to be culled out extremely quickly, thus speeding up the speed of the renderer. Here are a couple of screenshots, showing the same map with 1, 2, and 3 divisions of the quadtree.
(1, 2, and 3 quadtree divisions)
The images look a little ‘pixely’ because I’m drawing a single pixel per voxel currently rather than a real voxel. This will be coming soon, after I get front-to-back sorting and some visibility tests in. Then, sometime soon, turning it into a darn game. 😉
Voxels On The Side
Anyone who has been reading my journal for a while should know by now that I’m pretty fascinated by the topic of 3D graphics rendering — particularly in software (ie. no OpenGL/Direct3D) — and so it should come as no big surprise that I woke up on Saturday and spontaneously sat down to write a 3D voxel-based heightmap renderer. 😛
The core of it was written on Saturday, but I spent parts of Sunday and today doing optimizations and making it generally prettier. The end result is as follows:
The ‘features’ are a 640x480x32 voxel heightmap display running at ~25FPS on my 3.0ghz computer, with distance-based fog, and a skybox-esque background image that rotates independently of the camera. The water level is variable, and the water is shaded based on the depth of the water of that voxel. The terrain is infinitely wrapping, so you will likely see some seams here and there where edges meet. Give ‘er a download — I’m interested to hear feedback or ideas for improvement:
(Controls: Arrow keys for rotation/movement, Page Up/Down for moving up/down)
I had a lot of fun writing this, so I’m seriously considering a small (read: under 3 weeks) mini-game based on this voxel renderer. Something along the vein of the Comanche series. It’s not very impressive by today’s killer-3D-graphics standards, but a neat little project nonetheless. More to come as the week progresses!
Sorry for the lack of recent updates. Just got Crysis, so you’ll have to excuse me. 🙂
After working excessively hard on Friday and Saturday in order to clear my schedule up, I managed to fit in a rather large 6-7 hour coding session today, interspersed by breaks for food, of course. 🙂
A ton of work got done today, which is pushing Skirmish another huge step toward the finish line. It’s still a long ways off yet, but every line of code written is one leap closer.
(More) Items and Inventory
The work completed today focused around the weapon/item management system and the player’s HUD. So, the basic-most idea is that the player can bind any given item to a certain key/button, which shouldn’t sound too far-out. Multiple weapons that share the same bound key will become ‘stacked’ on the HUD, and pressing the key repeatedly will effectively scroll through that stack of items sharing that key. This is particularly handy when you have several items that are somewhat similar that you tend to use in order (like a stack of several types of grenades) or that make more sense in a stack rather than strewn through your inventory independently (like 4 different SMGs). It generally just really cleans up the HUD quite nicely.
It may not seem like it at a first glance, but this was quite a behemoth to implement. The order that a ‘stack’ of items appears in is determined by the order that the key-bindings appear in the configuration file, but the overall order of your items (ie. the order they appear in vertically on your screen) also depends on this. Selecting items needed to scroll through the same set of items in a consistent manner as well, but actually draw the stack in reverse order so that the layering looks proper. And blah blah blah many more painful issues along the same vein. The end result is that one can make a vertical “item listing” based on item category — the current images only show the ‘Firearms’ category — and also allow for both left and right alignment on the screen (also yet to be screenshot’ted).
Player Physics Redesign
The previous two iterations of Skirmish worked on the player control scheme of having the player move forward based on what direction the player is rotated in. Movement was relative to the player’s orientation, and was (pretty much) entirely keyboard based. I’ve been following this method so far, although today saw a very significant change.
Movement is now much more “Arcade-like”, insofar that movement is absolute (ie. left arrow key moves the player left regardless of player orientation), and that aiming now functions via the mouse (with instantaneous turning). As a result, the player feels much more responsive, and newer players won’t need to struggle with trying to become adept with somewhat more ‘oldschool’ keyboard configurations. I will also be adopting in some other neat changes to the player control, such as a Soldat-like ability to ‘shift’ the screen to scroll in a direction using the mouse, as well as giving players the ability to jump [on top of objects]. More screenshots and videos to come!
This entry is somewhat a large update (and explanation) from the Ye Olde Poste I made about Skirmish’s Object Model way way back when. It’s always interesting to look at “here’s how I think I’m going to code it” and “this is how I really ended up coding it”.
The original idea was to have a single base class, Object, which represented a single generic entity within the game world, and have classes like Player, Prop, and Item derive from it. What ended up happening was that Prop essentially became the base class — a Prop being an object in the world that follows the laws of physics within the game — that Item derives from. The idea is that everything in the world that performs physics but has no real purpose (chairs, empty bullet casings, splinters of wood from a broken box, etc) are just regular Props, but those props that were capable of existing both in the ‘game world’ and in the player’s inventory become the derived class Item. These have the logic of Props when they are on the ground or being thrown by a Player, but have an additional set of logic for entering/exiting the Player’s inventory, and for being used/fired/activated/etc as well.
Items are essentially weapons, depending on how you look at. Items have a Use, which can be defined as anything: create a networked bullet, heal nearby allies, launch a rocket, and so forth. It’s simple and flexible enough that I can generalize a lot of the network messages that will have to be implemented, and makes adding logic for new/different Items a really easy task.
Additionally, Items can each have one of three Ammo Models to follow for their usage. By default, all Items have values like ClipSize, FireDelay, ReloadTime, etcetera, and so all Items technically consume ammunition in some manner. An Item can follow one of three models, which all ties into how I’m handling things like reloading and ammo behind-the-scenes: Ammo Consumption, Object Consumption, and Infinite.
- The idea is that the first type will look for a certain ammo type in the Player’s inventory, say, “Standard Shotgun Ammo” as an Ammo object (derived from Item as well). Ammo objects hold an arbitrary amount of ammunition within them, and so they act as a sort of single container object for all of the Player’s ammunition of that type. Thus a Player with a rifle and shotgun would have one item holding all of his rifle ammo, and another for his shotgun ammo. These objects would be destroyed once the ammunition ran out, or merge two ammo objects together if another of the same type were added to the inventory.
- The second type allows the Item to instead consume another object in the inventory as ammunition. This is particularly neat, since it allows for some clever recursive ammo/gun relationships. One such example are grenades, which really would not make since under the above model. I mean, a grenade isn’t a weapon that you feed ammunition to; each grenade itself is a weapon. So, by setting a Frag Grenade’s ammunition to “Frag Grenade”, the weapon will consume itself as ammunition, thus destroying it from the player’s inventory. The inventory will seem to clean itself out as the player uses grenades/mines/etc without leaving over an annoying “Grenade with zero ammo” object. It also allows for weapons that use Props as ammo, like somesort of “Rock Launcher” that uses rocks you pick up from the ground. 😉
- The last type, Infinite, is pretty straight-forward. This is just a special type to accommodate for melee weapons, which have an infinite number of uses. This also applies to several special infinite-use weapons that some of the player classes have.
Above shows a disposable rocket-launcher item, which consumes itself as ammunition.
The HUD, The Map Editor, and Milestone 3
I don’t really talk about the game versions much, but I keep track pretty vigilantly in my internal documents. Milestone 2 is now completed, which has introduced the basics of the GUI system, saw Prop physics system implemented, the Object Model put into place, Player animations, firing basic weapons, and full map/object collisions.
The next Milestone, number 3, will be about fleshing out the HUD the rest of the way (lots to come!), and finally hunkering down and writing the map editor for the game. After that, well, maybe we’ll even start on the networking programming some day. 😉
This is a brief content-free entry, just to state that I’m still alive, and that midterms are finally over. Huzzah! Here is a screenshot for the time being, but I will expand more on the HUD system and what direction it will (eventually) be going in, in my next entry.
(Above: Showing the basis for the weapon display on the HUD. “INF” will later denote how much ammo for that weapon exists in total within the player’s inventory.)