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).