July 04, 2005

Sometimes It Helps to Go Backwards

I recall some meaningful discussion back when I was growing up about top-down versus bottom-up approaches to computer programming. I think the consensus answer was "you have to do both".

Perhaps that gives me license to do this:

What you see here is a stack of DVD cases for a game that I've written just about zero code for. Actually, six games. One game, six episodes.

I've recently been making a concerted effort to collect the entire Goodman Games Dungeon Crawl Classics line, and I realized that I could appropriate their gimmick for my own RPG game. Which, really, is appropriating the 1st Edition D&D look and feel. Goodman Games is doing it within the pencil-and-paper roleplaying milieu, whereas I'm taking it over into computer roleplaying.

I want to say that looking at the end helps me focus on where I'm going - playing around with making DVD covers gives me a destination to shoot for. But that's probably a little too generous - I'd be more comfortable with that kind of rationalization if I had finished more games on my own.

That said, there have been a few inspirations that have come from looking at the packaging of the different episodes. I decided to go with a spectrum, as you see in the picture, and certain characters and encounters have been floating around in my head without really knowing where they belong. I now have a better grasp of where I want various things to happen - based entirely on the color of the packaging. Cart before the horse, to be sure, but I think that anything that helps give you ideas is worth exploring.

Another gimmick that just occured to me today as I was thinking backwards was that I'd like to have a "premium" package - something that people would willingly spend a few extra dollars for, above and beyond a physical CD in a pretentious DVD case. One of the things that I always loved as a gamer when I'd open up a computer RPG box would be a map inside the box. And so, as a developer, maybe I can make that happen again. And, since I'm doing a multi-episode story, maybe I'll do a map per episode. Suitable for framing.

Now all I have to do is to burn the CDs to put in the cases. And write the software.

Posted by tsmaster at 07:00 PM | Comments (0)

May 29, 2005

BASS Sound Library (Crashing is Bad)

That project I'm working on in the moonlit hours specifies that the BASS sound library be used.

Seems like a pretty adequate tool for playing WAV, MP3, OGG, MOD, MIDI, and probably other formats that I can't even recall at this moment.

One comment I heard about "real hackers" was that they didn't like closed source tools. When a problem turns up in one of the libraries that you've licensed, a real hacker will want to get into the code, find the problem, fix it, and get back to work. Closed source libraries prevent this from happening. (The original author of this comment was blurring the definition of "open source" a bit, talking about libraries distributed in binary form alone, but you get the idea.)

I am reminded of this just now, because I have a BASS DLL and no source code. I've been seeing crashes when running in the debugger that seem to be happening in the DLL, and not in my code.

I'm of the opinion that if you're going to sell your code, it shouldn't crash. If it does crash, consider allowing the licensees to see the code so that they can help you fix it.

My current workaround is to limit the number of channels I have going at once. There may be a hardware maximum, but it seems like I shouldn't have to care about that - any extra sounds that can't be played should trigger an error condition. An error condition that higher level code can catch and respond to. Crashing is bad.

This is almost as bad as the case that an ex-coworker once found himself in - he was working on a console game, and they had a bug where the game could not go on. It wasn't precisely a crash, because the code was still running, but maybe the player control didn't work anymore, so there was nothing for the player to do but reboot the system. The crazy thing is that from within the game they could detect, but not fix, this phenomenon. So they hacked in a faux easter egg screen saying "Congratulations! You have discovered the secret bonus! Reboot your system to go back to the game!"

Posted by tsmaster at 10:47 PM | Comments (2)

May 28, 2005

Using ID3DXSprite

I'm currently working on a 2d game that mostly wants to draw unrotated rectangular images with one-bit (cookie cutter) alpha. Occasionally, though, the design requires that some of these images rotate on the screen (within the plane of the screen, nothing too fancy... yet). One route that I've taken down this path previously is to use OpenGL with an orthographic projection, but for reasons outside my control, OpenGL isn't an option for this project.

Back in earlier versions of DirectX, you might use DirectDraw for 2D games. But these days, DirectDraw and D3D are integrated, so I'm using Direct3D.

Since I've got the fullon 3D pipe available to me, I could certainly draw textured quads to the screen, similar to what I did with "Cars With Guns", but this seems like overkill when most of what I want to do is a simple copy of the image information, unmodified, from the source texture to the screen. In particular, I want the graphics to show up pixel-accurate on the screen without antialiasing or filtering.

In my research, I found CodeSampler.com, which is a terrific source for examples. At first, I was planning to use DirectX 9.0c, and the ID3DX sample got me running, giving me a simple interface for drawing sprites to the screen, with or without rotation, with scaling and other fancy stuff should I make that decision.

One thing that happens in just about any software project is changing requirements. I discovered after getting a working version of the game up that the game had to work on stock Windows XP machines, which meant dropping back to DX8.1.

Fortunately, DX8.1 has support for ID3DXSprite. Unfortunately, the interface is just about completely different. The MSDN documentation for each version, 8.1 and 9.0, is of no help.

    /* during device creation */
    D3DXCreateSprite( g_pd3dDevice, &g_pSpriteContext );


    /* during render */
    g_pSpriteContext->Begin();

    D3DCOLOR c = D3DCOLOR_COLORVALUE(1.0f,
                                     1.0f,
                                     1.0f,
                                     1.0f);
    
    float px=(pSpr->right+pSpr->left)/2.0f;
    float py=(pSpr->top+pSpr->bottom)/2.0f;
        
    float ox=pSpr->right-px;
    float oy=pSpr->bottom-py;
        
    D3DXVECTOR2 scaling(1.0, 1.0);
    D3DXVECTOR2 rotCenter(ox,oy);
			  
    D3DXVECTOR2 translate(pSpr->posX-ox,
                          pSpr->posY-oy);
    
    g_pSpriteContext->Draw(pSpr->textureHandle,
                          &pSpr->srcRect,
                          &scaling,
                          &rotCenter,
                          pSpr->angle,
                          &translate,
                          c);
The code above is a rough sketch of how I use the code. I begin by creating a "sprite context object" - my own term, as calling it a "sprite object" is misleading. I create my sprite object just after I have acquired the device.

Later on, when I'm rendering my scene, first I call Begin() on my context object, at which point, I'm ready to draw the individual sprites.

First, I create a color for the sprite. In this case, I want the original colors to be used, so I use a solid white color.

Next, I set px, py to the center of the sprite within the texture. It's important to understand that the intended use of ID3DXSprite is to draw rectangular sections of source art to the screen, so several of the arguments to Draw() are relative to the upper left corner of the texture.

Second, I set ox, oy to be the "half size" of the sprite (or 'offset', if you prefer). This is the distance from upper left corner of the sprite to the center.

I create a scaling vector, but I don't currently make use of it - so I leave it at a neutral value, (1.0, 1.0).

Next, rotCenter gets the half size offset value, specifying the point around which the rotation should be centered. For my purposes, the center of the bounding box of the sprite is a good point to center the rotation about, but for odd-sized objects (like a fryingpan) you might want to set the rotation center to be somewhere closer to one of the corners.

The last part of the setup is to create the vector describing the location where the sprite should be drawn on the screen. The peculiar bit is that the sprite is positioned by its upper left hand corner, which makes little sense when you start rotating the sprites. So I subtract off the half size offset from the point on the screen where I want the center to be drawn.

Finally, I call Draw(). The arguments are the texture handle, the sprite bounding box (in texture pixels), our scaling vector, the rotation center, the angle (in radions), the screen position coordinates, and finally the color.

Phew.


the MSDN documentation of ID3DXSprite is authoritative, but very difficult to get useful information out of.

Posted by tsmaster at 08:46 PM | Comments (0)

March 11, 2005

GDC 2005: Will Wright unveils "Spore"

Will Wright's talks alone justify the cost of going to the annual Game Developers' Conference. Though he's had only two hits (Sim City, 1988, and The Sims, 2000), he's recognized as a visionary. This has permitted him a certain amount of flexibility and license to pursue projects that others couldn't pull off.

I typically find his presentations intellectually stimulating - an exhortation to explore new spaces for gameplay, to draw inspiration from other disciplines, to make excellent games.

Today's demo was a deviation from his typical format, but it accomplished the same effect.

One observation that Wright has made in years past is that the size of teams for games has been increasing exponentially - games took a couple of people back in 1980, and every couple of years, the teamsize has doubled. "The Sims" took a couple dozen people, and "The Sims 2" took over 60. For comical effect, consider how long it will take before game teams grow to the point where all humanity will need to be employed on a single game.

But let's pay particular attention to the division within those game teams - the folks that work on content (painters, modellers, folks you'd think of as "artists", as opposed to the guys writing the code) have been taking an increasing ratio of the teamsize.

One significant point in history that influenced this phenomenon was the introduction of the CD-ROM. Until that point, the distribution medium was the floppy disk (1.44 megabytes of information on a 3 1/2" device). With the CD-ROM, developers instantly had 450 times more space to fill. I imagine that moving from a 2 bedroom apartment to a 900 bedroom house would be a bit of a shift for most people. You'd still have a hard time getting the car into the garage, though.

One of the early examples of a game that took advantage of this new media format was "Myst", by Cyan. All of a sudden, it was possible to pregenerate an unprecedented amount of detail for stunningly vivid graphics. If you looked under the graphical sizzle, all you'd find was a simple HyperCard slideshow.

Games have certainly become more complex since then, but the example of Myst has remained fairly representative - people filling up their media (with the advent of single-layer DVD-ROMs, we have 4.7GB, dual layer presumably going up to 9.4GB - big enough to fit almost 15 of your 900 room mansions.

But not everyone has headed in this direction, as compelling as it is to fill the media space available. There have been some really impressive accomplishments from the "demo scene", a loose group of creative folks centered around Northern Europe. They've been making very rich "demos", or 3-d noninteractive movies, and since they haven't been targeting retail distribution, the advent of the CD-ROM hasn't been as significant to them. A common self-imposed size limation for a demo is 64 kilobytes. Twenty-three demos could fit in that original two bedroom apartment. If you wanted to fill up a dual-layer DVD with 64 kilobyte demos, it would take about a million man years.

How do these demo coders fit anything of interest into such a small space? The trick that they make use of is "procedural content" - the technique of using a small amount of numeric data to synthesize content at runtime. Wright has long been intrigued by phenomena that act as compression procedures - having described human speech as an amazingly efficient compression/decompression process for getting ideas from one brain to another. And poetry as a compression medium for communicating emotion.

Procedural textures allow a small amount of instuctions communicate the way to construct an image of bricks for a brick wall, or marble for a vase, or even water, rock, earth, and snow for an image of the Earth. It's not unusual for art in today's games to be delivered in 128 by 128 pixel images (sometimes ranging up to 1024 by 1024, in special cases). A single 128 by 128 pixel image in its uncompressed form will take up 64 kilobytes, but the instructions for "make red bricks with white mortar, the bricks being 30 pixels by 14 pixels, and the mortar being 2 pixels wide" might take substantially less (I could imagine somewhere in the 5 to 10 byte range - maybe a little higher - but even at 16 bytes, that's a 4000 to 1 compression ratio, which makes MP3's 10 to 1 compression ratio (give or take) seem paltry.

Indeed, if you remember MIDI music files, you'll grasp what's going on here - through use of concise description (and the assumption of a certain amount of intelligence on the other end) you can say "use a clarinet to play a middle C quarter note" without having to provide every detail of what that sounds like.

If the talk of compression ratios has caused your eyes to glaze over, get a drink of water and come back to this point, because now I'm going to start talking about what Wright is planning to do with this technology.

He began by showing a fairly simple looking 2d game. He described it as a free-form version of Pac Man. In the middle of the screen, there was a little critter - to me it looked a little like an earwig or a silverfish.

The bug swam around in a petri-dish-like enviroment, sometimes eating little yellow balls, sometimes evading brown balls. Ho, hum. There are plenty of little games like that, I'm sure you can whip one out in Flash in half an hour. Nothing exciting yet.

After a while, the bug had acquired enough energy to "level up", and Wright opened up a menu, which allowed him to "purchase" new body parts for his bug. He chose a spike that he chose to mount on the nose of the bug. There were numerous other mounting options available to him, and I wondered how a spike on the tail would have affected the bug's survivability. With the spike on the bug's nose, Wright was able to chase after the brown balls as a predator - he had taken one little step up the food chain.


----------
ZOOM OUT
----------

At this point, there was a discontinuity of gameplay. I'm not sure how it will be managed in-game, but through the slight of hand that we excuse in demos, we suddenly found ourself transported from a 2d petri dish up into a 3d underwater scene. The creature that we had seen before had grown up. It was now a swimming beast, and was chasing after small fish. After a little while of this, Wright was able to go back to the Body Parts Purchasing Menu and rebuild the creature. Remove the fins, rearrange the tail, bend the spine like so, make the nose shorter, let's add some legs, two legs, three legs, yeah, three legs seems good. Let's add on a prehensile grabber body part on... let's say the tail. And back to the game.

Without fins, the creature isn't much good in the underwater scene, so let's walk out onto land. A beautiful tropical beach, with grasslands and trees and a number of other creatures greeted us. Well, not so much "greeted" - the first thing we did as we came out of the water was chase after a little creature.

One thing that was impressive was that the freeform sculpted creature that Wright just made was moving around in a natural-looking way. It's hard to know how a three-legged lizard would naturally move, but I was willing to believe that this was one possible way.

The other critters on the land, Wright told us, actually were authored by other players. This is where the procedural content is beginning to make a huge difference; the "DNA" encoding my three legged lizard amounts to a tiny packet of information. The game transparently sends this up to a server in the background, and shares the content that you've created with other players. In exchange, you get a bunch of content back. Lots of novel critters to eat. Each handmade. Each with a little bit different of a personality, a little different behavior.

After chasing after a few little beasts, Wright's lizard found a scary predator that he couldn't take on. So he fled. The predator was actually pretty frightening - and created with the same set of tools as we had used to make our lizard.

For fun, Wright chose to use a mating call. There was a shrill call, which was soon answered from somewhere behind us. We were able to find another creature like ourself and we went about engaging in sweet lizard love. I'm pretty sure the sax music in the background wasn't procedurally generated, but it did get a laugh. I can only imagine that if they could procedurally generate some Barry White, they would have.

After growing our creature some more, Wright pointed out that one of the "upgrades" for our creature was a bigger brain. And that as the brain got bigger, eventually the creature would become sentient.


----------
ZOOM OUT
----------

Another discontinuity of gameplay, and we now see a cluster, no, a VILLAGE of our little lizard guys. They're moving around in a believably social fashion. Our boy's done well for himself, I think. At this point, the game very much resembles "Populous: the Third Age". The player no longer controls the individual creature directly, but is able to drop goodies into the village for our critters to play with. At first Wright gave our guys a rack of spears. A handful of lizards crawled over to the rack and grasped the spears in the grabbers at the end of their tails. Menacing chaps.

"Before they get into trouble", Wright said, "let's give them a campfire". And the spear-bearers gathered around the fire. "And a drum", which was soon being beat by one of our lizards. The spear-bearers broke into a dance around the campfire which looked entirely like every tribal dance (every tribal dance involving spears, drums, and campfires).

As your village grows, eventually it becomes a city.

----------
ZOOM OUT
----------

We're now looking at an oddly Seussian looking collection of buildings. Here and there, we can see little lizard guys moving between them. I'm reminded of "The Sims" in a weird way. Wright grabs one of the buildings - a blobby collection of mushroomy bulbs - and goes into the building editor.

The building editor looks and feels just like the creature editors. Soon he's adding a couple new blobs to this building, and we're popped out to the 3d view again, and our building has a brand new mushroom-shaped tower. At the base of the building, a crowd of lizard guys cheer. Very much like "The Sims". I think they appreciate our architectural choice.

Wright explains that there are different buildings we can buy, and of course, our menu of buildings include some options authored by other players, selected for us according to our play style. If you make a building that goes up to the server, and a lot of people put that building in their cities, it gets positive feedback, causing it to be distributed to even more players.

As you build your city up, eventually, you'll come in contact with other cities, and you'll find yourself wanting to interact with them. We flew over to a nearby city, and Wright pointed out the very different style of this city. This was very mechanical, very austere. East German, if you will. Wright commented that he wanted to support artistic styles as diverse as Pixar's "Finding Nemo" to H. R. Geiger's "Alien". He also drew our attention to the three tanks emerging from this city, trundling back... back to our HOME!

We quickly went back and built some Seussian looking ostritch flying machines. Which proceeded to fly in precisely the wrong direction, leaving our town undefended as the tanks came and proceeded to pound on our city wall.

----------
ZOOM OUT
----------

At this point, without any cuts, Wright pulled back and we were able to see our town and the neighboring town. He put up a slide on the other projection screen, showing one of those cartoon "maps" of Atlanta - the kind where downtown is zoomed in and the suburbs are clustered around it, and just beyond the suburbs is California.

The point he was illustrating was that as you pulled away from your city, the city was out of proportion - other cities became visible as we pulled back and the entire globe fit on the screen, but we were still able to see the locations of our city and its neighbors. This is important, because at this level of the game, the player is responsible for building up a civilization (like many other games, including "Civilization"), which is going to involve managing city-states and the populations of continents.

He spun around the globe, showing the different continents available on this planet. There were little wispy clouds all about. The water shone, the land was green in places, brown in others.

And then we zoomed back in to our city. Wright mentioned that as you advance your technology, you'll be able to build a UFO. A goofy looking flying saucer appeared, and hovered around the city. At this point in the game, the UFO becomes "your swiss army knife", the device that you can equip with all sorts of neat upgrades. One of these abilities that the UFO can be equipped with is a beam of light that you can point down on critters on the ground. We chased after that scary looking critter from back when we had just barely crept out of the water. We "abducted" a few animals and flew around a bit.


----------
ZOOM OUT
----------

Out to low orbit. Out further, the planet turns into a small disk. Other planets appear. We see the shape of a solar system, with a gas giant, an asteroid belt, and several other planets. We fly over to a remote planet, further out than our own. We zoom in, and it's an icy ball, pocked with craters. We proceed to beam the monstrous creature to the surface.

Uh-oh. Creatures don't survive well on airless planetoids. It burst in a particularly crowd-satisfying manner. I guess we'll have to do something to get an atmosphere onto this planet. One of the tools on our UFO happens to be a missile that creates volcanoes. Zap, Zap, Zap. We're beginning to see the plume coming from the volcanoes turning into an atmosphere.

But that's not fast enough - Wright uses 'The Genesis Device' - another tool (weapon?) that he launches, resulting in the low-lying areas filling in with water, grass greening up parts of the land. It's not quite eden yet, but it'll come along. Before we unleashed the Genesis Device, we established a colony on the arid rock, a cute little city inside a bubble. One day, we'll have terraformed the outside to a point where they don't need the bubble anymore.

----------
ZOOM OUT
----------

So. We've colonized an alien world. We're terraforming other planets. Quite the achievement, so far. I wonder if there's anybody else out there? Zoom out from our new planet, out from our solar system, there's a nebula, there's a black hole, we're seeing a 3d stellar neighborhood. The planets are no longer visible, all we can see are phenomena familiar from Hubble photographs. Let's mouse over the various things that we see. There's some interesting noises that we can discern by listening to radio emanations from the distant bodies.

Wait, what's that? I do believe that I hear alien radio transmissions. Let's go investigate. Fly over to a distant star (we've got a UFO - three light years? Thirty?) and drop down into the alien solar system, isolate the alien planet, and find an alien city.

It's a completely different art style, of course. We want to make first contact with this race. Maybe they'll be our friends. We play the "Close Encounters" musical greeting. Or perhaps the aliens don't understand us, because they begin launching missiles at our UFO. We attempt to fight back, but our weapons are doing us no good.

We retreat to space, and Wright unleashes some larger weapons. Boom, the city is gone. Boom, what was once the planet is now a new asteroid belt. "There goes my reputation as a non-violent game developer."


At this point, Wright mentioned that the options available now were varied - we could attack alien planets (think Independance Day), we could take a paternal relationship to them (The Day the Earth Stood Still), we could seed them with technology (2001), abduct their creatures and interbreed our creatures with them (X Files) or engage in diplomacy (Star Trek).

Thinking about Star Trek, he pointed out that he wanted to make sure it was possible to represent all the favorite races as simply as possible. What would happen if the Klingon Empire encountered The Borg?

----------
ZOOM OUT
----------

Our final zoom of the day, we now see the spiral disk of our galaxy. How many stars? How many planets? How many races out there?

Wright commented that his intention was to provide the climb up the evolutionary ladder as the tutorial, and then allow the players the sandbox for the remainder of the game. This is an interesting reversal - most games treat the goal-directed part of the game as the overarching structure. In Spore, Wright intends to let the players toy with the galaxy available to them at a huge range of scales.

He then apologized that he would not be able to talk more about this game until E3. This hints that the game is more than a fancy tech demo (oh, but what a tech demo!) - but it's actually a production project. As I began writing this account, I was sitting next to a Maxis employee who commented that Spore was "a great game". I wanted to grill this individual for information that I realized would not be forthcoming - if Will Wright wasn't able to talk about it, this individual wouldn't be either. The one thing that this individual was willing to pass along was that "everyone thought it was a very ambitious game".

One of the questions I decided not to ask was going to be "how much of that demo was staged, and how much is shippable code?". I take the "ambitious game" comment to mean that much of it was demo-only, which suggests that it's not going to be on shelves for your Christmas gift giving.

If I have to wait for Christmas 2006, that'll be OK. Because it is a very ambitious game - crossing a phenomenal range of scales (think of Eames' "Powers of 10"), providing the players the opportunity to create and own their race of creatures, which could eventually visit strange new worlds, going where no three-legged-lizard had gone before.


I'm anxious to see what E3 has in store for us.

Posted by tsmaster at 09:52 PM | Comments (0)