Best Practices For jME3 Developers

A collection of recommendations and expert tips. Feel free to add your own!

If you are a beginner, you should first read some articles about game development. We cannot cover all general tips here.

Requirements Gathering

As a quick overview, answer yourself the following questions:

Planning Development Milestones

  1. Pre-Alpha
    1. Lay out the overall application flow using mock-ups or stock art. E.g. switching between intro screen / options screen / game screen.
    2. Get one typical level working. E.g. if it's a "Jump'n'Run", jumping and running must work before you can call it an Alpha.
  2. Alpha
    1. Run internal tests, debug, optimize (issue tracker).
    2. Replace all mock-ups with first drafts of real media and levels.
    3. Feature Freeze: Avoid a bottomless pit of side effects causing new issues.
  3. Beta
    1. Have external people review and "beta test" it (issue tracker).
    2. Even out the kinks in the code – don't add any more new features.
    3. Fill in all final content.
  4. Gamma, Delta = Release Candidates
    1. Last chance to find a horrible bug.
  5. Omega = Final Release

How you actually name or number these milestones is up to you. People use the words "milestone", Greek letters, version numbers, or combinations thereof.

Every milestone is made up of a development phase and a test phase. Here are some best practices:

Development Phase

Where to Start?

You have a list of features that you want in game, but which one do you implement first? You will keep adding features to a project that grows more and more complex, how can you minimize the amount of rewriting required?

  1. Start with implementing the most complex game feature first – the one that imposes most constraints on the structure of your project (for instance, networking.)
  2. Make sure the game's high-level frame (screen switching, networking, physics, loading/saving) is sound and solid before you implement low-level details of gameplay.
  3. Only add one larger feature at a time. If there are complex interactions (such as "networking + physics"), start with a small test case ("one cube") and work your way up, don't start with a whole scene.
  4. Test for side-effects on existing code before you add the next feature.

Acknowledge whether you want a feature because it is necessary for gameplay, or simply because "everyone else has it". Successful high-performance games are the ones where someone made smart decisions what to keep and what to drop.

Extend SimpleApplication

Typically, developers extend a custom class off of jME3's com.jme3.app.SimpleApplication (or even com.jme3.app.Application). For a racing game you would create a different base game class than for a space game or a shooter.

  1. Create a generic game class for your custom game:
    1. Create a jME3-based project with all necessary JARs on the classpath.
    2. Create a class in this package that extends SimpleApplication, name it something like my.company.MyBaseGame.java.
    3. Implement all generic features that the game type needs in the MyBaseGame class. For example methods for loading and saving scenes, physics, networking and multi-player logon screen, switching to settings screen, etc.
    4. Include generic assets (company logo, reusable GUI elements in your company style, etc) in the MyBaseGame's assets directory.
  2. Create your actual game, e.g. a shooter:
    1. Create another jME3-based project, and a new package for the game itself, e.g. my.company.zombieshooter.MyGame.java.
    2. Add MyBaseGame.jar to the classpath of MyGame.java.
    3. Make MyGame.java's main class extend MyBaseGame.
    4. The specific assets (scenes, models) of this game go into MyGame's own assets folder.
    5. Now implement this game's mechanics and levels – without having to worry about logon&settings screens and all the other features that you already dealt with in MyBaseGame.

Controls and AppStates -- The Smart Way to Implement Game Logic

As your jME3-based application grows more advanced, you may find yourself putting more and more tests in the simpleUpdate() loop, and passing around lots of object references. Don't implement game behaviour by copying and pasting boilerplate code! It is a best practice to move game behaviour into classes of their own. In jME3 these classes are Controls and AppStates.

Both classes automatically hook into the main update loop. Instead of remote controlling game entities via simpleUpdate(), you define the desired behaviour in the update methods of custom Controls and AppStates. You then add Controls to Spatials, and AppStates to the application, and jME3 will automatically trigger the update methods. This cleans up your simpleUpdate() loop code considerably.

Learn more about Custom Controls and Application States.

Optimize Application Performance

Use an Assets Folder

Put your assets into subfolders of your project's assets directory. This is the default path where the assetManager looks for files.

jMonkeyProjects/Pong/assets/    # Store assets here
jMonkeyProjects/Pong/build/     # jMP generates built classes here *
jMonkeyProjects/Pong/build.xml  # Customize Ant build script here
jMonkeyProjects/Pong/nbproject/ # jMP stores default build.xml and meta data *
jMonkeyProjects/Pong/dist/      # jMP generates executables here *
jMonkeyProjects/Pong/src/       # Store Java sources here
jMonkeyProjects/Pong/test/      # Store test classes here (optional)
(*) managed by jMonkeyPlatform, don't edit

Here is an example of a commonly used directory structure:

jMonkeyProjects/Pong/assets/Interface/ # .font, .jpg, .png, .xml
jMonkeyProjects/Pong/assets/MatDefs/   # .j3md
jMonkeyProjects/Pong/assets/Materials/ # .j3m
jMonkeyProjects/Pong/assets/Models/    # .j3o
jMonkeyProjects/Pong/assets/Scenes/    # .j3o
jMonkeyProjects/Pong/assets/Shaders/   # .vert, .frag
jMonkeyProjects/Pong/assets/Sounds/    # .ogg, .wav
jMonkeyProjects/Pong/assets/Textures/  # .mesh.xml+.material, .mtl+.obj, .jpg, .png

See also: Asset Packs

Don't Mess With Geometric State

Here are some tips especially for users who already know jME2. Automatic handling of the Geometric State has improved in jME3, and it is now a best practice to not mess with it.

Maintain Internal Documentation

It's unlikely you will be willing to fully document every class you write. You should at minimum javadoc all crucial methods/parameters in a meaningful way.

Use Version Control

Whether you work in a team or alone, keeping a version controlled repository of your code will help you roll-back buggy changes or recover that code that you or someone deleted and now is needed.

Convert Models to .j3o Format

From the beta on, convert all Ogre mesh models and scenes to the binary .j3o format. Use the jMonkeyPlatform for the conversion, and save the .j3o files into the Models directory.

Debugging and Test Phase

Test

Unit Tests (Java Assertions) have a different status in 3D graphics development than in other types of software. You cannot write any assertions that automatically test whether the rendered image looks correct, or whether interactions are intuitive. Still you should create simple test cases for separate game features such as loaders, content generators, effects. Run them now and then to see whether they still work as intended – or whether they are affected by side effects. Keep the test classes in a test directory in the project, but don't include them in the distribution.

Quality Assurance (QA) means maintaining a clear list of steps that must always work, and checking them. There can be bugs in software, but tasks such as installing and de-installing, saving and loading, starting/pausing/quitting the game, must work, no excuse. After every milestone, you go through the list again, on every supported operating system, and systematically look for regressions or bugs.

Alpha and Beta Testing means that you ask someone to try to install and run your game. It should be a real user situation, where they are left to figure it out by themselves (you only can include the usual read-me and help docs). Provide the testers with an easy method to report back descriptions of their problems, e.g. why they gave up. Evaluate whether these problems are exceptions or must be fixed for the game to be playable.

Debug

A Java Debugger is included in the jMonkeyPlatform. It allows you to set a break point in your code near the point where an exception happens. Then you step through the execution line by line and watch object and variable states to detect where the bug starts.

Use the Logger to print status messages during the development and debugging phase, instead of System.out.println().

Enhance Performance

A Java Profiler can be added to the jMonkeyPlatform via Tools → Plugins → Available. The profiler presents statistics on the lifecycle of methods and objects. Performance problems may be caused by just a few methods that take long, or are called too often. If object creation and garbage collection counts keep increasing, you are looking at a memory leak.

Release Phase

Pre-Release To-Do List

Distributable Executable

The SDK can help you with deployment. Do you release your game as WebStart, Desktop JAR, or Applet? Each has its pros and cons.

DistributionProsCons
Desktop Launcher
(.EXE, .app, .jar+.sh)
This is the standard way of distributing desktop applications. The jMonkeyPlatform can be configured to automatically create zipped launchers for each operating system.You need to offer three separate, platform-dependent downloads.
Desktop Application
(.JAR)
Platform independent desktop application.User must have Java configured to run JARs when they are opened; or user must know how to run JARs from command line; or you must provide a custom JAR wrapper.
Web Start
(.JNLP)
The user accesses a URL, saves the game as one executable file. Easy process, no installer required. You can allow the game to be played offline.Users need network connection to install the game. Downloading bigger games takes a while as opposed to running them from a CD.
Browser Applet
(.HTML+.JAR)
Easy to access and play game via most web browsers. Userfriendly solution for quick small games.Game only runs in the browser. Game or settings cannot be saved to disk. Some restrictions in default camera navigation (jME cannot capture mouse.)

Which ever method you choose, a Java-Application works on the three main operating systems: Windows, Mac OS, Linux.

view online version