Jump to content
  • Advertisement
Sign in to follow this  
  • entries
  • comments
  • views

About this blog

This time, I will do it differently. This time, I will actually finish. Psschyeah! As if!

Entries in this blog


Games! Games! Games!

I've been quite busy. My entry for Dream-Build-Play turned out okay, although we had to dash like mad to put actual gameplay levels together during the last week, having worked on art path and technology up until then.

Ko-Ado the Cloud

After handing in, I worked a bit on a 2D game, just to get the entire game development process, beginning to end, done in a span of two weeks. While it works, it's so much fun to work on that I'll keep adding to it. It's a multi-player space-based RTS, but I'm now deep into a desire/plan based AI implementation that will make it work single-player, too.

Both of these are developed in C# using the XNA Framework. The main limitation of that set-up is the limited CPU performance that C# programs get on the Xbox because of limitations in the Compact CLR it uses to run them. You'll just have to bite down and accept it, though.

More information on the early screenshots page.

I'm experimenting a bit with the UI. The four buttons in the center are the four controller buttons, where the buttons you can actually use are highlighted in color. The four buttons also double as cross-hairs. To select a specific unit, put the cross-hair buttons over the unit. Green will highlight. Press green to select. That kind of thing. And, yes, there are better ways of ordering multiple units around than just selecting them one by one -- one of the biggest problems for RTS games on consoles is the control sceme.




Have I been remiss in posting?

Well, yes. But I've actually been working on gamesey stuff! I'm helping an artist with an entry to the Dream-Build-Play XNA game competition hosted by Microsoft.

You can check out some screen shots and a video here: http://www.the-cloud-game.com/

Also, I recently wrote a rather long rant on some application performance sins that contribute to a simple reboot of a system taking 20 minutes these days. It's a bit Windows centric, but the central concepts actually hold for Linux and MacOS X, too. http://www.enchantedage.com/node/40




Oh, and some music

On Father's Day, I decided to stay creative all day. I locked myself upstairs with my CuBase and my Xboard, and out came an entry for the monthly KVR song competition. You might like it. You need an OGG player, though.





I've written some XNA code again

You can see a screen shot of the editor (which uses COM / .NET interop) and more musings about being a toolsmith versus being a game developer over at http://www.enchantedage.com/cargame.

Suffice to say: I may yet move beyond the tech demo stage of one of my hacks, and make a real game of my own one day.

Yes, one day!

Oh, and by the way: GTA IV on the Xbox is pretty good. I'd say 8.5 out of 10. It loses 0.5 because the controls seem to kill me once each mission. It loses 0.5 because of glitchy graphics -- especially a telephone I was supposed to read the number on, and the texture was too blurry! It loses 0.5 on general principle.




Project Gotham Racing 4: It Sucks!

I'm way too busy at work to do much development at home :-(

What free time I have, I typically spend playing games or watching anime, rather than developing on the game.

Speaking of games, I've been trying Project Gotham Racing 4 for the last week (I bought it together with a wireless steering wheel a while back). The sound track is awesome. The graphics are really nice. The car physics are good. But!

The AI cheats. You'll be driving full speed ahead on a straightway, and it will suddenly decide to zoom past you going 300 miles per hour. And once the AI is ahead of you, there's no catching up, no matter how well you take the corners. This makes for some very frustrating racing.

The controls are sluggish. I haven't used it with the wheel (turns out, I don't like the ergonomics of the Xbox wheel controller); I've used it with the controller, and there is a sluggishness in the controller that is really annoying. To get the vehicle to respond, you have to slam the stick one way or the other. And the dead zone is really big, so fine adjustments really don't work. This means that, when you break in front of a corner, you either will suddenly turn into the guardrail, or overshoot the corner by a fair amount, depending on how the stick chose to respond to your controls. This makes for some very frustrating racing.

Finally, the front end UI sucks. If I select a color scheme for my car, that color scheme is not remembered the next time I start the game. Selecting to re-try a race, versus re-trying at a different difficulty level, versus re-trying a previous or later race, are three different paths through the menu system. And, worst of all, the car selection list is totally unintuitive.
First, there's some wording above the list with an icon of the trigger beside it. It will say something like "(RT) Sorted by performance". Initially, I thought this meant that I should press RT to get the list sorted by performance, but now I think it means that the list is sorted by performance, and I should press RT to switch the list. (Why not the D-pad, like any normal UI?)
Second, in the list sorted by performance, there are initially four cars unlocked, and below them, some locked cars. You would then assume that the list is sorted from least to most performance (putting the locked, higher-performing cars at the bottom). But, no, that's not how it's actually sorted -- it's sorted with the highest performing car at the top. And while there are some metters for "speed" and "acceleration" and whatnot, those don't give enough information to understand how the car will perform -- what's wrong with real numbers?
This makes for some pretty frustrating racing.

So, all in all, not a great game.

Yesterday, I got a copy of GTA IV, which so far is very nice. Although the whole Serbs-as-bad-guys theme is a little tired, given how their regime acted in Europe, it's not particularly surprising. This game, too, has some problems, though. The handling of the default car ("Roman's taxi") sucks -- get a new car ASAP :-) (Although the missions will re-set the car to the taxi every so often). The game will hang my newly replaced Xbox 360 every once in a while, which means I lose progress. And the only way of saving will also advance time in the game, which is idiotic, because I can't dedicate very long times in a row to gaming, and need to do it in sessions.
But, all in all, GTA IV a great implementation. Liberty City is amazing in its detail, extent and variety. The character animation is also very well done, not very stilted or stiff at all (which is rare!)




More XNA stuff

XNA is fun, because you can run your stuff on the Xbox. Although the floating-point performance of the compact CLR (which they use on the Xbox) is really quite poor.

Anyway, you might want to read my screenshot comments on my current XNA experiment.




Help! I'm trapped in the body of a toolsmith!

Dammit! I had a witty post with all kinds of image and hyperlinks going, and IE 64 just crashed on me again. It tends to do that a lot. Blech!

Anyway, I was trying to texture some terrain to make something happen with the C4 engine I've had a copy of forever, and tried the Insane Terrain Texture Generator, but it crashed on Vista. Blech!

So i started writing my own. As good a reason as any to check out Visual Studio 2008 and .NET framework 3.5 that's been laying around.
OK, so installing those took forever, and I had to use a registry cleaner and separate download of the 3.5 framework just to be able to install Visual Studio Pro. Blech!

Anyway, yet another week-end wasted on hacking on tools instead of making stuff. I should probably just attempt to make Generic Sci-Fi Shooter #8624 so I can actually build something complete. Just to feel what it feels like. That'd be good!
But boring.




About projects petering out

So... my at-home project has petered out again. It's not dead, it's just sleeping. Really :-)

What killed it? Well, I usually blame a lack of art, but I'm not sure that's it. I think it's the point where I can start adding art, but I realize that to get anything actually useful, I have to add more art than I'm able to make myself. And I'm not independently wealthy, so I can't pay others to do my bidding for me. And I don't think my project is sexy enough to find an artist willing to work with me.

Meanwhile, I've been brushing up my l33t Java skilz. Last i did it, it was version 1.1, back in 1996 or so. I was lead for the team building one of the first true-threaded Java VMs back then (for BeOS). However, the Java environment has come a good way since then. It even has nice IDEs, like NetBeans or Eclipse. I've done some simple J2ME stuff for my cell phone in NetBeans before, but I prefer Eclipse after having used it for a while now.

I started using the jMonkeyEngine, as a way to jump in and get something done. However, I've reached the classic impasse that I get to with most of the free or cheap game/graphics engines I look at: the art path isn't very robust. In fact, the only way to get skinned animated characters out of 3ds Max and into jME is to use a Collada converter, that only understands a dialect of Collada that is exported by a MaxScript that is written and available only to NCSoft people.

I did my part: I wrote a new ASE file importer, that supports multiple meshes/nodes, and multiple materials, and animation -- neither of those options were supported by the ASE importer that comes with jME. You can find it on code.google.com if you want. I also looked at a number of other packages, including jmephysics2/odejava, and ran into various roadblocks. However, I'd like to stay for a little moment longer on jMonkeyEngine.

I found some code in the jME that I, honestly, feel was so bad it should go on www.thedailywtf.org. It was a matrix transpose routine, that didn't do a transpose at all; it created an identity matrix with a few (but not many) of the original matrix elements moved over. Finding this bug took me two full evenings of debugging, where I thought my ASE exporter was doing something wrong (it wasn't). However, apparently the community didn't agree that the code was so bad that it deserved to be laughed at by others, and in the end I had to realize I'd overstepped what's acceptable for the community, and apologize.

However, that brings me to another pet peeve of mine. The first is "art paths in low-cost game engines." The second, which I'll refer to here, is "amateurs and programming." There are people who may have spent three or four years doing programming, and maybe even graduated college, who believe that they are worthy programmers. In fact, that kind of people, I find, are most of the people contributing to open source projects. The problem with that, is that it takes at least 10 years of programming to make a grown-up professional programmer. Most of the code you find in open source projects ranges from "atrocious" to "cutsey." A great article about this phenomenon is Pounding a Nail: Old Shoe or Glass Bottle? by Alex Papadimoulis. I realize I'll probably sound elitist to some people, but then, so does anyone rejecting sub-par candidates at a job interview.

There are, of course, some great counter-examples, like the Linux kernel, or the Apache web server, or the GCC compiler. Those projects have managed to attract people with real experience, real talent, and managed to keep the code up to standards. I think a large part of it is that those projects have had strong supervision, where patches to the code have not been accepted until vetted by someone who actually has both experience, and a vision for the project. Most open source projects (and I mean 99% here) lack at least one of those four things (leader, with experience, and vision, and contributors submitting patches).

So, jME is one of the best supported Java open source 3D game engines. I'll agree with that. The other contenders might be Xith.org, and java3d, and the folks over at Multiverse (who are wrapping the C++ Ogre3D engine). However, it has a number of design defects that, in my opinion, would make it very hard to work with. In no particular order:

No working animated skinned character art path from 3ds Max
No support for interleaved vertex arrays
No support for multiple batches/materials out of the same vertex array
Special "shared mesh" delegating object needed to avoid duplicating vertex array data
Physics mesh objects duplicate the mesh data per object instance
Colors are stored as 4 floats per vertex
Inherits material state through the spatial transformation graph
No Matrix4f getters and setters for transforms
Un-thread-safe "StandardGame" base class, with no clear termination mechanism

These are the most annoying design problems I've found. There were (and are) also numerous bugs, some of which I've found, fixed, and submitted patches for. However, taken together, I don't think this is a great game engine, Java or no, free or no. C4, for example, would be a better engine. Ogre3D as well, except it's only/mostly rendering.

Can you deliver a game on top of jME? I believe you can. Especially if you don't worry too much about corner cases, or performance. The people doing Bang! Howdy seems to have delivered on jME. However, the fact that they succeeded may have more to do with those people, than with jME itself.

Alright, end griping. There exist people who think jME is a fine engine, and there exist people who think that beggars can't be choosers. Time for me to shut up for now.




Pageable Terrain Format draft specification availa

If you don't follow the Multiplayer and Networking forum, you don't know that the Pageable Terrain Format draft specification is posted, as a PDF!

Check it out. We've put a lot of work into the format, and the supporting code (which we'll make open source later this year). Hopefully, it can become a standard interchange format for runtime terrain/level data. (As opposed to Collada or SEDRIS, which are author-time interchange formats).




Work work work

I'm going to do something different today. I won't talk about the experimental game hacking that I usually do. Instead, I'll talk about work.

Work is so busy these days, I don't have time to work on the game. But I gave myself 9 years and 364 days, so I still have a sufficient buffer to finish on time :-)

At work, I've been working for quite some time on the general problem of how to hook together different kinds of virtual worlds. Right now, Second Life wants all of cyberspace to be Second Life islands; Multiverse wants all of cyberspace to use the Multiverse billing and messaging back-end; Qwaq wants all of cyberspace to be unsecured, peer-to-peer based on a VRML runtime (eh, good luck with that :-). That approach is not going to work.

Each big user of virtual worlds will need a diffent virtual world based on their needs, and most of them will want to control infrastructure and security themselves. However, they might still want to hook these worlds together, perhaps ad-hoc. For example, a large chemical company might have a virtual world for collaboration, remote meetings and distance education, and a county might have a virtual world for emergency management and practice. For one particular scenario, they might want to hook these virtual worlds together, to simulate an emergency at a chemical factory located in that county.

Today, doing such a simulation can sort-of be done in the military world, using various flavors of DIS, or HLA. However, it requires each participant to spend about two months with expensive connectivity consultants to ensure interoperability, before the actual exercise -- in fact, with the move from DIS to HLA, the amount of interoperability work has increased, because HLA does not specify the wire protocol, so there exist multiple, incompatible runtimes. DIS is also not so much a persistent virtual world protocol, as just a runtime telemetry protocol; while it works for what it does, it's pretty much run out of steam. Hence, the opportunity to create HLA, and the tremendous sadness of its failure to capture interoperability.

Okay, so there are many problems to solve. Here's one: Right now, each game studio has their own tool pipeline (unless you count Unreal 3 as a "standard"), and builds levels in their own way. Meanwhile, in the geo/sim industry, there are a few standards, although they are differently implemented in different tools, and none of them is really aimed at the kind of on-the-ground, in-your-face quality that you get from avatar-based games. Flight simulation seems to be mostly a solved problem, but that's not where the current action is at.

The standards that exist, are mostly for interchange, rather than runtime. COLLADA, OpenFlight(now Presagis, a division of CAE), X3D and SEDRIS are all fine ways of capturing data for exchange over a possibly lossy medium, but the captured art isn't typically directly useful for real-time needs, or requires significant conversion on load, which affects frame rates and makes streaming new content "live" a challenge.

For the last year, I've been working on a binary runtime terrain/level file standard. For some time now, I've gotten significant help from my company (Forterra Systems), and we're getting ready to present what amounts to a Grand Unified Whole-Earth Level File Format at the end of this year. Okay, so it won't solve everything, but it's defined with the following requirements in mind:

- compact, binary representation
- support for modern data, such as shaders, geometry subsets, etc
- not based on an old-school hierarchical scene graph
- extensive meta data support
- whole-earth support
- streaming/paging support
- multiple-resolution support
- transactional file format (commit or roll-back on edits)
- support for both artist-generated data and source-based geo-specific data
- support for collision acceleration
- support for encryption, authentication, compression, distribution, attribution and leveraging of synergies
- 64-bit clean file format
- documented, open, unencumbered file format
- documented, open source, C/C++ reference library to read/write
- extensible

The big catch-all is the last point. For example, if your game needs portals, then you can easily add that information to the file, even though the file format isn't defined to support portals. Further, other readers of the same file will see the data, minus the portals. You can still do on-demand paging of the portal-based data, while that data will stay out of the way of readers who don't understand it. All internal data storage is defined in a way that allows for transparent extensions. For example, if there is some kind of data that is defined as "some name, plus some number of 3D points" then this would be stored as a header, containing the name, the point count, and a pointer (within the data record) to the point data. The header would be followed by the point data, with possibly some other data inbetween. This allows future versions of the file format to add more data to the header (and even more arrays within the data), without breaking compatibility for a version 1.0 reader, which will read the header, and then read the array based on the offset found in the header.

I was going to present the file format (without the open source implementation, which we're still working the bugs out of) at the Terrain Summit in Huntsville, but as that got postponed, perhaps I could do it at Serious Games Summit in D.C. Except that got cancelled, so I guess y'all will have to wait for that big interservice/industry training, simulation and education conference around thanksgiving for the scoop. Consider yourselves forewarned! :-)

I might post a PDF sooner, though. Stay tuned.




Third party engines, again

I've been noodling around a little more in C4, mostly to figure out some things in an environment that's a little more complete than my home environment, but not as big as my work environment. And guess where I got stuck?

If you guessed "animated character pipeline," you're right! Just like with every other engine I've ever tried, except our work engine, I ended up running into bugs in Collada import, making an animation that is smooth in Max, have nasty kinks when imported to C4.

I'm starting to become a little more frustrated with this area than should be allowed. OgreMax is getting there for Ogre, and I'm sure Eric will fix the C4 problems (he always does -- major bonus for C4 owners), and the kW X-porter for X files makes it reasonable to do your own engine, should you need to. Torque, I don't go near anymore, as the support is non-existent, and you have to wait years for updated tools for new versions of Max, which then don't work. None of them is Actually There Yet. This includes spin-offs of the above, such as Multiverse, using Axiom, using Ogre.

Here's a tip to anyone who wants to take over the game engine world: Make a working character art pipeline. Everything else is simple by comparison.




It's been a while

I've been on vaccation (still am), and have made some progress on the project. I haven't, however, posted about it.

The exporter problems are mostly behind me. In the end, Derek Nedelman turned out to be quite responsive to problem files/scenes mailed his way, and made OgreMax work pretty well. I still have two outstanding complaints, but I can work around them:

Materials ought to have a common default copy base. Allow me to specify that all material definitions add ": SomeBaseName" in the exported script, and I'm happy. Now, I have to remember to re-edit materials each time they're exported.
Mesh data ought to be rotated so that the identity mesh orientation requires an identity node orientation. As it is, I have some animated/skinned meshes that come out lying down when I bring them into Ogre. In the OgreMax XML scene file, those entities have a non-identity orientation for the node that contains them. This is a major pain when trying to create mix-and-match meshes; that additional orientation needs to be carried along as metadata somehow.

All that art path stuff has taken a lot of time that I'd rather spend writing game code, but oh, well. Networking still works fine, and I added undo/redo of creating entities to my editor to make up for it. I still need a "delete entity" command, though, and better camera controls.

I'm still working on the overall goal of "player entity can walk around world after logging in," which currently means using real world collisions. I've been using the built-in OGRE ray-casts until now to constrain the camera and object placement, but that doesn't work if you want to be able to walk into houses but not through windows, etc. It also doesn't work if I don't want to run graphics on a hypothetical stand-alone server, as OGRE is needed to load the geometry for mesh colliders and heightmaps.

Thus, I imported ODE as a dependent library, and wrote a quick wrapper around its collision parts, to add as a component to entities that need collision. It also has a separate "collision world" abstraction that contains all the collision entities -- I tie them into the game code through the aforementioned component. In the level script, for a template or object, you add a "collision" component to the object, and magically the object will collide.

Because I don't want to load OGRE at runtime on servers, this allows me to save out the entire collision world as a separate piece of data. In the editor, where there are graphics, the mesh data is extracted, and compacted into collidable form (for use by ODE). When saving a level file (say, level.lua), it also writes out the corresponding collision file (level.lua.coll) in a simple format. When loading a level, the collision world is loaded from this file as well. Only when the editor is present will this file be updated for writing, else all entities simply find their collision entities in the inflated collision world. The main draw-back is that there's two files to keep in sync, but the editor does it for you most of the time.

Alright, so I'm currently testing the code that takes an Ogre::StaticGeometry and generates a large collision mesh out of it. Once that's done, I might take a detour and allow loading of OgreMax .scene files as large entities in the scene editor (not hard, and would improve the art path). Then it's on to players that can actually move through the level! I probably won't use the ODE solver for physical movement, because I want to use a simpler model of movement on the server. Mainly because all previous projects I've done have had real physics, and I want to know what it's like not to have it :-)




The pain! The pain!

So, you know I'm using Ogre 3D, version 1.4.3.

There are three exporters that allegedly work with animated characters and 3ds Max 9: LexiExporter 1.0.6 (just released), and oFusion Community Edition (from February) and the Ogre Mesh Exporter.

Unfortunately, oFusion doesn't work with skinned characters right now, and the Ogre Exporter generates data that won't be converted by the XML converter (missing for some part of the mesh). The Lexi exporter doesn't even load on my machine -- "Error loading dll: LexiExporter.dll" even though Depends says all the dependencies are fulfilled in the path.

I really, really, really don't want to end up writing a tool this time. Of course, I really, really, really can't afford the oFusion Pro cost, either. You may know that I've written several other exporters from 3ds Max and other tools, including kwxport and NuXporter for DeleD. I know what pain it is -- and avoiding that was the whole idea of using pre-made libraries only.

Is there any other rendering library (I don't need or want a full gaming engine), which has reliable tools, and is open source? I already own Torque (suck tools, suck code base, acceptable feature set, good hardware compatibility) and C4 engine (acceptable tools, good feature set, no outdoors capability and no support for low-end hardware).

Heck, maybe I should just create a Source mod or something...




New Etwork version

So I've spent the week-end releasing a bunch of code.

1) I released the updated version of kW X-port, my DirectX .X file exporter for 3ds Max. It's on SourceForge: http://kwxport.sourceforge.net/

2) I updated and released the Etwork networking library I'm also using for my project. It's on my home machine: http://www.mindcontrol.org/~hplus/etwork/

The property system's interaction with networking worked out pretty much the way I suggested it would, which is great! I have a "spawn" component that spawns a rock in the middle of nowhere, and the rock appears at the pre-set time in the pre-set place on the network client. Small steps, but cool!

Next, I'll look into actually making a player character. That'll be interesting, because I need to somehow take control of that object on the client side, and then somehow funnel the control input to the object on the server side. I have some ideas about how to do this, but they're not as elegant as the distributed property update system.

Last, I had a bug with Ogre3D where static mesh instances would not cast stencil shadows, whereas regular entity meshes would. That turned out to be a bug with 1.4.0rc1 which I was still using. An upgrade to 1.4.3 fixed that problem, but then added an assert that my meshes had a bad bounding box, generated by oFusion CE. The OgreMeshUpdate.exe program on the Ogre site didn't fix this problem, but the oFusion forum had an unofficial mesh update binary that did. The only problem now is that stencil shadows on a GeForce 7400 are... not fast.

But I already knew that from playing with C4 engine. I believe I'll just have to allow the player to choose between "no shadow," "simple shadow" (textures) and "exact shadow" (stencil).




Back in the swing

I've spent a few hours to get back in the swing of things, and it's paid off pretty well.

I defined packets for creating and removing objects on the client machine, and for updating properties of those objects. Here, the object system I designed a few months ago really helps, because public properties all have known types (long, double, quaternion, string, object reference, etc), and objects are all created from a known template.

Thus, the packets I need are:

- create object
- template name
- object id
- start object
- object id
- remove object
- object id
- update property of type X
- object id
- component index
- property index
- property value

Because all objects are created from the same templates, the component index, and the property index within the components, will be the same, which simplifies addressing. I assume I won't have more than 255 components per object, or more than 255 properties per component, so I use a byte for each.

The "start object" message is there to make sure that I don't start an object that's half configured. The way object start-up actually works is:

1. Send object creation, including object template.
2. For each component.
2.1 For each property.
2.1.1 If the property differs from the template. Send a property update.
2.1.2 Subscribe to property updates for future sends.
3. Send object start.

When a property updates after being started, a dirty flag is set, and when time comes to update object state, dirty properties are queued for sending. I prioritize property updates such that closer objects get higher priority. I also use a send queue with replacement capability, so if property X updates while it's already queued, I replace that piece of data in the queue with the newer data. This means I can also remove pending updates for objects as those objects are being removed -- no need sending network updates for things that die.

The neat thing is: Pretty much all of this code used infrastructure I already had written for the editor and composable object model!

I haven't debugged it yet, but looking at the code, it's quite simple. There are, however, some inefficiencies that I might want to address later (if profiling shows I need to):

The code that determines whether a property has changed from the template or not is inefficient. This affects CPU cost when starting up a new object, or when a new player connects. Bad N-squared cost.
Each player connection subscribes to all properties of all objects. This causes lots of allocations (one per subscription). A system of generation/change counts would probably be more efficient, to the point where each player connection stores the latest generation seen, and each property stores the latest generation updated.
Each updated property is prefixed with the object id. Some bytes could possibly be saved by grouping updates per object, then per component. This is mainly a network usage issue, and I think it'll be OK as is.
Properties are sent as generic pieces of data -- "a double" or "an int". If I had more information about the properties, I could marshal using less network data -- say, compressing floats to a byte when I know they are in the range [0..1] with precision 0.01.

Despite this, I'm pretty psyched! This part really looks straightforward, once all the infrastructure was there (components, properties, subscriptions, etc). Now I need to define some more interesting object kinds than "rock" -- like, for example, "player" :-)




New exporter

I had kind-of stalled out on the project, because I was at the part where I wanted to add moving entities (animating), and the exporters I had for 3ds Max 9 were all busted one way or the other for skinned, animated characters. I just read that there's a new LexiExporter for Ogre for 3ds Max 9, which may work. I'll try it, and maybe move forward again!

In other news, you may know me as the author of the kW-xport 3ds max X file exporter. I've been promising to make it open source, as soon as I fix two known bugs, for the last 6 months. I haven't had the time, and I still don't have the time, but grrr.... I really want to get it over with!





Screenies are good. This is from last weeks XNA game studio experiment.




Why is everything so hard?

This is work related. I'm working on testing out a popular content management system for an interactive web site: Drupal 5.1. It's a reasonably well functioning system, with a rich feature set, and it installs easily.

Among the features is the ability to add a new kind of content. You start out with "Page" and "Story" content types, and can add more using a simple web based interface. So I added the "Document" content type to host file uploads (Drupal already supports allowing file uploads for defined content types). Defining the content type is easy! I can also add a content of a specific type, and even find it in the search function.

However, I now want to create a menu item called "Documents" which lists all file uploads. Should be simple, right?


Drupal comes with no such feature, and searching the online documentation on "filter node type" and other such variants, I'm still nowhere near a solution. Then I find a user-contributed snippet, of how to display all content EXCEPT for a given type -- aha! I'll just change the " type" to "= type" and I'm done!

Except the formatting is really bland, so I need to dive in to figure out how to add annotation such as "submitted by ". Most of it was easy to figure out by reading source, but I got stuck for almost an hour on how to properly format a date to the user's preferred format using the Drupal settings (the answer is the 'format_date' function).

The problem really wasn't that it was hard; the problem was that the documentation was pretty sparse, and worse, there was no useful search function. Even a Google search with site:api.drupal.org returned nothing useful and lots of chaff.

Well, that, and I can't believe nobody before me have actually wanted a page that lists contents of a given type that they've just defined.




Writing and Building

Little in the way of updates. The house is coming together, and with that the home theater, which is taking a bit of time right now :-)

I also have a bunch of writing to do, so my creative spirits go there rather than my project. At work, I'm presenting at a conference on June 25; on the side line, I'm on the hook for a chapter on networking authentication for Game Programming Gems 7.

Also, in the home theater is not one, but two consoles that support home-brew. I've revved up the good ol' XNA Game Studio Express (that I used to write a toy 3D physics engine last year), and poked at it a bit. It'll be interesting to see some demo run on the Xbox, see whether I've compensated enough for TV overscan, and all that. All of which is distracting me.

See this, boys: BAD EXAMPLE!




And now... for something completely different!

It's my daghter's seventh birthday today. Kids are so funny. She got up before the alarm bell, and knocked on our door saying we had forgot about her birthday. Normally, we have to drag her out of bed to get to school.

Then, while we're still singing and bringing in the cake, she descends upon the presents like a ravenous horde of locusts on a single cob of corn. Shredded paper flying everywhere.

Compare that to her older brother, who is nine. He'll save some presents for a rainy day -- literally. Opening them maybe a few months later when he feels he needs a pick-me-up.

Anyway, among the engines I've looked at (and even purchased) is the C4 engine, which recently came out with build 135. New builds come out with some frequency, for that engine; a refreshing difference from some competitors (*cough*torque*cough*). I've decided not to use it for my game because the hardware requirements are way too high for my target market, and it also has no outdoors capability right now (slated to be added end of this year, if the roadmap is to be believed).

Anyway, playing around with it is interesting. The C++ code engineering is like a breath from the early '90s. There's no XML, no composition, very little templates, and a lot of switches on fourcc values instead of virtual functors or string hash look-ups. I won't say it's "fresh air," because I think it's way too code centric, but it's different. Different is always good to some extent, so you don't fossilize or get in a rut.

I think the worst part about C4 is that you have to define a fourcc in code for each mesh that you want to use with animation -- he calls them Entities. This makes data driven additions somewhat hard to accomplish. On the other hand, perhaps this is a conscious choice to force people to license the engine (c'mon, it's only $200) as opposed to taking the free demo and modding it to a total conversion.

Anyway -- it'd be cool to build something where you just blast the hell out of stuff. Loud sounds, fancy graphics effects, adrenaline action. Maybe with some upgrading/salvage, a la Interstate or MechWarrior, but that would really add too much. If I took a pause from the large (ten-year) project, how quickly could I get something playable?

That way lies madness! And not finishing.




Fighting the Ogre

I've been fighting the Ogre shadow system and near terrain renderer. It turns out that it uses different shaders for rendering ambient and color materials, vs rendering light contribution with shadowing. This means that, even if using the exact same code in both shaders, you won't get full invariance between the passes. and ugliness ensues.

In the meanwhile, I've resorted to using stencil shadows. Of course, stencil shadows, in turn, don't seem to work on static, "baked" geometry, using the Ogre StaticGeometry stuff. Grumble.

"Warts and all"

I'm re-factoring a bit of the LUA integration, using a bit of macro and template wrapping to get some meta information along with the actual function being bound into the LUA state. Given that I have two LUA machines; one for the main application, and one with level data, I needed this.




Travels, and editing

I went to Paris over the week-end. Me and my sister took my mom as a present for her. We've been before, but a long time ago. Say what you want about the French, but they cook really well! I ate deliciously all week-end long. It's also always nice to hook up with family.

While returning to the airport, I would see occasional burned-out cars parked in the side of the road. Apparently, the French celebrate the fact that they've elected a new president by going out and torching random vehicles. I'm not sure I think that's really all that charming...

I haven't written in a while, but that's because I've made some progress! I have a just-in-time Lua debugger which shows up when compiling a Lua script fails. It allegedly lets you change the code right there, and try re-loading it. I've implemented it by suspending the main thread, and spawning a new thread that creates the debugger window and runs its own message loop. When the window is done, I release an event that the main thread is waiting on, and the main thread goes on. Unfortunately, there seems to be some interaction between the main window (which doesn't get messages while suspended) and the debugger window, so depending on when the breakpoint is hit, the debugger window doesn't respond to mouse messages. Annoying! I don't really dare put the message loop in the main thread, because Ogre probably doesn't take kindly to being re-entered.

I'm also getting closer to a usable UI for the editing functions. I'm soon at the point where I need some geometry to actually edit a level. You can see a screen shot here:

I'm running into all kinds of warts, though, that I don't understand, and that aren't in the specs. So much for my "no source is better" philosophy...

Ogre additive texture shadows don't clamp correctly at the edges (leading to streaking in the distance).
The mesh I use for locating the selection has really weird specular lighting, even though the material only calls out a little bit of it.
The weird window problem, which I believe to be message loop interaction, I talked about above.
oFusion CE, which I use to export geometry for Ogre, doesn't split-and-duplicate two-sided triangles, so proper lighting can't be done in that case.
oFusion CE also has a bug (fixed in the Pro version, which I can't really justify right now) where it doesn't display skinned characters. This makes creating animated characters, such as players, a challenge.

The first three I can probably debug if I break down and get the Ogre source download.
The fourth I can probably work around by writing it myself and doing a post-process on the meshes in question, although I am loath to do that, because it totally messes with the art path. It's bad enough that oFusion doesn't export version 1.4 meshes yet, and thus the mesh converter tool pass is really needed for best results.





I'm using OGRE, and OIS, and CEGUI. I'm using an OIS::MouseListener.

I get the callback for mousePressed(), but for some reason, I'm not getting mouseReleased(). This bums me out. Anyone have a clue?





I downloaded the latest version of SQLite and stuck it inside a thread in my server. I then made log-in password validation be asynchronous, waiting for look-up in the database. That's better than using the hard-coded password "pass" that I've had until now :-)

Actually, the way I went about it might be interesting.

First, I have a common interface for "requester" and "someone requesting."

class IRequester {
// Complete is called back by the Request when it's done.
// If "ok" is false, the error message is in "error".
// The request is auto-deleted after it's called Complete(),
// you do not call Dispose() after Complete().
virtual void Complete(bool ok, char const *error) = 0;

class IRequest {
// Start the request running.
virtual void Start(IRequester *r) = 0;
// After Dispose() returns, Complete() will not be called
// for the request. Any work remaining to be done by the
// request will be canceled.
virtual void Dispose() = 0;

This lets any asynchronous task (that still completes on the same thread) be managed in the same way, which makes helpers easy to write.

I also have the notion of something to do later, which I call a Task. This is useful for scheduled events, and for things like DPC (deferred procedure calls). I have two different task schedulers: one that just runs things as soon as the application gets up to the main loop, and one that runs tasks on a timed schedule.

class ITask {
virtual bool Perform() = 0;

class IDeferredQueue {
virtual IRequest *AddTask(ITask *task, FileLine fl) = 0;
virtual void RunTasks() = 0;
virtual void Dispose() = 0;

class IScheduler {
virtual IRequest *AddScheduledTask(double atTime, ITask *task, FileLine fl) = 0;
IRequest *AddDelayedTask(double delay, ITask *task, FileLine fl) { return AddScheduledTask(Now()+delay, task, fl); }
virtual void Dispose() = 0;
virtual double Now() = 0;

The Scheduler is actually implemented on top of the IDeferredQueue() (it keeps a task of its own that just reads the time and checks what's ready to run).

OK, so given this background, I then added a ThreadTaskQueue:

class IThreadTaskQueue {
virtual void Dispose() = 0;
virtual IRequest *AddTask(ITask *task, FileLine fl) = 0;

Given a task, it will hand that task off to a worker thread (owned by the queue), and call the Perform() of that task in the context of this other thread. After the task is done, it will call the requester back with completion status, in the main thread again. I implement the hand-off to the main thread using polling; as long as there is a thread task running, the ThreadTaskQueue will re-schedule itself using the DeferredQueue, and in each deferred callback, service any thread requests that are marked complete.

Cancellation is also a little special. Disposing the request you got from the ThreadTaskQueue ensures that Complete() is not called after the dispose. However, the work of the thread may currently be in flight, or may already have been completed and awaiting notification. Thus, you're not guaranteed that the work hasn't been done, but you're guaranteed that the work won't start if it hasn't already, and you're guaranteed that Complete() won't be called.

This structure reduces the risk of threading bugs, as creation, completion and cancellation all happens on the main thread. The only threaded data lives in the Task that gets handed off to the thread, which makes isolation easy.




The refund

Today, I got a refund on the "historical buildings" purchase from TurboSquid. Good that I got the money back, but bad that I couldn't use these.

Does anyone own a copy of Lightwave, and an exporter that can export to any common format (Collada, .X, etc) that can be imported into 3ds Max? Apparently the .3ds exporter for Lightwave doesn't include texture coordinates, and the separate LWO importers/translators I've found don't read LWO texture coordinates right.



Sign in to follow this  
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!