Tuesday, January 27, 2009

I've been trying out a few ideas with quick & dirty demos to see if they're at all promising as part of a game. Two posts ago I talked about a spaceship editor, where you could place the thrusters, and the “AI” would learn how to pick thrusters that most closely matched your desired motion. In the last post I spent some time describing how I spent some time trying to figure out the characteristics of the ship, how I learned more about the problem I needed to solve, and some of the things I tried to find a “nice” solution to the math. I was really happy with the things I had worked on. However…

The real questions I wanted to answer were:

  1. Is it actually fun to fly a ship with this physics model?
  2. Is it actually fun to design a ship? In other words, are there interesting designs and tradeoffs?

Somewhere during the process I realized that getting the “nice” solution wasn't that important, and I had probably spent too much time on it. (Reading this article reminds me that I get distracted too easily on fun problems and I have trouble completing things.) I wasn't getting closer to answering the important questions. Instead, I was having fun learning some math that I had forgotten 15 years ago. Having fun learning math isn't bad; it's just not the main goal.

My spaceship flying around

To answer the first question, I spent some time in various ships just flying around. My conclusion was yes, it's fun to fly around in a world by itself, but no, it doesn't seem like it'd be fun in an actual game, where there are other things to do. And that's when it hit me: all that time I spent thinking about the math might have been a waste of time (except that it was a lot of fun to learn some math); I should first make sure I can make the ships fun to fly.

I flew around a lot and thought about what bugged me. The main problem was that inertia was fun at first but it seemed to get annoying after a little while. For example, if I'm moving forwards with W, and then I rotate left with A, I'm still moving, but my jets are pointed at an angle. To stop moving you need to use a combination of S and Q. Even worse, since it's a keyboard instead of an analog controller, you can't hit the right mix of the two to make yourself stop.

In addition, it wasn't clear to me whether the controls should set acceleration, velocity, or target position. Acceleration was the most natural thing, and that's what I started with. But that means when you hit any key, you start out slow, then go faster and faster, until it's out of control. That might be realistic but it's not much fun. I switched it to setting velocity. But what velocity should I target? I arbitrarily chose some multiple K of the acceleration, so that after K time you'd reach that velocity.

I also needed to do more tuning. The mass, moment of inertia, friction, and rotation/translation tradeoffs are set arbitrarily. I had tried adjusting this but none of the parameters were quite right, and every time I changed the physics it got worse, and I had to tune to make it better again.

I tried to answer the second question (whether there are interesting ship tradeoffs) by creating several ships. Based on that experience, my answer is maybe. The ships I made are noticeably different but I have a clear favorite. If there's only one best ship then the ship editor's not going to be interesting. The problem is that the answer to the second question depends on what I do with the physics.

So I decided to work on the physics first.

I tried tackling inertia directly, with some ideas from a friend:

  • Inertia in World Coordinates gives me realistic physics for flying ships. This is what I had started with, and this is what I was unhappy with. When you're going north, and turn left, you keep flying north. The inertia keeps moving you north, even if you face west.

  • Inertia in Ship Coordinates gives me something that behaves more like a vehicle on wheels. When you're going north, and turn left, you start going west. The inertia keeps moving you forwards, whatever direction that may be.

  • No Inertia would mean that you only move when thrusters are fired. This is the most extreme change but if inertia is really a problem then it's worth a try.

I also tried treating rotation differently from x and y, because rotation seems to lead to some of the situations that make the ship less fun to control.

My spaceship flying around

It was only after playing with the various options that I learned that I do really want inertia in world coordinates. Sometimes I just have to try something to help me learn something (also see this blog post). Having no inertia, or inertia in ship coordinates, just didn't feel fun to fly at all, and that's not what I would've predicted. I had the right form of inertia; something else was wrong.

After all the testing, I realized I wanted inertia but not the full effect. At low speeds, inertia is great, but at high speeds, inertia is less fun. With inertia alone it takes as long to speed up as it does to slow down again. It's okay if it takes a second or two to reach a high speed. But when I let go of the keys I want the ship to come to a stop pretty quickly. I added a force to slow the ship down. I tried three approaches:

  • Constant force decreases velocity V by up to K. This can be interpreted as surface friction.

  • Linear force decreases velocity V by K*V. I don't know what this might correspond to in physics, but in the calculations it corresponds to “reducing” inertia.

  • Quadratic force decreases velocity V by KVV. This can be interpreted as air resistance.

All three of them helped. After trying and tuning the three I decided that the linear force reduction was the most pleasant, but still not ideal. With quadratic, the problem I ran into (which I might have predicted if I were smarter) was that you can't increase your maximum velocity much if you add thrusters. Instead, it was largely determined by the air resistance. That would be fine if I were creating just one ship, but for the ship editor to be interesting, I need the number and power of the thrusters to actually matter! Constant friction left too much of your motion determined by inertia at higher speeds. The linear slowdown felt the best. I can't justify it if I were going for realism, but I'm going for fun, not realism.

I think flying the ship can be made fun. The next question to tackle is whether there are interesting tradeoffs in ship design.

Labels: , ,

8 comments:

Anonymous wrote at January 28, 2009 2:46 AM

Why do you need to introduce friction in a space game? You already have a ship that can use its thrusters to stop itself. Simply make it that when the users releases a both keys on an axis (W-S, Q-E, A-D) then the ship automatically applies a thruster to make the velocity in that axis 0. This will also make choosing between symmetrical/assymetrical thrusters important, because in one case you'll accelerate quickly but slow down slowly, etc.

Amit wrote at January 28, 2009 9:16 AM

Anonymous: Yes, the ship automatically applies a thruster to set velocity to zero. That's what I originally implemented and that's what wasn't that much fun. It was -cool- but not fun. If you press A for 5 seconds and are now rotating quickly, it takes 5 seconds to decelerate back to 0. I added friction so that (a) deceleration would be much faster than acceleration, (b) acceleration would not lead to unlimited velocity.

Darren R wrote at January 30, 2009 12:07 AM

Hey Amit,
Dismissing 'realism' when it comes to game physics is always a good idea, just so long as the physics are self-consistent.
In regards to your friction problem, have you considered implementing a brake which the player can apply to -gradually- reduce all motion to zero. This could be in combination with the world friction. Never mind that spaceships should not be affected by friction, they can always be flying on a planet, or you could make the exact same game using boats or some other vehicle.

I think the importance of varied ship design will only really become clear when you know what environments they will be flying in. If the ships are racing on a circuit, perhaps as in Star Wars Phantom Menace, some circuits might favor high speed, others will favor tight cornering.

Amit wrote at January 30, 2009 7:49 PM

Hi Darren,

No, I hadn't thought of having a brake. That might be worth a try!

I agree that the environment will matter. I had imagined you'd design a different ship for each environment you're in, or perhaps you'd adapt it over time. Perhaps I need to set up a few test environments for this prototype.

twifkak wrote at February 01, 2009 2:04 AM

Towards making it "fun," you might consider thinking of the direction of the ship not in regards to the direction of the thrusters, but as the player's desired direction of motion. That is, if I'm going east, and I turn to face north, there will be some inertia, but I will eventually be going straight north, without having to compensate by turning a little further left. Expert players can learn to make sharper turns by overturning.

Amit wrote at February 01, 2009 8:49 AM

Hi twifkak, thanks for the suggestion. There are two things I hope will work here. One is that the thruster calculation is based on how the direction you want to move differs from the direction you are going. So if you are still going east but you want to go north, I'm calculating what combination of thrusters will both stop the eastward motion AND make you start going north. The second is that the friction will slow your eastward motion. As you say, expert players will be able to make better turns than this but novice players can rely on the defaults to do what they want.

Lorenzo wrote at February 10, 2009 7:48 AM

"If you press A for 5 seconds and are now rotating quickly, it takes 5 seconds to decelerate back to 0."
This is of course boring, but the problem begins with the notion of accelerating (as opposed to merely pressing the acceleration button) for 5 seconds.
The avionics of any starship would limit angular velocity (not to mention velocity) to reasonable amounts: the ship should reach the top angular speed (I suggest 5 to 60 rpm) in a fraction of a second (I suggest 1-3 animation frames), turn for a while and slow down equally quickly.
Regarding controls, the ship can stop spinning automatically when both buttons are released (suggested by the first anonymous) or keep spinning indefinitely, stop with a press of the opposite button, or start spinning in the opposite direction with a single press of the opposite button; the choice can be left to the user and/or made during tests.

jcdickinson wrote at April 15, 2011 6:42 AM

Idea for 'gameizing' this component:

- World starts off with a fixed set of ships (hardcoded) controlled by the AI. These ships would be poorly designed.
- A metric is calculated that includes "total damage dealt to player" and "time survived".
- The metric is used to select the parents in a genetic algorithm.
- The chromosones would be used to control the AI and design individual ships.
- Enemies come in wave cycles; each wave with its own GA history and 'tendencies' (a further metric where the ship should gravitate to certain graph types).
- Enemies always do the same amount of damage.
- There are always the same number of enemies.

Now the idea is that this would exploit any weaknesses in the player's ship; and the player himself. The game would have a natural difficulty progression as the GA optimizes the ships.