May 20, 2012

Update 5/20

I'm still alive and kicking!  As I mentioned in my last post, I've had a bunch of stuff going on in my life lately.  Just finished a draft of a journal article based on my Master's thesis from 2 years ago, just bought a house a couple weeks ago (and will be moving in ~1 month), had family visit, and have still been slammed at work.  I've put in some time on the game when I've been able to--and when my brain hasn't been fried from all the other stuff going on.

I am still working on getting basic graphics, interaction, and audio going.  In what time I've had since my last update, I've done the following:

1) Created a framework for "Features" that can be added to any object in the game.  For example, a star may be given a SolarFlares Feature and this would change the way it appears on the map and also allow it to create SolareFlareEvents, capable of doing damage to ships and (if severe enough) planets in its system.  Features can contain ViewModifiers, DataModifiers, and EventGenerators.

2) ViewModifiers and DataModifiers... well, do what the name says.  They can be applied to any object in the game.  ViewModifiers can change the way an object looks by altering its texture, colors, etc.  I still have to figure out what the limits of their capabilities are, but for now I'm using them to change textures.  They're usually coupled with Features that alter the behavior of an object, though they can be applied independently as well.

DataModifiers change some variable within an object's model data.  All object data is now kept in a HashMap<String, Double>, where the String is the variable name and Double is its value.  DataModifiers are Strings that are sent into the model and applied to a target variable.  They consist of a source, target variable, and modification.  For example, the technology of Nanoprobes could carry with it "Nanoprobes Production +2."  The String is parsed and the modifier +2 is added to Production, while the source of the modifier (Nanoprobes) is registered.  All modifiers are tracked in the model and can be added and removed through referencing this source.  This setup was necessary because players can lose or throw out technologies, reversing any gains previously made.

At this point, I see DataModifiers as probably more flexible than ViewModifiers and found in a wider variety of places (Features, technologies, special events, etc.)

3) EventGenerators generate in-game events.  They can be found in Features by may be found in other objects as well--I'll figure that out as I go along.  They can have a certain probability of generating an event every turn or can require some logical trigger condition to start.  Some persist forever, some for a limited number of turns, and some are single-shot and just create one event.

4) Vastly simplified my Events system.  I was creating an entirely new class for each event type and, since I'm making this a very loosely coupled application, I was generating a ton of very small classes that were all quite similar.  It makes more sense to just use a generic template class (ApplicationEvent), provide it a String for a name ("SolarFlareEvent"), and then stuff any needed object references into it (via an array of generic objects--Object[]).  The receiving classes look at the name and know exactly what to expect in the Object[] array, so they can cast to the appropriate types and do their thing.  This does mean that I still need to create a whole bunch of EventStrategies (which encode the responses to particular events), but its about 50% less coding burden in this area.

5) Simplified references to EventManager, AssetManager, and RootNode.  Don't remember if I've discussed these before, but EventManager handles all game events and communications between objects, AssetManager is part of JME3 and loads/maintains all assets (textures, materials, audio, models, etc.), and RootNode is also part of JME3 and is the base object to which all rendered visuals are attached--if you want it to appear, you attach it here.  I found myself having to pass references to these things to virtually everything and it was getting cluttered.  I'm a little worried about my solution, but it seems to be working so far.

And that solution is:  Create classes called EventPortal, AssetPortal, and RootNodePortal that contain static accessor methods for their corresponding classes.  I just initialize one object of each of these classes at startup, pass them a reference to the appropriate *Manager class (or RootNode), and can then access them anywhere.  I suppose its bad OO design since I'm not explicitly passing in references to objects that use these systems, but this removes a lot of worry for me while coding.  If I need a given object to send a particular event, I just write EventPortal.queueEvent(new AppEvent([misc. data])) and that's it.  No need to pass references to everything through all my various Builder classes.  I don't want to expand this technique further though, as I'd prefer it to only be used for referencing these really big, very common systems.

6) I've rewritten some of the external data loading for more flexibility and greater ease of modding down the road.  JME3 uses a Material class to set the visual properties of game objects and encourages either creating Materials on the fly or, if creating lots of them, loading pre-made Materials from .j3m files.  Well, so far I only have about a dozen materials, but I'm using them upwards of 10,000 times to create (for example) stars.  Creating them on the fly is therefore slow.  However, pre-made Materials would all have to go into self-contained .j3m files, of which there could be dozens or hundreds.  Modding that many files would suck.

Instead, I've placed all the relevant data for each Material into one table in a .txt file.  I load this data up and build each Material once at the start of the game, then save them in my AssetPortal class.  This avoids slowdown from creating thousands of new Material objects, but also lets modders (and myself, the developer) avoid slogging through tons of separate files to change things.  It's all in one table.

...

Wow, that actually ends up being more than I realized.  Still not enough for all the time that has gone by.

After all these changes under the hood, I am now back at a point where I can get a star up on the screen and have its level of detail change as I zoom in and out.  Next steps are, as they have been since February, being able to click and highlight it, play a sound when clicked, and get some sort of GUI display to appear/disappear when its selected/deselected.

Then I'll create a system for multi-star system visuals.  At a certain level of zoom, you will be able to see the number of stars in each system.  When zoomed further out, each system is just represented by a single star icon.

We're moving into the new house in June, then in July I'm traveling for work for over half the month.  I will do whatever I can in my free time!

March 21, 2012

Update 3/21/12

Still slow progress, for a variety of reasons--family obligations, looking to buy a house, got sick for a little while, work time encroaching on free time, etc.  I also just had an old, unfinished project from grad school pop up and I'll have to devote some time to it over the next month or so.

In what time I've had lately, I've made a lot of progress in learning how to use the graphical aspects of the Java Monkey Engine.  This has resulted in (1) some refactoring and reorganizing of my code and (2) the creation of some test textures and external data files.

Otherwise, not too much to report for now.  I'll keep chugging along--I'm in this for the long haul!

February 26, 2012

Star System update

Time to check in and see where things stand.  In my last post, my aims for February were:
My next step is to fully create a single StarSystem object--the data model, graphics for its view, and the controller that handles its events.  I want to be able to experiment with level-of-detail changes, clicking and highlighting, audio effects, loading/saving it, switching between views of the model, and adding modifiers to its model data.  The toughest part will likely be handling the graphics and views, as I've neglected that aspect of the game so far and am not sure how robust my current structure will be.
(1) Data model:  No changes made here so far.  I will have to add in some more data eventually.
(2) Graphics:  I have created a stand-in star object and can load a texture onto it.
(3) Controller:  Done, though I may have to work on more star system-level events as I go forward.
(4) Level-of-detail changes:  Done.  I created a cameraWatcher class that monitors the camera's position and field of view and issues events to increase or lower the level of detail displayed.  When you zoom in right now you see a full, spherical, rotating star, but at a certain distance it is replaced with a flat 2-D image.
(5) Clicking and highlighting:  Half done.  I have implemented mouse-click listeners for all game states and can detect whether or not I've clicked on the star system.  I have not yet implemented highlighting the system after it has been clicked.
(6) Audio effects:  Not done.  Goal will be to make a click/un-click sound when star is selected, de-selected. Secondary goal is to play some music while testing.
(7) Loading/saving:  Not done.
(8) Swapping views:  Not done.  Create interface buttons that alternate between two different views of star system when pressed.
(9) Model modifier system:  Not done.

Other changes:
--Created a strategy view camera which is fixed looking "down" at the star map from above.  It can move up/down and left/right to traverse the map, plus zoom in and out with the mouse wheel.  I'll need to go back and make the zoom smooth later.

--Better integration of the inputManager into the larger game system, plus miscellaneous changes to the testing system and star system views.

Next steps:
Finish (5) through (9).  Add the following goals:

(10) Create interface elements to display star system data on the right side of the screen.
(11) Be able to interact with these interface elements.
(12) Display star system name below star.

Looks like this will take me into mid-March.

January 27, 2012

XML work finished

Well, finished for now...

Over the last month, I have accomplished the following:

1) Loading of game data from external XML files, enabling modding of the game's parameters.  XML files contain information on the relative proportion of star types, the sizes of galaxies, the colors of stars, and so on.  I have plans to use XML data to define game events, ship designs, and more.

2) Loading/saving of game objects from/to XML files.  I likely have a bit more work to do in this area, but the base capability is there and works for now.  I'll revisit this during later development as the need arises.

3) Refactoring of my object structure, moving away from inheritance and toward composition with interfaces.  It feels more intuitive to me to assemble an object from smaller pieces than it does to inherit.  With composition, you can mix and match as needed, provided you code to the interfaces that go with each piece.

My next step is to fully create a single StarSystem object--the data model, graphics for its view, and the controller that handles its events.  I want to be able to experiment with level-of-detail changes, clicking and highlighting, audio effects, loading/saving it, switching between views of the model, and adding modifiers to its model data.  The toughest part will likely be handling the graphics and views, as I've neglected that aspect of the game so far and am not sure how robust my current structure will be.

I'm guessing this work will take most of February to finish.

January 22, 2012

Code re-tooling

This is where my naivete with working in Java shows itself.  I'm largely self-taught and there are definitely some holes in my knowledge when it comes to good coding practice, designing flexible code, etc.  While testing out XStream to save a simple starSystem object, I realized that my existing code structure for in-game objects--based purely on inheritance--would make things somewhat difficult to load/save and was also going to make it very difficult to go back and refactor code later on.

So, I'm switching to a structure using interfaces and object composition ("has-a" instead of inheritance's "is-a" relationship).  Shouldn't take too long to retool--I've already created the necessary interfaces and have reworked the Star model classes already.  Next I'll rework the Star controllers and then move on to the starSystem classes.

A couple hours effort overall, then its back to working on the load/save system!

January 20, 2012

Custom Galaxy Shapes Implemented!



All this mucking around with XML is paying off!  Modders can now create custom galaxy shapes by entering (x,y) coordinates and a name into an XML file and placing it in a folder called CustomGalaxies in the game directory.  The way you enter the points is to imagine that you're drawing the shape without ever "taking your pencil off the paper."

January 8, 2012

More XML

Well, playing Deus Ex: HR definitely took more time than I wanted... :).  The new year also brought a bit more stress at work, so I've been less productive after work than usual.

In the interest of simplicity, I'm going to try and use XStream for all my XML needs.  I've developed a basic XMLLoader class which loads data from a pre-defined list of files into pre-defined Java classes, which are then accessible to various game systems as needed.  This should still provide modding flexibility, as each XML file will host an expandable list of entities of a given type.

For example, a file named SpaceMonsters.xml will contain a listing of all the space monsters in the game.  Each monster would be contained within a tag such as <spacemonster></spacemonster>.  New monsters can be added by simply creating a new set of these tags at the end of the document and filling in the relevant details.  In code, all space monsters will implement the same ISpaceMonster interface.  Using XStream, I can read SpaceMonsters.xml entries into an ArrayList in code and then handle any given monster via its interface.  It should be straightforward to implement a similar system for technologies, random events, default starship designs, etc.

Tasks remaining:

1) Finish conversion of remaining Java Enumerations into XML files/classes.
2) Add in support for custom XML galaxy shapes.
3) Implement load/save capability for a single star object (as a test run).

December 30, 2011

XML and Save Games

I'm about ready to continue forward in developing the various game classes (planets, stars, etc.), but there is one last system that I definitely need to build before moving forward much--saving and loading the game state and game parameters.

I'm planning to hold as much data as possible in external files, allowing users to edit and modify as they wish.  I see three different types of data files:

1) Game parameters, such as galaxy sizes, weapons damage, or the max. number of planets allowed per system.
2) Save game data.
3) Application settings information, such as keyboard mappings, video settings, etc.

I'm currently using Java Enums for some of (1), have not even touched (2), and have a Settings object that I pass to the relevant systems for (3).  I plan to convert (1) and (2) entirely to XML, and probably create an XML file that contains (3) as well.

For (1) and (3) I can probably use either Java's native XML capabilities (likely going the DOM route), JAXB, or XPath for creating new, user-generated classes.  The latter two options would be exercised if the user (for example) added new technologies to the game by editing the tech tree XML file.  

For (2), I plan to use XStream, which looks like a very quick and powerful way to grab object data and store it in XML, and then also unpack XML data back into Java objects.  I test ran it the other night by saving just one StarSystem object--and it followed all the references in the Controller, Views, and Model for that system, creating a 1.2MB text file...  Upon review, it had followed references to Java Monkey Engine classes and ended up saving a good chunk of the graphics engine's underlying object data, none of which was necessary.  Oops.  I can write some conversion classes that will better determine what data should be saved.

So all this is what I'll be doing over the next couple weeks--in addition to just refreshing my memory on XML (worked with it for a month or two about 5 years ago!) and celebrating the new year!  I also got the new Deus Ex game for Christmas, so I might be a little slower than I'd like in getting to all this... :)

December 19, 2011

Minor update--Elliptical Galaxies and Collision Detection

1) Straightened out a few kinks in the collision detection algorithm.
2) Converted the bounding boxes for detecting collisions into bounding polygons, so custom galaxies of any shape can be aligned in a variety of ways and not "squared off" as the old bounding rectangle method I used would have it.
3) Implemented elliptical galaxies.
4) Implemented random galaxy rotations--most noticeable with the ellipticals.  Adds some variety to the layout.

In the picture below, the bright orange pixels are the bounding polygons for each galaxy--I turned them on in this run to observe.  There are two large elliptical galaxies, two large spirals, one medium spiral, one small spiral, and about four tiny ellipticals.  Note that not all ellipticals will look like footballs--I set their parameters to make them dramatically non-circular for testing reasons.


I'll maybe have one more post in the next day or two, then nothing until after Christmas.  Enjoy!

December 11, 2011

Multiple Galaxies

I can now place multiple galaxies in random, non-intersecting patterns.  Each galaxy has its own hex grid that references world coordinates--meaning, I can place the galaxies anywhere and their grids take on appropriate values, but I don't have to place any grid locations between the galaxies.  Saves quite a bit of space.  Later, I'm going to add the ability to create hex grid locations in empty space to allow for the possibility of new destinations being created out there.

Note that the 2-arm spirals below are actually barred spiral galaxies.


December 10, 2011

Star Locations Picked

I've finished the algorithm for randomly generating star locations within a galaxy.  A few pictures, again using stand-in graphics (the blue dots):



Detailed Spiral Galaxy Shapes Complete

I know I promised some pictures with stars in them in my last post, but they're not here yet--don't worry, they're coming though!  Since my last update I've been integrating the hex grid locations into my game.  This has ended up being a bit more complicated than expected due to the sheer number of them.

I encountered two performance bottlenecks:

(1) Generating the hex locations
(2) Determining which locations are in which sector of the galaxy.

The algorithm for (1) runs in O(n^3), which would be fine if my hex grid was only about 50x50 tiles (2,500 tile area).  Unfortunately, the grid can be as large as 300x300 (90,000 area) so the generation was taking anywhere up to about half a minute.  The solution was to auto-generate a large array of locations and save them and their distances from the center point of the map (0,0) to a text file.  The text file can then be read in during any galaxy generation, with the read stopping at a specified distance (so the whole file isn't read every time).  The process now takes ~0.5 seconds for the largest galaxies, though the text file is about 8 MB.  I could probably put it in a .zip file to decrease that size.

(2) was a bit more difficult until I discovered that Java AWT could create polygons from (x,y) coordinates and test if points were within them very quickly.  It takes about 3 seconds to test 75,000 points and determine which sector of the galaxy they are in.  My only complaint is that the test can only use integers, so there are some rounding errors that create a handful of points that should be in a sector but are not.  If the test used floating point numbers there'd be no problem, but I'd guess it wouldn't be so fast...

On top of (1) and (2) I've had to fix a number of small errors with the positioning, rotation, and spiral skewing of the various branches that come off the main arms of the galaxy.  The pictures below show locations in the main body of the galaxy (green) and those outside the galaxy (red).  The red locations will actually host some scattered stars, as they form the galactic halo.  The center red hole shouldn't be there--one of my sectors isn't showing up for some reason.  My apologies in advance to those who are red/green colorblind--I'll think of a better color combo if I post something like this again.



There are 2, 3, 4, and 6 arm spiral galaxies.  Shown above are a 3-arm and a 4-arm.  Remember, these pictures are just for testing and the solid colors are actually about 90,000 individual points--the shots are just very zoomed out.

December 1, 2011

Hex Grid Working

I've been re-tooling the galaxy generation algorithm to account for the existence of the hexgrid.  While doing that I've also been testing the amount of memory that a hex grid will consume and finally playing around with different lighting options, etc. in JME3.

I can now generate circular arrays of hexagons over 400 tiles wide and maintain a decent framerate.  The picture below is a sample grid that's about 100 tiles wide.


To keep performance acceptable, I've made the tiles all one object.  Additionally, as you move away from the tiles they'll disappear.  Note that they become a blue "haze" above at some distance away--that haze will be replaced by a gradual fade out as they recede into the distance.

I've estimated that a low density, 3,000 star spiral galaxy will require a circular gird approximately 400 tiles across, so I appear to be ok.  I'll try to get some more pictures together (maybe with a star or two) this weekend!

November 11, 2011

Update: Space geography

Almost two months since my last update, but I've been busy.  Still lots of work ahead though!

The star system layout code has been re-worked and made much, much more OO-like.  I had to go back and debug it and ended up not remembering how it worked, so breaking up what was a 2000+ line system design class into several smaller classes with self-contained methods and variables helped a lot.

I've also taken a crack at making spiral arms more interesting by adding arm branches that diverge from the main trunk, but so far the results are not very spectacular.  However, this effort lead me to realize a few things:

1) There is no reason to have the star layout in 3D, even relatively flat 3D.  Yes, it adds realism, but it also makes judging distances and moving ships much more complex.  I've decided to flatten out all my galaxies into a 2D plane.

2) By flattening into 2D, I can now much more easily implement some more interesting "space geography" (astrography?) stuff that I've wanted to do since starting.  Stars voids and clusters are just the beginning, and I'm keeping the full list secret for now :).

3) 2D also allows me to better organize the game space.  Rather than picking points out of the ether and working with undefined spaces between stars or other objects, I can now implement a grid system and bring some order to space.  I'm a little concerned about the amount of memory this will take up--some back-of-the-envelope math tells me that a 10,000 star game with 4 galaxies could require as much as 1,000,000 grid tiles, which would take from 30 - 50MB of memory for just the tiles.  Eek.  But a 10,000 star 1 galaxy game would probably need half that or less (as there would be no empty spaces between galaxies), so I have some options to reduce the overall burden on memory.

Ships would not be forced to travel along the grid (they can still move in straight lines any way they need to) but they would be forced to choose a grid tile as a destination--travel paths must always end at the center of a grid tile, which is where anything in that tile resides.

The main benefit of the grid is the ability to organize space and to pick out a region of space relative to other regions.

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.

July 16, 2011

Spiral Galaxies Done (for now)!

Spirals are done... enough.  Still have some tweaks that I want to implement, but I'll wait on those.  Here's a description of how I designed spiral galaxies in 3D:

I realized early on that I would have to generate the core and arms separately, as there's no single geometric shape that easily describes an entire spiral galaxy.  The core would be a disk that bulged a bit toward the center, while the arms could be described by half-ellipsoids--think of them as looking like footballs that are pulled to be longer and then cut in half.  One of those halves can roughly represent the volume of a galactic arm.

When you cut an ellipsoid in half, you get a flat "butt" to it.  In order to join this flat region to the side of the disk-shaped core, I decided to cut away at the sides of the core to transform it from a disk with rounded edges to a polygon-disk.  In other words, a spiral galaxy with 4 arms would have a square core (though it would still have height in the z-direction) and the flat sides of the square would be the locations where the flat butt of the arm ellipsoids would join.

But how do you cut away at the central disk to create the flat joins?  Answer:  Don't cut away, just build it that way in the first place.  Rather than fill in a disk using a disk point-picking method, fill in a series of triangles and rotate them to the appropriate angle.  Think of it this way--a hexagon can be broken into 6 triangles, a square into 4 triangles, and a larger triangle can be broken into 3 smaller triangles.  I used a triangle point picking method to create each "triangle sector" of the core.  In the end, I was left with the desired shape of either a big triangle (3 arms), a square (2 or 4 arms), or a hexagon (6 arms).

(Edit:  Forgot to mention that I also had to use a triangle interior detection algorithm when doing the triangle point picking, since the point picking actually puts the points in a quadrilateral and you have to determine which sector they are in.)

After that I just used the disk point picking method again to create each arm, multiplying the (x, y) coordinates for each point by the (a,b) dimensions of the arm ellipsoid.  Then I had to rotate the arm to align with the proper flat join on the core and translate it outward so it lined up perfectly.

I have some code in place to allow a single arm to have branches that split off and run for some length, but it was getting somewhat complicated to implement.  I might come back to it at some point, but for now I'm happy with just having singular, non-branching arms.

I recorded a couple videos of the new spirals.  My recording software can only capture at about 15 frames/second, so there's a bit of chop.

Videos:

3 Arm Spiral, 3000 Stars


4 Arm Spiral, 3000 Stars


6 Arm Spiral, 3000 Stars

May 13, 2011

Stars almost ready

Wow, the time just flies by.  I re-worked the elliptical galaxy algorithm to give them a better and more defined shape and have nearly finished implementing the Star class.  Next steps:

1) Create a visible elliptical galaxy full of stars.
2) Confirm that all star model values are within expected tolerances (i.e. my equations all give good numbers).
3) Create a visible spiral galaxy full of stars.
4) Create a bar spiral galaxy full of stars.
5) Create a uniform/irregular galaxy full of stars.
6) Enable multiple galaxies, with appropriate collision checking (will have to break out the math for this one...).
7) Implement some sort of depth culling so that stars farther away are not rendered but instead fall into a sort of galactic background.
8) Implement nebulae
9) Implement voids/clusters within galaxies
10) Develop planet/habitable object classes

I think that will keep me busy for a while!

February 13, 2011

More Galaxy/Universe Building

I realized that my cluster galaxy algorithm only lets me make roughly spherical galaxies--where's the fun in that?  I'm going to tweak it a bit to let me generate elliptical galaxies as well, following math here for a 2D ellipse, then creating a random (appropriately scaled) projection along the z-axis to add a 3rd dimension.  I'll probably have to collision check all the stars, so it might take a bit longer, but it's worth a shot.

Other than that, I've been hacking away at the universe creation routine.  This is the thing that makes the galaxy--and actually, it now makes multiple galaxies!  I figured that while a 10,000 star galaxy is unwieldy in 3D (issues with seeing into it, navigating around, etc.), 10 galaxies with 1,000 stars each could be quite manageable if they're separated enough.  I just need to figure out a good way to randomly arrange them--will work on that tomorrow if I have time after work.

Biggest annoyance today: the Java Vector3f class doesn't seem to have a rotate() method or anything like that.  Have to do it all "by hand."

February 4, 2011

Galaxies

I'm working on the galaxy generation algorithms right now.  I did a bunch of work on the cluster, multi-cluster, and spiral algorithms back in summer '09, but they (1) were in just 2-D and (2) took waaaay too much memory and possibly too much time to generate.  Since I shifted the game to a 3-D star map, the memory required to generate a 3-D cluster or spiral galaxy using the old '09 algorithm would be more than most computers could handle.

Briefly, the old algorithm created a 2-D grid of numbers and assigned them integer values that acted as probability weightings.  Two number generators spit out a sequence of gaussian-distributed random values that were taken as the X and Y coordinates of a star system.  Once a star was placed on the map, the grid cells immediately adjacent to it had their weightings changed so that no other star could be placed next to it and so that stars a little further out had a lower chance of being placed--essentially, reducing the clustering of stars a bit and preventing overlaps.  Spiral galaxies just did this with a particular shape and then applied a 2-D rotation matrix, with the rotation amount scaled by the distance of the stars from the galactic center (giving a nice spiral shape).

You can probably see how this would take up a lot of memory if generating a galaxy with lots of stars--the grid could become huge if you wanted to place 10,000 stars on the map.  Additionally, the random number generators, by the end, were trying to put new stars into an already populated map and would have to start over every time they landed on or near an occupied area.

My solution:  For the cluster galaxies, I'm using a series of concentric spherical "shells" that expand outward from the galactic center, one light year (LY) of gamespace at a time.  The number of stars on the surface of each shell is dictated by a gaussian distribution, cut off at six standard deviations (sd).  The value of the distribution at each LY is computed, as is the total area under the curve (integrated out to 6 sd's) and these two numbers, combined with the total number of stars to be placed, produce the number of stars in a given shell.  The star locations are then calculated by computing random points on the surface of a unit sphere and then extending them out to the appropriate radius.

The only collision checking I need to do is with the current shell of stars that a given star is being placed within, which is rarely more than 100 and decreases over time.  This still might take up more CPU time than my previous algorithm, but it looks like it will take up MUCH less memory.  I'm a little worried that the shells might appear too regular, but I think the relatively small number of points per shell surface area and their random locations should prevent this.  I'll try to get some visualizations up and running soon and may finally have pictures to post!

December 31, 2010

Hooray!

I've managed to get a colored square to appear on the screen, then make it change color by left-clicking the mouse.  Sounds pretty boring, doesn't it?

But this means that the following subsystems work:

3D rendering
Input manager
Game event handling
Basic GUI interface system

First the 3D engine and input manager (keyboard presses, mouse clicks, etc.) are loaded.  (Note:  I'm skipping many other subsystems that all come with the Java Monkey Engine [JME]--but these are the important ones).  Then the event manager is loaded and all basic game events are registered with it.  I currently have just one event for testing... :).  Next, the GUI state manager is loaded, which in turn creates the "Main Menu" state and the "Second Menu" states.  Main Menu contains a blue colored square on the screen while Second Menu contains a green square.  The Main Menu registers the action of left clicking the mouse with the input manager, then registers the GUI state manager as a listener for the click event.  The GUI state manager is told how to handle any messages coming into it and knows that the event should signal it to swap out the Main Menu for the Second Menu, thus changing the square from blue to green.

What this means is when the application is started, a black background appears with just a blue square in the lower left.  When the mouse is clicked, the "Main Menu" state sends a message to the input manager saying that a left-click occurred.  The input manager then sends a message to the game event manager, which the event manager then processes and sends to the GUI state manager.  The GUI state manager sees this message and swaps the Main Menu for the Second Menu, thus turning the blue square green.

Phew.  Sounds like a lot, but this loose coupling enables each system (input, events, GUI) to function independently and not worry about referencing and hooking into all the others.  It'll save a lot of time and effort when the game gets big and complex!

December 5, 2010

Kick-off

Hello everyone!  This blog has been created to keep any interested people updated on my progress in designing and coding the game Dark Matter.  This game is a turn-based strategy game set in space, similar in some ways to the Master of Orion, Galactic Civilizations, or Space Empires franchises.  I intend for the game's mechanics to differ somewhat from these mainstream games, though I'm not going to reveal exactly how until I've made much more progress coding.  Please also note that Dark Matter is a working title only and the real game's name will be different (since there is already an actual PC game named Dark Matter!).

I've been designing this game for several years now in an on-again off-again fashion and have come to the point where I need to get serious about coding it.  Designing on paper can only get me so far and the whole exercise starts to feel circular after the fourth revision of my tech tree...

I have a programming background, but its unfortunately in scientific/numerical methods and analysis--Matlab and C.  This means that I've had to teach myself object-oriented programming over the past few years.  I think I'm at a point where I can start coding Dark Matter now.  I'm going to write the game in Java using the Eclipse IDE and will probably use Java Monkey Engine 3 as an underlying engine for the game, with additional coding and game design help from Mike McShaffry's "Game Coding Complete, 3rd Edition."