September 18, 2011

Star System Layout Complete

I now know why most space-based games don't try to include multi-star systems in anything approaching a realistic manner.  Whew.  The following star system types are now available:

Single
Binary center:  2 stars tightly orbit each other at system center with mutually shared planets.
Binary orbit:  2 stars orbiting each other further out, with planets around each individual star (or no planets, if they're in the "dead zone" of about 3 - 30AU which stops planet formation).
Trinary center:  3 stars tightly orbit each other at the system center, mutually shared planets.
Trinary, binary center, single orbiter:  2 stars together at the center of the system, with a single star orbiting farther out.  Planets potentially around each grouping.
Trinary all orbit:  3 stars, one at the system center, 2 more in their own, independent orbits.  Possibility of planets around each.
Quad center:  4 stars at the system center, mutually shared planets.
Quad binary center, binary orbit:  2 stars at system center, 2 stars orbiting each other further out.  Planets possible around each grouping.
Quad binary center, single orbit, single orbit:  2 stars at system center, then 2 independently orbiting stars further out.  Planets possible around each grouping.

Based on the system type, the masses of the stars present, their radii, and the orbital distances of the stars, I calculate approximate regions of stable planet orbits around each star/group.  If I wanted to do this accurately I'd use some sort of dynamical simulation, but that would be a bit crazy given that this is a computer game.  I have enough detail as is, so I fudged the calculations a bit.  For systems with just "center" stars, it sets the minimum stable distance at the largest center star's radius plus 0.05AU and the largest stable distance at 100AU (arbitrary, but approx. the maximum distance of Eris).

For systems with stars in separate orbits, it gets a bit more complicated and calculates the stable orbit zone around each star/group as a mass-weighted fraction of the distance from the star's surface to the zero-gravity point between each pair of stars.  I won't go into the details here, but I've been getting decent numbers out of this for multi-star systems.

In the process of setting this up, I noticed some errors in my star building routine that were creating nonsense values for the parameters of certain star types.  I had to go back to the source I took some of my equations from and discovered that his paper was full of typos!  That's the last time I trust something published in the Journal of Serbian Astronomy... probably should have seen that coming though :).  I've since fixed the star creation routine and have confirmed that all star parameters are within expected boundaries.

Now that I have my stable orbit regions, it's time to build the planets!  Gas giants are apparently key here, so they're going to be put in first and their characteristics will determine where/how many rocky/icy planets are created as well.

September 12, 2011

State Machine Up and Running

The game now launches in the Menu state and loads the corresponding bundle of Nifty GUI designs that take you through the various UI menus to set up a new game, load a game, set options, etc.  Upon loading/starting a game, the state machine:

1) initiates a shutDown() method in the current state (Menu) which de-registers all of its listeners from the event manager system
2) confirms shutDown() is complete
3) swaps to the Strategy state (the main game-playing state where you view the stars and everything else) and passes this state the game settings
4) runs a startUp() method for the Strategy state, which registers all of its listeners to the event manager if the state already exists or creates a new Strategy state (generates a new galaxy, stars, etc.).
5) sends an event that tells the elements of the Strategy state (stars, etc.) to enter their default views.
6) and then goes from there.

There's also a Combat state that remains to be implemented and which is only accessible via the Strategy state.

I've made a small modification to my event manager as well.  The normal system receives an event and broadcasts it to all the listeners registered for that event.  However, there are certain events for which there may be many listeners, only a few of which are affected.  For example, adding a new planet to a star system is a possible event in the game and is an action that all star systems listen for.  In a 3000 star game, the event manager would have dispatch this event to all 3000 of them so they can figure out if they're the one adding the star or not.

One way around this is to directly access the star that is getting the new planet, circumventing the event manager entirely.  But I'm trying to maintain very loose coupling between systems and this violates that rule and opens up the possibility for more problems down the road as the code gets more complex.

As an alternative, I've added in the ability to specify an optional target for an event message.  Every game object (physical--planets, stars, etc--and social--empires, religions, etc.) has a long int identifier associated with it, so an event may specify the identifier or a particular object.  The event manager will test for an identifier before doing anything and, if it finds one, will send the event directly to the correct target.  The tradeoff is maintaining an extra hashmap in the event manager class that links the identifier to an object, but the boost in performance will be worth it for these "many listener" events.  Adding stars to a new 3000 star galaxy went from taking 6 seconds to less than 1 second after this change.

Next up, I'm designing planets and other habitable objects.