Or… the journey through the x, y, and z axes through the lens of a computer screen.
If you want a performant game, written in Java, on the libGDX library, here are some of the handy tips and tricks that I have come across.
Whilst this is a bit of a hodge-podge of hints and tips, it is worthwhile to read through them all, even if the terms and nomenclature is not clear, it always good to have in the back of your mind that there are handy hints about a subject you are working on.
Note: this is part of a series of articles: See 3d Game Programming with Java and libGDX — Overview of Articles
Always think of performance
If there is only one thing that you do, it is this one.
Always think of performance. If you leave this too long, all of the small decisions that you have made without thinking of performance will add up, and it will be too late to fix them, and your game will run slow.
Table of contents
- Code Related
- libGDX related
- Model related
- Other considerations
Well, at least as much as you can, save time and CPU cycles. If you can work it out before hand, rather than on the fly, this will save cycles.
For example, if you are loading the same model, over and over again, and every time that you do, you compute the bounding box — do it once, and never again.
Don’t create new objects
Instead of creating new Objects, use the a single object within a class to be utilised. Object creation will trip you up, waste memory, and CPU cycles.
You are periodically checking your stats with VisualVM aren’t you?
Watch out for floating point mathematics
Floating point in computer terms are at best an approximation, and there are discrepancies between addition and multiplication (and division and subtraction for that matter). Looking at the code below
Running the above will give you the following output:
Adding 0.0 + 1.392 = 1.392
Adding 1.392 + 1.392 = 2.784
Adding 2.784 + 1.392 = 4.1759996
Adding 4.1759996 + 1.392 = 5.568
Adding 5.568 + 1.392 = 6.96
Adding 6.96 + 1.392 = 8.352
Adding 8.352 + 1.392 = 9.744
Adding 9.744 + 1.392 = 11.136001
Adding 11.136001 + 1.392 = 12.528001
Adding 12.528001 + 1.392 = 13.920001
Adding OFFSET 10 times in a loop = 13.920001Multiplying OFFSET by 10 = 13.92
As you can see — they are not the same, and can lead to a lot of problems — 13.920001 does not equal 13.92.
Some ways around this:
- Choose multiply or add and use it always — multiply is faster, but beware of loops and resetting counters.
- Round your floats to a number of decimal places (i.e. remove the least significant digits)
I chose the last option above — to 3 decimal places.
Throw some of the core Object Orientated tenets out the window
Information hiding— gone — allow public access to primitives and fields, the following is ‘old school’
However, this is much ‘better’
Why, you ask — simply because you save having a method call being pushed on to the stack — and when you are trying to hit 60fps consistenly, all of these little things will add up.
Always use an InputMultiplexer — you never know when (or if you will need it), but it will make it easier to always think about multiplexing input (i.e. from differents screens or UIs)
Watch for scaling and the models
Blender, by default, scales everything to metres, libGDX, by default, scales everything to centimetres.
This manifests itself, that when you load and display a model in libGDX that has been exported by blender, and converted by fbx-conv —you may not see it rendered on the screen as your camera is actually ‘inside’ the model (and back face culling is active)
Invert the textures when you fbx-conv
When running ‘fbx-conv’ always set the ‘-f’ flag when exporting from blender, or your image textures will be upside down, as an example:
fbx-conv -v -f -o G3DB medium-rhombic.fbx medium-rhombic.g3db
Multiple models/image textures
If you are using the same model, just with different textures, load up the model once, and then change the image texture on instantiation. (don’t forget about transparency in your images if you have one…
// create a new material with an image texturethis.originalMaterial =
// you will need this line if you have any alpha
(i.e. transparency) in the imagethis.originalMaterial.set(
// clear the material which was loaded with the model
this.materials.get(0).clear();// set the material on the model
Load time is better than wait time
People will forgive loading times as you get everything up and running, however, games that run at below 60fps as things are happening in the background will not be tolerated. Load everything up-front to make your game snappy.
Plan your screens up-front and have a standard naming convention. Whilst this may seem obvious, the complexity comes in when you need to add in a lot of screens over time, and how you hook them in.