Monday, January 17, 2011

Multi-planet prototyping

The past couple of weeks I've been working on a prototype of multi-planet gameplay for my lunar lander game. Results are not terribly encouraging, so far.

One of the big problems is figuring out how to miniaturize the solar system without getting totally wacky gravity. On Earth's surface (if I've done my calculations right) the acceleration due to the sun is about 1600 times weaker than the acceleration due to the Earth itself. Thus it doesn't much matter where the sun is in the sky; up is always pretty much the same direction.

I would like to have a smaller, denser solar system to cut down on travel times between planets. Unfortunately in my experiments so far this results in slanted gravity as the sun and other nearby bodies move across the sky.

Our solar system has about 99.9% of its mass in the sun. Thus, there's very little gravitational influence from one planet to another. As I distribute more of the solar system's mass to the planets this makes it harder to fly between them due to the perturbations. (It would also make their orbits unstable but I'm restricting them to only pay attention to the sun's gravity.)

I'm also hitting numerical precision issues as I expand the play area, so I'm trying to track those down.

I may end up falling back to having an “overworld map” for travel between planets, similar to Gravitar. This would lose some of the wow factor that continuous flight between planets would have, but you could operate on different time scales in the two modes and reduce boredom and precision problems.

Thursday, January 6, 2011

Planning for 2011

In addition to working on sound over the holidays I did some unsuccessful further experiments with the game camera. I want threats to be visible on-screen whenever possible. What I tried was to collect up any turrets that are close enough to hit the rocket, and include them in the set of things that the camera frames. Unfortunately this introduces big discontinuities in the framing circle's position and size as turrets enter and leave. I have camera smoothing, of course, but even so it is much jumpier than I would like. Maybe I need different "frequency bands" of smoothing, with the threats coming and going on a much lower-frequency smoother. I don't know.

I'm in the middle of planning for the upcoming year. At my day job we are in the last couple of months of development on Infamous 2, so that will demand a fair amount of time. Nevertheless I'm going to attempt to devote an hour a night to work on my own projects; this is what novelists with day jobs do, and I'm not going to get much of anywhere on less time than that.

I'm giving up any TV watching that I used to do, as well as most videogame playing that isn't with my daughter. (By the way: it seems to me there is a major dearth of games that are great for playing with your five-year-old. Currently I'm working through Lego Harry Potter with her. This seems like a potentially underserved market.)

In the near term on the lunar lander game, I'm going to do some experiments to determine the feasibility of having multiple planets that you can fly between. This is the major purpose of rockets, after all, and it's a feature most people who've played it have suggested. The big questions are:

Will this work with the physics engine? I'm going to have several very complex objects moving around (the planets) where I used to have most of the complexity in the static part of the world.

How will gravity work out? Currently the gravity all comes from a single point source, so orbits are straightforward ellipses, and are stable. I'm not too worried about having multiple gravity sources for the player; the rocket flies around under power most of the time and doesn't care if its orbits aren't stable. The mothership can stabilize its own orbit with its thrusters; it's already doing that to some extent. I will probably have to fudge the planets themselves so that they don't affect each other, to ensure that they have stable orbits.

How will the camera work out? Currently the camera rotates so that "down" is down. If I have multiple sources of gravity then there will need to be transitions between orientations so I'll have to figure out how that works.

I will reduce the planets to simple circles for purposes of the experiment, to work out travel times, camera, and so forth.

Wednesday, January 5, 2011

Treasures of a Slaver's Kingdom is Now Free

Good news, everybody! S. John Ross' magnificent text adventure Treasures of a Slaver's Kingdom is now free.
Enjoy!

Vorbis decoding working

OK, I feel like an idiot. Finally ran down the problem with my decoder, and it turned out to be due to accidentally reading the file as text rather than binary. One of the oldest mistakes in the DOS/Windows-programming book. As soon as the file read encountered the magic DOS end-of-file character it quit reading.

I still think the Ogg format's unnecessarily complicated, and I'm not sure Vorbis is the best choice for dialog lines. I don't want to pay ~4 KB per line of dialog in my game for a bunch of identical decode tables, along with the CPU and memory to unpack them every time I play a line. You could imagine putting all the lines in one Ogg stream and then seeking to the appropriate line, but that would require creating an index, something that Ogg itself doesn't provide. I may take a look at using GSM-style linear prediction compression if I can find a decent implementation.

Tuesday, January 4, 2011

Ogg = Lame

On further debugging I am forced to conclude that the Ogg container format is lame. This is not saying anything about the Vorbis compression format; I haven't delved into that other than to note that it has quite a bit of overhead for small files, at least the way Audacity encodes it.

Here is a good explanation of the ways in which the container format is unfortunately designed. For my purposes, the main problem has to do with how packet size is encoded. They didn't want to put a fixed-size 32-bit value in the packet header because they expected typical packet sizes to be under 256 bytes. Never mind that they have at least three other wasted bytes in their header, and they chose an encoding scheme that made their header variably-sized. The encoding scheme for packet length is this (feel free to laugh): first, a count byte. Then an array of that many bytes. Each byte represents a part of the size count; to get the full size, add them all together. You are expected to set the first N-1 bytes to 255 and the last byte to the remainder. It's sort of the inverse of compression, really. They should have thought very, very hard before making their packet headers variable size. And then if they really, really thought it was a good idea they could have used the UTF-8 style of encoding arbitrary-size numbers.

The decoder I was reading followed the spec in that it assumed that a non-255 value indicated the end of the array (it isn't paying attention to the count as far as I can tell). However, all the files I've encoded with Audacity have an early packet with a non-255 value in the initial byte, followed by a bunch of 255s, followed by a non-255 final byte. The initial non-255 byte is causing the decoder to prematurely think it's reached the end of the packet.

It's telling that Wwise (an audio middleware provider with which I am familiar) supports Vorbis compression but wraps it in a RIFF-style container format (what .wav files use) instead of using the Ogg container format. (Confusingly they retain the .ogg file extension, though.) It'd be nice if there was a standard for this; I'll have to investigate.

Monday, January 3, 2011

Ogg Vorbis

I have been debugging stb_vorbis.cpp, Sean Barrett's Ogg Vorbis decoding library. Somehow it is not unpacking the Huffman code tables correctly. Since it is broken on every .ogg file I've tried I think it must be somehow related to the way I'm compiling it.

Digging into the .ogg file format has been interesting. All the audio I record has identical code tables on the front (I'm encoding with Audacity), which amount to about 3.5 KB. Ogg is different from other compressed audio formats in that it doesn't have any assumed decoding tables; they all have to be embedded into the file. If you put individual lines of dialog into their own .ogg files that adds up to quite a bit of overhead (about 20% for my lines which are currently around 17 KB each).

A tidbit I learned: DVD audio is sampled at 48 KHz, rather than being the same rate as CDs (44.1 KHz). I'd wondered why PS3 games had 48 KHz audio; now I know why.

I've been thinking about how to complete my lunar lander project so I can move on to others. Part of the problem is that I haven't really settled out which direction I want to take the gameplay. More later; have to go to work now.

Tuesday, December 21, 2010

Rocket sound

I've put together a very basic sound engine for my Lunar-lander-on-a-disc game, although it isn't in a released version of the game yet.

It's my first time using XAudio2; it went fairly painlessly. The only trouble I had was with my synchronization between the playback thread and the sound generation thread. Originally I was using an event but it was possible for the consumer to occasionally generate two events (meaning it had consumed two buffers) while the producer was busy. After this happened a couple of times (I am currently triple-buffering) the producer and consumer would wind up writing to and reading from the same buffer, with nasty-sounding results. I switched to a semaphore which keeps a count of how many unqueued buffers there are and it works fine now.

At the moment my sound engine is very, very low-level. I generate sound in small batches (17 ms at a time, one video frame's worth) and feed it to XAudio2 for playback. I'm not using any pre-recorded audio yet and I'm not really doing much signal processing yet either. Since I'm triple-buffering there are a couple frames of latency; I may shrink the buffer size to reduce that.

Now I'm trying to come up with a good, interesting rocket engine sound. All I have so far is some white noise that has been filtered with a 64-tap low-pass FIR filter. It's also shaped with a basic envelope for when the thruster is on or off.

I am currently generating the white noise at 44.1 KHz and filtering it down which is incredibly wasteful. I'm going to switch to synthesizing the noise at 11 KHz or lower and upsampling to the final rate since I am knocking out all the high frequencies anyway. I want to experiment with a dynamically-changing filter as well so I can get interesting transient effects at the start and finish of a rocket firing. I'd like to give the noise more of a 1/f or 1/f-squared shape as well since I think it might sound better (louder bass, softer treble). It's just kind of a generic hiss right now.

I've experimented in Audacity with phasing and it produces some really nice whooshy effects so I may try to come up with a way of relating phasing to what is going on; maybe do phasing based on the nozzle angle or something, so that as the nozzle sweeps back and forth you get some stereo effects.

The steering jets will get their own sound generators as well, and then it's on to impacts, weapons, and whatever else is needed.