So I decided to create a guide outlining the process I found best for creating an Eclipse workspace for various parts of a jME3 game. While developing my own game, I came across several things that were either poorly described in other guides or omitted completely. Not only that, but I needed to incorporate some JNI for both desktop/Android applications for some more advanced voxel rendering for which Java just couldn’t pull through, so I decided to throw my project structure in there as well.
Seeing as how I can’t create a wiki page without the proper permissions, the guide itself is formatted rather flat; when/if the wiki page is created for this guide, I will go through and re-format it for the wiki’s markdown and glam it up a bit. Hopefully it’s not too unreadable.
This was the product of about 6 hours of straight typing, so naturally any corrections or feedback would be much appreciated. I’m sure I made some mistakes seeing as how it was fueled by about 5 or so cups of coffee.
For many, the Netbeans-powered IDE provided by the JME SDK is suitable for their project; however, many users are comfortable with other IDEs. Arguably, Eclipse is one of the leading Java IDEs available.This guide will show you how to effectively set up your Eclipse environment for not only a basic JME3 project, but an Android project, an assets project, and a JNI project (including the ability to build for Android through NDK).
While you do not have to create a project of each type to use Eclipse and this guide, note that the Android and JNI projects do require having a base Eclipse project to be applicable using this guide.
The code samples provided in this guide should work for any IDE, but setting up/configuring your IDE to do what Eclipse does in this particular guide may require some creative workarounds.
Setting up JME3
I will assume you have already downloaded (and built, if necessary) the JME3 binaries. If not, either download the latest SDK release (http://hub.jmonkeyengine.org/downloads/), nightly (recommended for new users) (http://nightly.jmonkeyengine.org/), or take a quick detour over to this guide (https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:build_from_sources) to build from source (recommended for advanced users).
Note that one directory you should have on hand (or know where to find) is the location of the resulting library (JAR) files.
For the various methods of obtaining the libraries (as described above), the path is usually in the following places:
- SDK: [SDK Install Dir]/jmonkeyplatform/libs
- Nightly: /libs
- Source: [SDK Dir]/sdk/build/cluster/libs
NOTE: Throughout the course of this guide, do not copy JAR files to any project directory - leave them in their original spots so they can be easily updated for when a JME3 update comes out or when you rebuild the source.
Workspace
If you are unfamiliar with Eclipse and how it lays out/stores its configuration, one of the first things that you should be aware of is that almost all settings that are set at a workspace-level (i.e. through Window -> Preferences) are stored in the workspace.
You can select your workspace either by starting Eclipse (if the initial prompt is enabled) or by navigating to File -> Switch Workspace -> Other.
TODO Image
For this guide, we’re going to create a new folder called “JMonkey” in our C:\ drive, however this folder can be anywhere on your drive (the same applies for users of other operating systems). We will also switch to it as a workspace.
Base JME3 Project (Desktops)
Prerequisites:
- JME3 (downloaded/extracted/built/installed) libraries located
It’s time to create our base JME3 project, which is actually relatively easy. Go to File -> New -> Java Project.
NOTE: If you don’t see “Java Project”, you are more than likely in a perspective other than Java or Java EE. Simply select “Project…” and then select Java → Java Project from the window that appears.
Give your project a name (we’ll call ours “JMEclipse-Base”) and click finish. The project should show up in the Project Explorer pane on the left.
First, we need to configure our build path. Right click the new project entry and go to Build Path -> Configure Build Path, and then select the “Libraries” tab.
There are a number of libraries you’re going to need to include, as the ‘core’ JME3 system requires them.
WARNING: There will be many libraries in the previously identified “libs” folder that aren’t initially used. Certain aspects of JME3 (for instance, collision detection) will require the appropriate JAR if your code requires that functionality. However, it is highly recommended you do NOT include every JAR in the ‘libs’ folder due to the fact that exporting them all when they are not needed will result in a huge jar file (~60MB).
Click “Add External JARs…”, navigate to the JME3 ‘libs’ folder (see Setting up JME3 if you’re not sure where this is), and select each of the following:
- jME3-core.jar
- jME3-desktop.jar
- jME3-jogl.jar
- jME3-lwjgl-natives.jar
- jME3-lwjgl.jar
- jogl-all.jar
- lwjgl.jar
- vecmath.jar
Add the JARs, hit OK, and you’ve successfully set up the base JME3 build path for your project.
The last bit that must be added are assets. Note that while the SDK has a single way of managing your assets, assets can be handled in a number of ways.
The rule for assets is that their files must be on the build path. This means that you can either include the inner folders directly in your project, or you can create a separate project (and thus, a separate JAR) for your assets.
Alternatively, you can keep them in the local directory if you do not wish to package them with the JAR, though this may not be desirable for certain deployments (such as applets, Android apps, or JNLPs).
To include your assets within your base project, follow the ‘Assets’ section without creating a new project. However, do note that this will make the process of including these assets in your Android project, if you create one, much harder.
Finally, the SDK creates a base source file for you that ends up being the main source file. Since we’re using Eclipse, we’ll have to manually create that file.
Right click your project, go to New -> Class, and fill out the appropriate information:
- Package: your package name (i.e. com.jme3.test)
- Name: the class name (i.e. MyGame)
- Superclass: com.jme3.app.SimpleApplication
Then hit Finish. This will create and open the new class file. Eclipse should have automatically inserted the method “simpleInitApp()” for you. This is where all of your game’s start up code will go.
Running
Running your JME3 project is quite simple in Eclipse. You can either create a Java run configuration (Help - Eclipse Platform) or you can simply hit CTRL + F11 to run the project (if Eclipse doesn’t know what to do, it will ask).
Packaging
Packaging your JME3 project is also very straight forward. Assuming you heeded the warning stated earlier about not including every JAR in the ‘libs’ folder, you should be able to right click your base JME3 project, go to Export…, select Java → Runnable JAR file, specify an output location and click “Finish”.
If you have assets set up as a JAR, make sure to read the Packaging section under Assets.
Assets
Each JME project has a set of assets that are used to load textures, models, and other resources used by your game.
As mentioned earlier, assets can be located/included in one of several ways. This section will describe how to include your project’s assets through the use of a separate JAR file, which has the added advantage of allowing you to update assets without needing to update the JAR itself. If you have a dynamic class-path system set up, this could be very useful.
First, create another generic project by going to File → New → Project… → General → Project and giving it a name (we’ll call ours “JMEclipse-Assets”).
NOTE: We create a General (non-Java) project for cleanliness because our assets will not require any special build settings or the like.
For new users, it’s a good idea to add the initial JME3 folders that the SDK creates, as they are referenced by many other guides on the web. To do this, for each of the following right click on the assets project and go to New -> Folder, type in the name listed, and hit Finish:
- Interface
- MatDefs
- Materials
- Models
- Scenes
- Shaders
- Sounds
- Textures
Although this specific structure is what the JMonkeyEngine SDK generates upon the creation of a new project, it is by no means the only way to structure your project. All asset loading methods will work with folder names other than those listed above.
Packaging
Packaging your assets is also a simple process. Right click the assets project and click “Export…” and then select Java → Jar file. It will show a list of files you can export; make sure to uncheck all files such as “.classpath”, “.project”, and any “.jardesc” files you may have created. As well, ensure only the resources and assets you want to export are checked.
Check “Export generated class files and resources”, select a destination for the JAR file, and check “Compress the contents of the JAR file”, “Add directory entries”, and “Overwrite existing files without warning”. Click Finish.
NOTE: Optionally, you can click Next and specify a .jardesc file by checking “Save the description of this JAR in the workspace” and specifying a location for a .jardesc file. That way you can simply double-click the jardesc file and easily re-export your assets when they change (remember, always refresh your project before exporting!).
Android
Prerequisites:
- JME3 (downloaded/extracted/built/installed) libraries located
- JME3 Base Project created (as described above)
- Android SDK downloaded and the Android 8 (2.2) target installed (higher API versions work too but may limit compatibility when deploying)
- Assets compiled into a JAR (see Packaging under Assets)
- Eclipse ADT plugin installed (ADT Plugin (UNSUPPORTED) | Android Developers)
The Android project is a slightly more involved setup project, but is still quite simple, even for new users.
To start, create another Android project by going File → New → Project… → Android → Android Application Project.
Fill out the following information and then click Next:
- Application Name: name of your application (i.e. “JMEclipse Test Project”)
- Project Name: name of the project in the workspace (i.e. “JMEclipse-Android”)
- Package Name: name of the base package, preferably the same as the one used in the base project (we’ll re-use “com.jme3.test”)
- Minimum Required SDK: API 8 (Must be AT LEAST SDK 8 for OpenGLES2 and JNI)
NOTE: Most of the lower options are defaulted based off of your ADT configuration and should work as-is.
After clicking Next, uncheck “Create activity” (JME3 provides a base activity class). You can check/uncheck “Create custom launcher icon” at your own preference.
Make sure that “Mark this project as a library” is unchecked and hit Finish (or Next if you chose to create a custom launcher icon; this will take you to a customization page, after which you will be forced to finish).
First, we need to set up our build path. Surprisingly enough, it’s much easier than the base project, though it is done a little differently.
At the time of this guide’s writing, the latest release of the ADT/Eclipse plugin creates a “libs” folder within your project structure. This special folder automatically includes all of its contents on the build path.
Normally, you would drop the JAR files directly into this folder. However, this is undesirable as future releases/builds of JME3 would require you to re-copy all of the JAR files. Instead, we will simply link them.
For each of the following, right click the “libs” folder within your Android project and go to New → File, click “Advanced >>”, check “Link to file in the file system”, click “Browse…”, navigate to the JME3 ‘libs’ folder (as identified in the “Setting up JME3” section above), double click the listed JAR file, and then click “Finish”:
- jME3-android.jar
- jME3-core.jar
- vecmath.jar
WARNING: There will be many libraries in the previously identified “libs” folder that aren’t initially used. Certain aspects of JME3 (for instance, collision detection) will require the appropriate JAR if your code requires that functionality. However, it is highly recommended you do NOT include every JAR in the ‘libs’ folder due to the fact that exporting them all when they are not needed will result in a huge jar file (~60MB).
As well, repeat the above step for your compiled assets JAR (see Packaging under Assets).
Now that the core JME3 libarilibrariesbeen added, we’ll need to include our base project’s code. To do this, right click on the Android project and go to Build Path -> Configure Build Path, select the “Projects” tab, click Add, and select the base project (in our case, “JMEclipse-Base”).
Lastly, select the “Order and Export” tab. Ensure that your base project (i.e. “JMEclipse-Base”), “Android Private Libraries”, “Android Dependencies”, and optionally “Google APIs” (if you have that target enabled) are checked. This step is important, or your project’s libraries/assets will NOT be exported into the end APK.
Click OK, and your project’s build path will be set up.
The next step is to create the application’s activity and edit the AndroidManifest to configure the project to actually use our JME3 project.
First, right click on the Android project and go to New -> Class, entering the following information and hitting Finish:
- Package: your application package (it’s best to use the package specified in the project creation dialog; for this guide, we’ll re-use “com.jme3.test”)
- Name: the activity class’ name (i.e. “JMEclipseActivity”)
- Superclass: com.jme3.app.AndroidHarness
This will create a new activity class. In the resulting file, create a default constructor and add the following code:
public JMEclipseActivity()
{
// Set the application class to run
appClass = “com.jme3.test.MyGame”;// Try ConfigType.FASTEST; or ConfigType.LEGACY if you have problems eglConfigType = ConfigType.BEST; // Exit Dialog title & message exitDialogTitle = "Quit game?"; exitDialogMessage = "Do you really want to quit the game?"; // Choose screen orientation screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; // Invert the MouseEvents X (default = true) mouseEventsInvertX = true; // Invert the MouseEvents Y (default = true) mouseEventsInvertY = true;
}
NOTE: Pay close attention to the values above; appClass MUST be the full package + class name of the class in your base project that extends SimpleApplication (for advanced users, this is actually a subclass of com.jme3.app.Application).
Running
Running your Android project is just like running any other Android project (ADT Plugin (UNSUPPORTED) | Android Developers). Assuming you’ve set up your build path correctly as instructed above, your application should deploy to any device/emulator and run as expected.
Packaging / Deploying
Packaging your Android project is too vast to entirely cover in this guide. As this step is different for each project, I will simply link to this guide to signing and exporting your APK (Menandatangani aplikasi | Developer Android | Android Developers) as it outlines the most common steps to exporting you Android application to be uploaded directly to Google Play (fmly. App Market).
Native (JNI + NDK)
Prerequisites:
- JME3 Base Project created (as described above)
- Eclipse’s CDT plugin installed (http://www3.ntu.edu.sg/home/ehchua/programming/howto/EclipseCpp_HowTo.html)
- At least one configured toolchain for compiling on desktop platforms (Cygwin/MinGW/MSVC/GCC/etc.)
- Familiarity with JNI and how native libraries are included in a Java application’s architecture (this section will assume you do)
- JDK for Java 6 or above
If additionally building for Android:
- Android SDK downloaded and the Android 8 (2.2) target installed (higher API versions work too but may limit compatibility when deploying)
- Android NDK downloaded
- Optional: NDK Eclipse plugin installed (although I haven’t seen a real need for it quite yet - it’s mainly for building/launching native Activities) (Using the Eclipse NDK plugin - Android Studio Project Site)
NOTE: It should be mentioned that this section will not go into C/C++ best practices, sample code, or any details about the inner workings of JNI; instead, this section simply shows you how to set up the environment/configurations to create a near-seamless build environment for including your native code in both your base project as well as your Android project (if you’ve created one).
Building JNI is actually quite straightforward (assuming you know how the C/C++ build process works). Even for Android, the NDK provides a slick system for building/including your compiled binaries in your project.
First, create a new C/C++ project by going to File → New → Project… → C/C++ → C++ Project and clicking Next, giving it a name (we’ll use “JMEclipse-Native”), expanding “Shared Library” and selecting Empty Project, then selecting a toolchain (select the most appropriate for compiling on your immediate desktop/platform, even if you plan on compiling for Android). Click Finish.
Next, we need to configure our build settings. Right click the native project and click Properties and go to C/C++ Build -> Settings. Select the Build Artifact tab, ensure the drop down menu says “Shared Library”, and change the “Artifact name” field to what you want to call your eventual JNI module.
WARNING: What you call your artifact is VERY important to how Java loads your library. For instance, linux dynamic library (.SO) objects require that the library have the “lib” prefix. Keep this in mind when specifying an artifact name.
If you plan on building for Android, you must include an Android makefile in your project. In order for the build process to be as seamless as possibly, this guide sets it up unlike most tutorials instruct.
To do this, simply create a new file in your native project called “Android.mk” and set it up accordingly (http://www.kandroid.org/ndk/docs/ANDROID-MK.html).
NOTE: Even though the native project is not the Android project’s directory, keep the ‘LOCAL_PATH’ variable set to ‘my-dir’. This is important!
Next, we need to create a configuration for the Android target.
NOTE: This step is only relevant/possible if you have the NDK Eclipse plugin installed. Otherwise, you will need to install awk/make (using Cygwin if on Windows) and build through the command line manually.
To do this, right click your native project, click Properties, and go to C/C++ Build → Tool Chain Editor. For the configuration, click “Manage Configurations…” and create new configuration(s) based on the current default configurations, putting “Android” in the name, and hit OK.
For each of the configurations you just created, select them in the “Configuration” drop down menu, set “Current toolchain” to “Android GCC”, set “Current builder” to “Android Builder”, then click “Select Tools…”, remove everything from the right side and replace the last item with “Android GCC Compiler”. Click apply and then OK.
After the toolchains have been set up, go to C/C++ Build and select the “Builder Settings” tab. For each of the Android configurations, select them in the “Configuration” drop down menu and change the “Build directory” to the Android project directory by clicking “Workspace…” and selecting the Android project (in our case it’d be “JMEclipse-Android”).
The last step in the Android setup is to create a symlink called “jni” (case sensitive) inside your Android project root that points to the root of your native project:
- Windows: CMD prompt -> “cd path\to\Android\project” -> “mklink /J jni path\to\native\project”
- Linux/Mac: Terminal -> “cd path/to/Android/project” -> “ln -sv path/to/native/project jni”
NOTE: What this has essentially done is created a separate project for C/C++ building while tricking the Android project into thinking the source files are located directly in the Android project itself. With this configuration scheme, you can easily build regular shared libraries for desktop platforms as well as build/install the Android libraries using the NDK without the need to have a copy of the source code inside of the ‘jni’ folder of an Android project. By setting the workspace for the Android builder and creating a link, it executes the NDK builder inside your Android project while serving the source files as if they existed in the ‘jni’ folder.
Lastly, some additional include paths need to be added. Within the properties window, go to C/C++ General -> Paths and Symbols and select the “Includes” tab.
Under Languages, select “GNU C++” (or the correct C++ equivalent) and then “Add…”. Specify the absolute path to your JDK’s “include” folder, check “Add to all configurations”, and hit OK.
NOTE: For Windows platforms, repeat the above step for the “win32” directory within the JDK’s “include” folder.
After hitting OK, you are now set to write your JNI code.
Building
Building your native project is fairly straightforward.
First, right click the native project, go to Build Configurations, select the configuration you want to build, and then right click -> Build Project. Short of packaging, that’s all there is to it.
Packaging / Deploying
Packaging and deploying your native libraries is a two-sided topic. For Android, the NDK build script installs these for you, and they are packaged directly into the APK. For desktop applications, however, there are a multitude of ways to package your libraries - all of which are too vast to be included in this guide.
These libraries, however, are simply JNI libraries and should be loaded as such. A simple web search will explain how JNI works and how to load these libraries.
It’s 8 in the morning. Time for bed.