November 15, 2012

Design Patterns in Game Programming (II): Strategy

Here are some use cases for the strategy design pattern in game programming, all of them leading to a more dynamic game setup, making configuration easier and decoupling the game core from implementation details of various algorithms.

Paint Strategy
In Java2d define an interface to render images with two implementations:
  • simply call Graphics#drawImage()
  • use java.awt.image.BufferStrategy
Win Rule
A game can be played with different rules to actually win the game, like:
  • LAST_MAN - the last survior wins
  • HIGHSCORE - the highest score wins
  • TIMESPAN - highest score wins after playing for a fixed time
  • INFINITY - play forever, useful for development and testing
The game has one current win rule object which is called on a regular basis to find out whether the game should be finished. In case the win rule is fullfilled, a list of the winners is returned.

Path Finding
Call the path finder only through an PathFinder interface to be able to easily swap between different algorithm at runtime like A* or Dijkstra.

Field Of View
Call the field of view calculation through an interface, thus making it easy to change the algorithm at runtime according to defined game performance options or machine specs. Add mock implementations to support testing.

Collision Checking
Isolate collision check algorithms in concrete strategy implementations.

Navigation
Moving a sprite from point a to point b is possible in different ways:
  • straight
  • by following a tile path
  • by following calculated spline nodes

Some Thoughts about (Object Oriented) Game Programming

Some of my favorite best practices for object oriented programming. Actually, they also apply to programming in general, and no matter if it is business software or a game.

Understandability, Maintainability, Readability
This is the most important practice of all, to avoid:
  • cryptic, chaotic, over engineered and under engineered code
  • bad formatting, no formatting rules, weired naming, thousands of lines per method
  • undocumented code, useless comments, wrong comments
  • code blocks without empty lines to let the reader easily grasp its meaning
  • methods broken into smaller parts and thus hurting understandibility
  • names for variables, methods, classes, packages which are not self-documenting
  • names being too short or too long
  • methods hard to use because of too many parameters
  • errors and exceptions not treated properly, not logged, sent into nirvana
  • keeping users totally uninformed about errors, showing useless information ("an error occured") or a pile of technical messages
  • a cumbersome environment with slow, annoying and error prone development cycles

Knowing all kinds of fancy programming techniques, patterns and the like is not enough. One should always think of how an application will behave when being run in an production environment for years and years - possibly long after the creators have moved on.
What kind of problems might occur ? Will they be easy to track down ? Is the given architecture and environment comfortable to use for enhancements, or will new developers just think wtf and create arbitrary bypasses and thus worsen the situation ?

Use simple solutions whenever possible and complex ones if appropriate.
Follow common sense.

Data Encapsulation
Hide your data from the others. Otherwise harm will be done - sooner or lateer.
Do not use the public scope for class members. And do not mechanically add getters and setters for all members, as that breaks encapsulation as well.
Do not store everything as member variable, just for the case that it might be useful some day. Favor method parameters instead and pass data around.

Static is toxic
There are rare use cases for static methods and class members, exceptions are constants in Java or, for example, a collection of stateless mathematical functions.
Stateful methods need to store information somewhere. If they are static, they can only access static members, which in consequence leads either to shared states or to a singleton class design. Both options are seldom practicable and useful.

Static methods are not overridable and as such do not allow to change implementations any time later, neither for the whole code base nor for selected modules. Keeping software flexible and open for changes is very valuable. This is also essential for good frameworks and the infamous game engine.

Remember that any variable marked as public static is nothing but a global variable.
Keep in mind what it means when multiple objects of a class are creatable and some of the class members are static. All objects share those members, they are no longer private to each object, no longer encapsulated into each object. A good way to introduce side effects.

Multithreaded programming will become more and more important in the future. To benefit from multiple threads and/or cores, static variables are to avoided as well. If not, hard-to-find bugs are the probable consequence.

Anybody who is starting to learn programming with an object oriented environment like Java should never use statics. Later on, with more experience, one can decide on when to make exceptions to this rule. Otherwise, you won't learn how to set up, handle and maintain object relations and understand the design of existing libraries.

Static is an exception to the default way, you need to add a keyword to your code. There should always be a good reason to leave the main path.

Modules and Dependencies
Split up the code into classes, packages and modules. Limit responsibilities and tasks of classes and methods (Separation of concerns).
Keep relations between classes and packages as low as possible. Stay away from cyclic dependencies.
Use interfaces for communicating between layers, packages or modules. Do not create dependencies across packages into concrete implementations.
Keep interfaces lean, typically do not add lifecycle methods for creating and setting up objects, as those are mostly implementation dependent and are only called at places where concrete classes are dealed with anyway.

OOP != Inheritance
OOP is much more than class inheritance. Setting up an inheritance hierarchy of seven levels is not the way to go. Favor object composition which can be dynamic at runtime as opposed to static compile time inheritance.
Lego brick programming.

Frameworks, Libraries, Game Engines
This is the ultimate challenge. To create something useful for a broad audience, without knowing each and every use case.
Good frameworks give support for use cases the users choose while at the same time do not force any unwanted features and clutter upon them. Features should be selectable which is only possible with a good dependency management (see above) of the whole work.
Classes must be accessible and extendable (no final modifier, no package scope) without breaking encapsulation by making each and every member protected.
Again, object composition is to be preferred as opposed to force inheritance on library users and only give a limited set of overwritable methods (template method pattern).
All of this is very difficult and takes a lot of experience to achieve.
 
Documentation
Eh, what ? Yes, the part we all love the most. Keep in mind that there is never more than one person (at most) who thinks your code is self-documenting, clear as it can be and just ingenious...

What else
A frequent use of the instanceof operator is an indicator of incomplete class design and thus preventing to benefit from polymorphism.

October 28, 2012

Design Patterns in Game Programming (I): Observer / MVC

Design patterns are well established in business software, but there is no reason to not benefit from using some in game programming. After all, programming is programming.

Design patterns are often either loved or hated but neither position should have its place in professional software development. You shouldn't work with a pattern check list at hand and integrate them without reason. And if you do not like patterns, there are most likely more of them hidden in your very own programming work that you are aware of.
They are also a means of communication and common language and knowledge between developers.

Patterns are not restricted to programming, but can be found in many other domains. Human behaviour often follows established patterns as do created novels, movies and songs.

 
The observer is probably - after the infamous singleton - the best known design pattern in software development.

Here is a simple but useful example.
Let's design a game which has the following objects:
  • a scene to represent the whole game world full of acting characters and the environment
  • several views for the visual part, like the main game view, HUD view for statistics, a debug view 
  • controller for the game logic
Whenever the controller decides to modify the world, like for instance spawn another evil monster or remove it again after being killed by the player, the changes must be reflected by all views.
First, the controller modifies the scene. Then, we make the views passively observe the game world.

public interface IPuppetLifecycleListener {
    void onPuppetAdded(Puppet puppet);
    void onPuppetRemoved(Puppet puppet);
}


Each observer implements this interface and gets called whenever characters are added to or removed from the game scene.
For example, we have two views: a main game view and an additional small radar sub view to let the player see at a glimpse where all the enemies are hiding.

public class TileMapView implements IPuppetLifecycleListener {
    private List spritePuppets;
   
    @Override
    public void onPuppetAdded(Puppet puppet) {       
       SpritePuppet viewPuppet = 

          puppetHouse.createViewPuppet(puppet);
       ...
    }
      
   
    @Override
    public void onPuppetMoved(Puppet puppet) {

       ...
    }

public class OverlayHudView implements IPuppetLifecycleListener {
    private ListViewPuppetCast radarPuppets;
   
    @Override
    public void onPuppetAdded(Puppet puppet) {       
        if (puppet.getActorClass().equals(ActorClasses.BIONIC)) {
            rivalCount++;
            RadarPuppet radarPuppet = new RadarPuppet(puppet);
            radarPuppets.addPuppet(radarPuppet);
        }
    }


    @Override
    public void onPuppetMoved(Puppet puppet) {

       ...
    }
    ....
}


Both view types have their own kinds of visual puppets. For the tile map are sprites created, for the radar view small filled circles are drawn.

The publisher of any puppet event is the game scene which holds a list of observers:

public class GameScene {
    private PuppetCast puppets;

    private List<IPuppetLifecycleListener > puppetLifecycleListeners;
 

    public GameScene () {          
        puppets = new PuppetCast();
        puppetLifecycleListeners = new ArrayList<>();
    }

 

    public void addPuppetLifecycleListener(IPuppetLifecycleListener listener) {
         puppetLifecycleListeners.add(listener);
    }

 

    public Puppet addPuppet(Puppet puppet) {
        puppets.add(puppet);

        
        for (int i = 0; i < puppetLifecycleListeners.size(); i++) {
            IPuppetLifecycleListener listener = puppetLifecycleListeners.get(i);
            listener.onPuppetAdded(puppet);    

        } 
     ....
}

Very simple and very useful. Actually, this is is a model-view-controller implementation for games.
Benefits are:
  • observers can take it easy and only get active when called
  • on each event individual additional actions can happen like playing animations or sounds
  • dependencies are reduced, no global object sets are referenced throughout the code base
  • the internal representation of the game scene is hidden from the views
  • only one clearly defined place to handle each external event
Here, no dependency is pointing from the scene to the views. The scene does not know - and does not need to know - whoever cares about its puppet events. The scene could even run without any views at all in a distributed multiplayer environment.
Thus, the complete scene package can be independent of the view package. Note, that to accomplish that, all observer interfaces are placed into the scene package and not into the view package.

The same technique can be applied for the other way round, for handling UI events created in views:
  • views allow observers to register for UI events
  • view interfaces are placed into the view package and are implemented by controller classes
  • thus, views do not need dependencies to their controllers

Observers can be added once at game start or during level changes.

Class sketch:


MVC roles:
  • model: ClientScene, Puppet, PuppetListener
  • controller: SceneController
  • view: SceneView, TileMapView, SpritePuppet, OverlayHudView, RadarPuppet

July 4, 2012

Java & Candy



Eye candy, to be precise.
Who said that all Java games look cheap and amateurish ? With the help of OpenGL you have all possibilities of modern graphics hardware at your hands.

So I decided to polish Biodrone Battle a bit by adding dynamic particle effects for explosions and other game events. The game uses LibGDX as OpenGL frontend. Setting up particles is pretty easy and for tweaking the appearance there is a nice graphical editor available.

Each particle effect is made from one or more particle emitters, defined in plain text files. Additionally, an image file (a small filled circle, e.g.) is named which is used to actually draw each particle. If no image path is specified, just place the image into the same folder as the particle definitions.

First, you load the definitions:

FileHandle particleFolder = Gdx.files.classpath("resource");
FileHandle smokeParticleFile = Gdx.files.classpath("resource/smoke.particles");

ParticleEffect effect = new ParticleEffect();
effect.load(smokeParticleFile, particleFolder);

To render the particles, you need to start once, then position, update and draw the emitters:

effect.start();
...
effect.setPosition(x, y);
effect.draw(batch, ds);

Updating is done in each game frame by supplying a valid SpriteBatch and a time delta (in seconds). Naturally, you can also reposition the emitters for getting moved particles. To do so, the attached property must have been enabled in the particle definition file.
Furthermore, particle emitters can run either once or continously. This is decided by the continuous property. To check whether a one-time emitter is done, call isComplete().

Loading and parsing of the definitions files does not need to be done each and every time again during the game loop. A ParticleEffect can act as template to create cloned objects from which are then actually drawn:

ParticleEffect effectTemplate = ...
ParticleEffect effect = new ParticleEffect(effectTemplate);

When cleaning up, only the templates need to be disposed because the internal textures are shared between all clones.



Fun stuff :)

May 10, 2012

Client or Server ?

The server HotSpot VM does more or better optimizations, or both.
So, as game programming is often about maximizing performance, using the server VM would be the first choice, right ?

I did a rough comparision:
- a quadcore CPU, Windows 7, Java 7
- calling yield() from the logic game loop and no throttling whatsoever lets the framerate go through the roof

As result,
the server VM manages ~25.000 fps,
the client VM ~15.000 fps.

So, better performance at no cost ?

Let's look how the situation is on a weaker machine, or let's simply run the game on only one CPU core.
Now the tradeoff is clearly visible: the game stutters during the early HotSpot compilation phase, whereas the poor single core is easily able to manage the code compiled by the client VM - while the game is still fast enough overall and shows no stutter.

Single core, server VM: ~19.000 fps
Single core, client VM: ~11.000 fps

Now, what's the conclusion, always use the client VM for gaming ? No, as always, it depends.
But definitely test on weaker hardware as well :)

April 18, 2012

And There Was Light


Lighting with Java & OpenGL

I started game programming with Java2D. While it was enough and easy to use, adding realistic lighting for the field of view, is nearly impossible. So, the Java2D view renderer can only do it in a very primitive way: tiles out of view are drawn a bit darker by adjusting the alpha composite for the drawImage() call.

tile based field-of-view

A nice and easy to set up solution (that means no OpenGL programming knowledge is required) for OpenGL and LibGdx is box2dlights.

field-of-view with box2dlights

Here are the main steps outlined for adding one scene light as shown above:
// light camera 
pixelPerMeter = 64f;
boxLightCamera = new OrthographicCamera();
float boxLightViewportWidth = spriteCamera.viewportWidth / pixelPerMeter; 
float boxLightViewportHeight = spriteCamera.viewportHeight / pixelPerMeter; 
boxLightCamera.setToOrtho(true, boxLightViewportWidth, boxLightViewportHeight); 
boxLightCamera.update(true);

Box2dlights uses the physics simulation Box2D (in its native version as integrated with LibGdx), and Box2D prefers meters as unit of measure instead of pixels. With the rest of the game using pixels, a new camera is needed for mapping pixels to meters. A simple way to do this is to define 1 tile as 1 meter, and thus 1 meter equals 64 pixels.

// world and light setup
 world = new World(new Vector2(), true); 

RayHandler.useDiffuseLight(true);
rayHandler = new RayHandler(world);
rayHandler.setCombinedMatrix(boxLightCamera.combined);
rayHandler.setAmbientLight(ambientLight);

spriteLight = new PointLight(rayHandler, 128, lightColor, 10, 0, 0);

A new yet empty Box2D world (no gravity defined, we only care about light rays) is created.
RayHandler is the main light controller. Setting the diffuse flag is important to prevent an over-illuminated player sprite.
With ambient light, tiles out of view still get some low amount of light.
Finally, a light is created that will be later continually moved to the player sprite position and thus allowing a dynamic field-of-view.
128 rays make up a nice smooth light, 10 meters is the light range. Furthermore, a light color is defined.

As box2d is used to find out about light obstacles like walls from which shadows are created and light is blocked, the tile map must be converted into box2d world objects. To keep it Simply, for each tile one world body is created. This could be theoretically optimized by combining rows and columns of neighbour tiles to only one body, but so far I did not see any performance impact.
protected void createWorldScenery(ITileMap tileMap) {
 // build plan for wall bodies
 float halfBody = tileSize / pixelPerMeter / 2;

 PolygonShape tileShape = new PolygonShape();
 tileShape.setAsBox(0.5f, 0.5f);

 BodyDef tileBodyDef = new BodyDef();
 tileBodyDef.type = BodyType.StaticBody;

 FixtureDef fixtureDef = new FixtureDef();
 fixtureDef.shape = tileShape;
 fixtureDef.filter.groupIndex = 0;

 // create box2d bodies for all wall tiles
 for (int row = 0; row < tileMap.getRows(); row++) {
  for (int col = 0; col < tileMap.getColumns(); col++) {
   int tileClass = tileMap.getTileClassMask(col, row);
   if (Tools.anyBitSet(tileClass, obstacleMask)) {
    float bodyX = col + halfBody;
    float bodyY = row + halfBody;
    tileBodyDef.position.set(bodyX, bodyY);
    Body tileBody = world.createBody(tileBodyDef);
    tileBody.createFixture(fixtureDef);
   }
  }
 }

 tileShape.dispose();
}

Disposing box2d objects must not be forgotten. Tile classes are bit fields for identifying light blocking wall tiles.

For rendering each frame, first tiles and sprites are drawn with a separate camera, then the moving light is updated to match the player's center position:
puppetLight.setPosition(clientCenterX, clientCenterY);

Afterwards, the light camera gets updated following the scrolling tile map:
boxLightCamera.position.set(camX, camY, 0);
boxLightCamera.update();

And finally, the RayHandler does all the magic:
rayHandler.setCombinedMatrix(boxLightCamera.combined, 
boxLightCamera.position.x, boxLightCamera.position.y,
boxLightCamera.viewportWidth * boxLightCamera.zoom, 
boxLightCamera.viewportHeight * boxLightCamera.zoom);

rayHandler.updateAndRender();

That's it. Without one line of OpenGL code.

For even more fun, it is possible to add and remove lights any time, so I illuminated fired bullets in different colors. For bullets, computing power can be saved by reducing the number of rays to 16.
Additionally, a nice effect is to continuously dim bullets instead of switching them off immediately when they hit a wall. Just set new light colors while lowering the alpha composite until it reaches a value of 0.

The game uses OpenGL 2.0, it runs with OpenGL 1.1 as well, but the lighting impression is totally different, lights are much brighter, so to switch between both version, some adjustment would be necessary.

What about the performance impact ?

~ 2500 fps for rendering the scrolling tile map without lights.
~ 1000 fps for rendering with enabled lights.

While a bit of a performance drop, 1000 fps are still way beyond of what is required, so some more lights could be added, I guess :)

April 12, 2012

From Java2D to OpenGL

I started game programming with Java using the default 2D API.
It is easy to use and fast enough for drawing images, which is basically all you need to create a tile based game with some animated sprites.
But the support for creating game eye candy like color effects, lighting, shadows or particles is quite limited. While you have access to every single image pixel, the drawback is a more or less heavy performance loss, emphasis on more, most probably.

Luckily you can use OpenGL with Java.
There are several bindings and frameworks available. I decided to use LibGdx with LWJGL as backend. LibGdx has a good reputation performance wise, and is furthermore based on classes and examples presented in the book "Beginning Android Games" which is also a good and gentle introduction into OpenGL. Then, there is an awesome lighting library available: Box2dLight. That leads to the most important advantage:
Abstraction from OpenGL, which is very low-level, static and stateful. Enough said.

Eventually, with little knowledge about OpenGL, I was able to implement a new renderer based on LibGdx in a few days. Some pitfalls were to overcome, though:

Multithreading is problematic if possible at all. Better do anything OpenGL related in one and only one thread. Loading images, drawing, creating lights, disposing resources. While it shall be possible to activate the OpenGL context in multiple threads, it did not work for me.

The default coordinate system of LibGdx has it origin in the left bottom, which did fit not with the existing game relying on the upper left as the origin. But with configuring a camera that's very easy to overcome, as follows:

OrthographicCamera cam = new OrthographicCamera();
cam.setToOrtho(true);

This y-down camera is then used for drawing sprites and tiles. Additionally, all textures must be flipped vertically. Best to use a TextureRegion for that.

Even if you are using an object abstraction layer on top of OpenGL, you have to keep in mind, that after all, every operation invoked on a Java object ends up in OpenGL which is, well, static and stateful. Thus, there is a lot of dependency and interaction going on under the hood. You can not think and design like it was a real object-oriented system even if certain classes seem to encapsulate OpenGL.

Be sure to adjust the viewport dimension with the camera. I spend some time wondering why I got weired mouse click coordinates. In the end it turned out that the camera was 64 pixels lower than the viewport due a copy-paste-action from my Java2D renderer.You get what you deserve, I guess. It was not visible, OpenGL did a good job in stretching.

The basic and most important classes are: 
  • OrthographicCamera
  • Texture
  • TextureRegion
  • SpriteBatch
  • BitmapFont
SpriteBatch is for drawing all kinds of images, animated sprites, tiles, HUD items and text.

Unfortunately, LibGdx forces you into a predefined application skeleton which I don't need and want to use. That means, access to several configuration classes is restricted, so that I had to put some of my own game classes into a gdx package. It's good to have a standard easy-to-use setup, but it should be an option and not block different valid approaches. But that's only a minor issue.
Good progress so far :)

April 11, 2012

Java Games and Performance

Some basic performance considerations for real-time Java:

Choose collection classes wisely.
What are the most frequently called operations ? Collections classes can give very different performance signatures when it comes to
- iterating all items
- index based direct access
- key based access
- insertion, appending or removing items
- keep items ordered
- concurrent access, whether algorithmic or by synchronization
- scaling / extensions of memory

Some hints:
- FastMap supports ordered maps
- Colt's maps can store primitives
- LinkedList is not that good for index access
- ArrayList isn't the best for finding concrete items
- Ever looked what ArrayList does when you remove an item (except for the last one) ?
- Choose the right initial capacity and growth behaviour
- For fast get/set access of hash maps, check out Trove's maps or just use Java's native HashMap
- Take care of collection classes which create additional objects for each added item like LinkedList and ConcurrentLinkedQueue
- Array based Bags are good and fast for adding as well as removing items when no item order is required
- The various cuckoo hash maps of LibGdx are said to be very fast and worth checking out
- After all, only profiling can show realtime behaviour - and can result in different conclusions for different platforms, machines, CPUs, CPU core counts, etc.

Do you know what the following code does ?
List names = ..
for (String name : names) {
...
}

Certainly you do, but do you also know what happens under the hood ?
These enhanced loops work with implicit created iterator objects. So if you use them in your main game loop, this ends up in creation of tons of avoidable object garbage.
Better choices are ArrayList with index access or maps like FastMap THashMap which offer callback loops.

What about this:
String guitarGod = "Jimi" + " " + " Hendrix";
Well, the coding makes no sense, the meaning very well does, but unfortunately Java creates StringBuilder objects to concatenate such strings. Again, for frequently called code fragments...
Better set up your own controllable StringBuilder.

When dealing with images, be sure to to create compatible images, for example by using
GraphicsConfiguration#createCompatibleImage(...) and
GraphicsConfiguration#createCompatibleVolatileImage(...)

That ensures compatible data and color models to prevent from implicit slow conversion while rendering images.

For hardware accelerated images use VolatileImage. Take care if you intend to fiddle with image pixels by yourself. Prior managed images might very well become unmanaged and thus lose any hardware acceleration (see VolatileBufferedToolkitImage Strategies).

Keep synchronization blocks short and be sure you know what you when it comes to multithreading ;)

Add delay or conditions to certain operation to lower the invocation frequency and save CPU cycles.
For example:
- calculating a field-of-view only needs to be updated if an actor was moved or the environment has changed
- sending postion updates from server to client might only be required for actors which have actually been moved
- don't call your genius-pixel-exact collision detection when the cool rough collection detector said: relax boy, too far away anyway
- write algorithms that are interruptable and can continue later on for spreading their execution over multiple game frames
But beware that processing heavy code kicking in only from time to time can cause cpu spikes and an unsteady game experience. Thus, the right balance must be found.

Using prerendered text images instead of drawing true type antialiased fonts each time letter by letter might relax your machine.

Avoid object creation from auto boxing.

Think about object caching for selected classes (not in general).

A profiler can easily reveal performance hot spots you have never thought of and keep you from tinkering the wrong code fragments.

Be careful with micro benchmarks:
  • let the JVM optimize during an appropriate warm-up period before measuring
  • prevent from dead code optimizations
  • compare results of client and server VMs
  • cache hits or misses influence benchmark results

Game Programming with Java

When you tell someone that you're programming a computer game with Java, the first response might very well be: really, is it fast enough ?

Short answer is: sure it is.
The more detailed answer is simply, as always: it depends.
It depends on the type of game, on the architecture and programming, on CPU and naturally, very important, for polished graphics, on the graphics card.
For casual games, for 2D games, it is.
Sadly, established myths are hard to overcome, and one is the „Java-is-slow“ myth.

In the old days, probably the Assembler guys were thinking similiar of C++, before it became the game development standard. And why not use the standard ? Well, first of all, when I started, Java was my job language, and second, C++, well... let's say I find not that attracting :)

Here is an older (nicer shading soon to come) of my current game under development. It is a 2D top-down-shooter inspired by games from ancient ages...



The scrolling view is made of tiles, each 64x64 pixels. Visible are 16x12 tiles, thus 192 tiles need to be rendered for each view frame. The game has an event driven multithreaded client/server architecture, runnable either via TCP or as standalone game sending in-memory events.

With pure Java2D as rendering module, on a machine with an Intel Q6600 at 2.4GHz and a GeForce GTX 460, after loosing the brakes, I get a framerate of ~1400 fps.
Thus, Java2D draws 16*12*1400 = 268.800 images each second.
Considering that the average monitor only has a refresh rate of 60 fps, that is pretty much fast enough.

The game server, the game's logic core responsible for actor movement, collision detection, game AI, path finding and field-of-view calculation reaches ~ 20.000 fps, where the client side (without rendering) shows up to ~140.000 fps.
Again, just to illustrate possibilites.

So far, this was Java 7 with Java2D for rendering (basically drawing everything with VolatileImage).
Some external libraries and tools are used to keep from reinventing too much wheels:
- collection classes from Trove, Javolution and Colt
- SoundSystem for 3D sounds
- JGoodies FormLayout for the Swing based game lobby
- JInput for game controller support
- Tiled map editor

Later additions were LibGDX, Box2DLights and LWJGL for nicer, more polished graphics based on OpenGL.

So, is it all nice, easy, fun and beautiful ? Certainly not, but where is it like that ?

:)