Sunday, March 22, 2009

Last year I decided that I just don't have the time and energy to work on a full game, and instead I should work on quick prototypes instead. I had planned to try an idea every few weeks. The space station generator was one of these; the spaceship editor was another. Spaceship physics turned out to be really interesting and I kept working on it. It's been months now. I have lots of other things I want to try, so I need to wrap this up, even if there's more I could do.

In the last post I talked about the physics. The final step was to figure out whether there were interesting tradeoffs that a player could make when designing a ship. I needed a spaceship editor.

State diagram for mouse dragging

I made a circle that could be dragged around with Flash's built-in draggable object feature, but I switched to handling the mouse events myself, so that I could add "snap to angle" and other constraints. It wasn't long after having a draggable circle that I made a circle for each thruster. And then two, one for the head and one for the tail. I also wanted the thruster to move as a whole if you dragged the base, but only the tip to move if you dragged the end. I overlaid these on a large version of the ship to make a ship editor. Now I could start answering the key question: are there interesting design choices?

After playing around with lots of configurations my answer was no. It's always better to put the forward thrusters near the wingtips. You don't lose any forward thrust, and you gain a great deal of rotational speed. The other thrusters were less of an issue, because they were used for less common motions.

To make this interesting I need some disadvantage of putting forward thrusters at the tips. One thing I considered was that thrusters at the edges of your ship are more vulnerable to damage. However, I don't actually have a game here, so that's not something I can easily test. So I turned to the other idea: thrusters require support that have mass. Putting a thruster far from the center requires more massive supports, which slow you down. I started with mass and moment of inertia calculations from physics, and then used tuning and experimentation to come up with something that felt reasonable. The main tradeoff I focused on is between rotational and forward acceleration, when both are from the same forward thrusters. If you move the thrusters near the wingtips, you get lots of rotation, but you need a lot of mass for the structural supports, and that slows your forward acceleration. This plot shows acceleration versus thruster distance from the center:

Tradeoff between forward and rotational acceleration

It shows that at least for the forward thrusters, there's a nice tradeoff between rotational and forward acceleration, and you can't get unlimited rotational power because the supports become too massive. There are lots of other things I could look at, but I think some tradeoffs depend on the game (for example, they may be completely different if the ship is in an atmosphere than if it were in space), and I'm not writing a game right now.

I eventually recognized that I could keep working on this for a long time, but I need to move on and explore other topics. I've mostly answered the question I set out to answer: if you let the player design the spaceship, are there interesting tradeoffs arising from the physics? I think the answer is yes, but probably not as many interesting tradeoffs as Spore's approach would allow. In addition, things weren't automatically interesting; I had to design a tradeoff and then tune the physics to make that tradeoff show up, and I had to be careful to avoid overpowered ships. That was unsatisfying. In a real game I imagine I'd have to manually design lots of tradeoffs for different game levels or areas of the world, and it'd be quite tough to test all the combinations. And even if I could do that, controlling sliders in a continuous tradeoff space seems less fun than picking from some really interesting manually designed items in Spore or Ur-Quan Masters. So yes, I was able to make what I set out to make, and it was fun to play with, but probably would be a lot less work and more fun to give people a few interesting choices.

The Demo

Of course after all that I should let you try designing your own ships and see what you think. Instructions:

  1. Press T to change ships (you may have to click on the map first to get focus). The demo ships are: yellow square (4 thrusters), green square (like yellow but you can make it asymmetric), teal curved, purple curved (like teal but two thrusters are broken, so it can't fly properly), blue square (8 thrusters!), red triangle (goes fast but can't turn well). I mostly play with the yellow and blue ships.

  2. Change the ship by dragging the thrusters and adjusting their size and orientation. As you do this, watch the graphs. The bar charts show what happens if you press one key at a time. The polygons represent your current flight envelope for two keys at a time. I find that I use the W+A and W+D combinations often, so I watch the chart in the lower left. The shaded ovals show the "target" that you want to mostly cover if you want a reasonable ship. The yellow and blue ships are easy to improve: just increase the power of the thrusters and they will fly well. The teal and red ships are slightly harder, and the purple ship is near hopeless. In a real game the number and power of your thrusters would be limited, and fuel efficiency and fuel tank size would be additional factors to consider.

  3. Fly the ship around with W=forwards, S=backwards, A=rotate left, D=rotate right, Q=slide left, E=slide right, Z=reset position.

(screenshot of spaceship editor)
Try the demo.

The demo is written with Flash 10 in mind. It should work with Flash 9 but there may be some visual artifacts (due to bugs in Flash 9 that I didn't work around). There are some other minor bugs that I might fix someday.

I'm finished with the spaceship editor mini-project and haven't decided what the next mini-project will be. I really enjoyed working on the spaceship physics and editor, but I spent too much time on it, and hope to spend less time on the next mini-project.

Update: [2009-12-05] If you want to try a game that lets you create your own spaceships, check out Captain Forever. It's pretty neat.

Update: [2012-08-16] Another game that lets you design your own spaceships is Gimbal.

Update: [2012-10-15] Also see Evolving Spaceship Designs for Optimal Control and the Emergence of Interesting Behaviour [PDF], by Samuel A. Roberts and Simon M. Lucas, or watch the video.

Update: [2017-01-05] Another game that lets you design your own spaceships is Reassembly.

Labels: , ,

4 comments:

Amit wrote at March 22, 2009 12:50 AM

For those few of you interested in what I did with mouse events: I used mouse over/out to highlight the object you're hovering over, mouse down/up to handle the mouse press, and mouse move to handle dragging. But as soon as I moved the object, the mouse out event would fire and my dragging would stop. To work around this I added a huge hit area that covered the entire screen, and I removed the hit area when you released the mouse. This worked reasonably well except there are always corner cases. What if you drag the mouse outside the window and let go of the mouse and then move the mouse back in? Will I see the mouse up event? It seems like the answer is no, which leads to a mess. The roll in/out events seem to be of no help. Event.MOUSE_LEAVE (not that it's not in MouseEvent!) might be the thing I need. But I found a much better way (probably from senocular's site): check MOUSE_UP on the stage instead of on my draggable circle sprite. So when the mouse button is pressed, I add an event listener for mouse up and mouse move on the stage, and I remove these two event listeners when the mouse is released. I removed the ugly hit area hack. This seems to behave the way I want: you can drag the object around, and it stops dragging only once you let the button up.

Bram wrote at March 22, 2009 5:33 PM

Well done, Amit.
It's fun to experiment with your editor.
You are close to a complete game with this.

In my opinion: this would be the route to take:
- Add obstacles, or a course in your world
- Implement an Autopilot that flies the course without crashing.

Gameplay would be:
- Player designs the ship
- AI flies it on the course and sets a time.
- Lowest time wins. (Maybe rate on fuel consumption as well?)

To make it interesting, you could even use two courses. On the test course, you can tweak your design. Once finalized, your design will be rated on a new unknown course.

For course navigation you could use the same brute force approach that you have been using. Train a neural network, or use GA's to navigate.

Amit wrote at March 28, 2009 12:54 PM

Thanks Bram! Obstacles, a course to follow, or things to shoot at would be useful for evaluating the ship. I think an AI flying player-designed ships would be quite interesting. It's beyond the scope of the editor project (which was supposed to last a few weeks) but it might be a future mini-project.

Anonymous wrote at April 14, 2009 9:33 PM

It's a very very amazing idea. I've been just trying some 2D experiment and was thinking what can be done ... you just did it :)

wow...well done...the demo is quite a game by it self.