If you've used libGDX for even a short time, you've probably used the official gdx-setup.jar
made by the libGDX team. It's seen
major improvements lately, but it still lags behind in some areas -- it places assets in different locations depending on how you
initially configured your project, and it is very far behind the times on its default LWJGL version and on third-party extensions.
The official setup may transition to a web-based tool soon, but any user of the Internet can recall times when
formerly-reliable services went offline or had outages. This project provides another alternative setup tool based on
SquidSetup, but removing the close ties to the SquidLib libraries to make it more general-use. Using SquidSetup's
code, which is built on czyzby's code, gives us working projects that use Gradle 7.6, a bit ahead of the official setup and far ahead of 4.0.2 for czyzby's gdx-setup.
The current Gradle version is 7.6 at the time of writing, and since gdx-liftoff 1.11.0.5, new projects use that 7.6 version.
This allows new projects to "just work" on machines where Java 8 through 18 could be the default, and the moderate amount of configuration
changes needed for Gradle 7.x are all handled by gdx-liftoff. Thanks to the Gretty plugin's latest release, Gradle 7.x
now works well with the HTML platform, without additional quirky configuration (earlier versions of Liftoff needed that).
Currently, gdx-liftoff projects depend on libGDX 1.11.0 by default, and allow using earlier versions or snapshots as well.
The current version of libGDX is 1.11.0. You can choose any released version of
libGDX (or a nightly version) in the Advanced tab of the program window; it will be downloaded if needed when you import
the Gradle project into your IDE or run one of most Gradle tasks. If you're updating from an older libGDX version, see
the official migration guide.
Projects default to using LWJGL3 instead of LWJGL2 (the old 'desktop' platform), since code tends to be very similar between the two, but LWJGL3 generally offers more features. Somewhat confusingly, gdx-setup used LWJGL2 for its desktop platform until recently, but now uses LWJGL3 and still calls it 'desktop'. Liftoff projects can have both LWJGL2 and LWJGL3 modules, which shouldn't be needed for too much longer, but is sometimes needed now. The "lwjgl2" module is LWJGL2, and "lwjgl3" is, well, LWJGL3. If following a tutorial, you may need to change mentions of the "desktop" or "lwjgl2" module to "lwjgl3". This code is tested for compatibility with GWT, including the various changes that Gradle needs with this version. It is sometimes tested on Android, but Android Studio is often incompatible with recent Gradle releases, and Android certainly doesn't support Java 12 or higher features across the board. Issues with iOS and RoboVM will have to be addressed by someone sending a pull request, because I can't reproduce any iOS issues without an iOS device.
The current version of gdx-liftoff uses LWJGL3 internally; 1.9.10.5 used LWJGL2 in an attempt to be compatible with libGDX's TexturePacker, but there seem to be more compatibility issues with LWJGL2, maybe since it hasn't been updated in 5+ years, than with LWJGL3. This perhaps validates the decision to default to LWJGL3 for new projects generated by gdx-liftoff.
Using the latest Gradle, as gdx-liftoff tries to always do, is important when there are ongoing security concerns. The latest Gradle versions are all pre-configured to avoid vulnerable versions of log4j (which had the serious "log4shell" vulnerability exploited starting in December 2021). We don't need the mitigations that earlier versions of gdx-liftoff used to avoid vulnerable log4j versions, now that Gradle has updated and considers this automatically.
- Get the latest
gdx-liftoff.jar
from the Releases tab of this project.- If you have an older gdx-liftoff.jar, or you aren't sure when it was released, getting the current latest is a good idea.
- Regardless of what platforms you intend to target, make sure the steps described by the libGDX wiki here are taken care of.
- Run the JAR. Plug in whatever options you see fit:
- For the Platforms tab, LWJGL3 starts enabled by default (it works on all desktop/laptop platforms), and you can
manually check other platforms to match your needs.
If you target iOS, it will only build on a MacOS machine. Downloading iOS (and/or HTML) dependencies can take some
time, so just check the platforms you want to target. You can re-run the setup, make a new project with the same
settings (in a different folder), and copy in the existing code if you want to quickly change platforms.
- LWJGL2 and/or LWJGL3 should usually be checked, so you can test on the same computer you develop on.
- LWJGL3 is almost the same as LWJGL2, but because it has better support for new hardware
(such as high-DPI displays), it should probably be preferred. It also allows multiple windows and drag+drop.
- LWJGL3 itself supports Linux on arm32 and arm64 hardware, and libGDX since version 1.9.13 (current is 1.11.0) also supports ARM Linux on desktop platforms.
- The new ARM Macs are now supported as of libGDX 1.11.0 when using the LWJGL3 backend. LWJGL2 does appear to work via macOS "Rosetta" emulation, though.
- LWJGL2 should mostly be preferred if you need to also depend on gdx-tools, such as if you need to run the
texture packer at runtime. Some machines have issues with an inconsistent or very high framerate with LWJGL3,
and using the "Legacy" desktop can fix that. This platform can also be less compatible with some JDKs, and
distributing a JDK from Adoptium usually fixes that.
- The framerate limit problem is currently solved with both LWJGL2 and LWJGL3, as long as you use libGDX 1.9.12 or higher.
- The "less compatible" JDK issue manifests as a crash immediately at startup, with several warnings printed
(which themselves don't matter), and a line right after them mentioning
ld.so
or a linking error. If you encounter this, switch to AdoptOpenJDK (bundling it with releases) or LWJGL3. - The warnings on startup when using (legacy) desktop are somewhat important to note; even though they say
the application won't be allowed to start on future JDK versions, LWJGL 2 and 3 both will adapt to any
inability to use certain internal APIs, and both should run perfectly fine on Java 16 and up, even though those
default to blocking what the warnings mention. Actually, Java 16 and up shouldn't emit these warnings at all.
- Even if you didn't build a JAR with Java 17, you can still run the generated JAR with Java 17, and this may be a good idea for distribution because of some speed and stability improvements in that JVM release. 17 is also an LTS release, and those tend to get more adoption.
- Java 18 is out now, and supported by the current Gradle, but it isn't an LTS release.
- LWJGL3 is almost the same as LWJGL2, but because it has better support for new hardware
(such as high-DPI displays), it should probably be preferred. It also allows multiple windows and drag+drop.
- iOS should probably not be checked if you aren't running MacOS and don't intend to later build an iOS
app on a Mac. It needs some large dependencies to be downloaded when you first import the project.
- If you have a Mac that is set up for iOS development, please try to generate any project and see if it gets made correctly! We've had some good feedback on iOS projects, but any extra usage info would help ensure that liftoff is ready for any libGDX usage. It isn't a typical usage for a GitHub Issue, but sending any feedback as an issue, whether it's "iOS projects work for me" or "iOS support is broken" would really help.
- Support for iOS should be better as of 1.10.0.3, but it could still use more testing. There are changes in libGDX 1.10.0 that should really help iOS projects out of the box; if you encounter screen trouble with any template applications, first add a Viewport like you would for any other platform, and see if there is still an issue. If you still have clipping or a smaller view area, post an issue. Several changes happened in libGDX 1.10.0 to improve behavior on iOS, and gdx-liftoff may need to apply some changes to template code for iOS projects to work more cleanly with libGDX 1.10.0.
- Android should only be checked if you've set up your computer for Android development. Since gdx-liftoff uses
Gradle 7.6, having an Android project present shouldn't interfere with other platforms or IDE integration, as
long as your IDE supports Gradle 7.6 (current Android Studio and IDEA both support it).
- You must set your project's JDK to a version 11 or higher to use Android, due to a new requirement of the Android Gradle Plugin used by Android Studio and IDEA. JDK 11 is the most versatile option right now, because it can be used with gdx-setup projects and Android projects. JDK 17 or 18 will work. You could have to open older projects, so having JDK 11 installed is a good idea.
- Having an Android module in a larger project changes some of IDEA's features, including disabling hot-swap. Some libGDX developers take the approach of having a separate Android-only project, keeping desktop platforms completely disconnected from Android. This also lets the assets be different, so it has other advantages.
- If
Java version
is set to 8 on the Advanced tab, then gdx-liftoff sets up the Android configuration to use core library desugaring and other Java-8-related features, allowing a large subset of Java 8 language features, and the standard library in JDK 8, to be used across most platforms (not iOS, though).- Several 3rd-party dependencies require Java 8, such as TuningFork (which is LWJGL3-only), and jdkgdxds (which works on Android if the above Java 8 steps are taken).
- If you are using an Android Studio version before 4.2 or an IDEA version before 2021.2, you can set the Android Gradle Plugin on the Advanced tab to a lower version, like 4.0.2, that is compatible with that older IDE version.
- HTML is a more-involved target, with some perfectly-normal code on all other platforms acting completely
different on HTML due to the tool used, Google Web Toolkit (GWT). It's almost always possible to work around
these differences and make things like random seeds act the same on all platforms, but it takes work. Mostly,
you need to be careful with the
long
andint
number types, and relates toint
not overflowing as it would on desktop, andlong
not being visible to reflection. See this small guide to GWT for more. It's very likely that you won't notice any difference unless you try to make behavior identical on GWT and other platforms, and even then there may be nothing apparent.- GWT 2.9.0 is available but doesn't integrate with libGDX by default; there's a third-party replacement to the
official GWT backend that supports it with libGDX
1.10.0. Using GWT 2.9.0 allows Java 11's
var
keyword to be used, plus other Java 11 features, but doesn't change much of what's available from the standard library.
- GWT 2.9.0 is available but doesn't integrate with libGDX by default; there's a third-party replacement to the
official GWT backend that supports it with libGDX
1.10.0. Using GWT 2.9.0 allows Java 11's
- LWJGL2 and/or LWJGL3 should usually be checked, so you can test on the same computer you develop on.
- For dependencies, you don't need libGDX checked (the tool is ready to download libGDX and set it as a
dependency in all cases).
- There are lots of potential dependencies you can add, some official but most third-party (unofficial).
- Some to note: ShapeDrawer is a great replacement for ShapeRenderer from libGDX, Ashley (official) and
Artemis-ODB (third-party, well-maintained) are both useful Entity-Component System libraries, Typing-Label
provides all sorts of effects for text, RegExodus and Formic provide support for missing features in GWT,
TenPatch enhances the options for NinePatches in GUIs, simple-graphs and gdx-ai are different options for AI,
Anim8-GDX provides ways to write GIFs and other images that libGDX can't normally write, gdx-gltf is a much
better way to handle modern 3D graphics in libGDX, and Lombok is a popular way to reduce boilerplate in Java.
- Yes, I wrote or contributed to some of these, so I'm biased.
- There are options to add language support for non-Java JVM languages; of these, Kotlin is the best-supported.
- The HTML target won't work with non-Java languages, and others targets may be questionable.
- Kotlin should work well on Android, LWJGL2 and LWJGL3, and will probably work well on iOS.
- You can see some extra ways to use Kotlin as the Gradle build language in Quillraven's Dark-Matter repo; it also uses Kotlin launchers.
- You can select Kotlin templates on the templates tab, if Kotlin is selected as a language.
- Some third-party extensions only work with Kotlin, like the KTX libraries.
- Scala and Groovy should definitely work on LWJGL2 and LWJGL3, and may work on Android and iOS.
- Clojure may technically work on Android but is usually incredibly slow without extra steps for Android
compatibility; it's doubtful if it would work on iOS. You probably shouldn't use Gradle to build Clojure
projects anyway; it has its own (excellent) project manager
lein
and a simple built-in manager.
- In the Templates tab, you can select various sets of starting code that gdx-liftoff will generate in your new project. Classic will show a white screen with a pixel-style face when you run, so it can be good to verify that a project works, while ApplicationAdapter is probably the easiest to bring an existing game into. The super-koalio demo is from libGDX's tests, and may act as a good way to test input and basic graphics in a new project.
- In Advanced, you can set the libGDX version (it defaults to 1.11.0, but can be set lower or higher) and
various other versions, including the default Java compatibility. Typically,
Java version
is the minimum across all platforms, and should be 7 or more (8 is generally safe). You can setDesktop Java version
to any version at least equal toJava version
, and similarly forServer Java version
; these only affect the LWJGL2/LWJGL3 and Server modules, respectively. You can setJava version
to as high as 18 if you have Java 18 installed, or similarly for Java 11, 12, 13, 14, 15, 16, or 17, but it will require users to also have Java of that version, or for you to distribute a JRE of the appropriate version with your game.- Distributing Java 14, 15, 16, 17, or 18 is much easier now thanks to Beryx' "Badass Runtime Plugin," which may be included in future versions to help ease the process of releasing a game.
- HTML projects this generates always use language level 8, even if the JDK is newer. A comment in
html/build.gradle
provides some instructions for how to use an alternate backend and use as new as Java 11.
- For the Platforms tab, LWJGL3 starts enabled by default (it works on all desktop/laptop platforms), and you can
manually check other platforms to match your needs.
If you target iOS, it will only build on a MacOS machine. Downloading iOS (and/or HTML) dependencies can take some
time, so just check the platforms you want to target. You can re-run the setup, make a new project with the same
settings (in a different folder), and copy in the existing code if you want to quickly change platforms.
- Click generate, and very soon a window should pop up with instructions for what to do.
- Generation is very fast here, relative to gdx-setup, because it doesn't run Gradle tasks at this point. When you
see
SETUP COMPLETE
in green, the build is done; at the time you import the generatedbuild.gradle
project file, some tasks will run.
- Generation is very fast here, relative to gdx-setup, because it doesn't run Gradle tasks at this point. When you
see
Now you'll have a project all set up with a sample. In IntelliJ IDEA or Android Studio, you can choose to open the
build.gradle
file and select "Open as Project" to get started. In Eclipse or Netbeans, the process should be similar;
see libGDX's documentation.
- The way to run a game project that's probably the most reliable is to use Gradle tasks
to do any part of the build/run process. The simplest way to do this is in the IDE itself,
via
View -> Tool Windows -> Gradle
, and selecting tasks to perform, such aslwjgl3 -> Tasks -> application -> run.
If you try to run a specific class'main()
method, you may encounter strange issues, but this shouldn't happen with Gradle tasks.- To run a
main()
method, you usually need to set a run configuration so the working folder isassets
. The location of theassets
folder is different here than with the official setup; it's at the same depth ascore
orlwjgl3
, and doesn't change across configurations like with the official setup.
- To run a
- If you had the LWJGL3 (or LWJGL2) option checked in the setup, and you chose a non-empty
template in the Templates tab, you can run the LWJGL3 or LWJGL2 module right away.
- You can build a runnable jar that includes all it needs to run using
lwjgl3 -> Tasks -> build -> jar
; this jar will be inlwjgl3/build/libs/
when it finishes. Note: this is the command-line optiongradlew lwjgl3:jar
, not thedist
command used by the official setup jar. Substitutelwjgl2
wherelwjgl3
is if you use the legacy LWJGL2 version.
- You can build a runnable jar that includes all it needs to run using
- If you had the Android option checked in the setup and have a non-empty template, you can try to run the Android module on an emulator or a connected Android device.
- If you had the GWT option checked in the setup and have a non-empty template,
you can go through the slightly slow, but simple, build for GWT, probably using the
superDev
task for thegwt
module, or also possibly thedist
task in that module.- GWT builds have gotten much faster with Gradle 7.6 (since Gradle 6, really) and some adjustments to configuration, so if you were avoiding GWT builds because of slow compile times, you might want to try again.
- If you had the iOS option checked in the setup, you're running Mac OS X, and you have followed all the steps for iOS development with libGDX, maybe you can run an iOS task? I can't try myself without a Mac or iOS device, so if you can get this to work, posting an issue with any info for other iOS targeters would be greatly appreciated.
- Consider changing the icons when you're looking to distribute your app. appicon.co or
some similar service can generate all the different requisite sizes.
ios/data/Media.xcassets/AppIcon.appiconset
has the iOS icons,android/res
has icons in subfolders, andlwjgl3/src/main/resources
has icons for desktop with LWJGL3. You'll probably want to keep the icons' existing names, and customize their content.
Gradle has some quirks. Here's some notes on things you might encounter during upgrades from other projects or older versions.
- All builds currently use Gradle 7.6 with the "api/implementation/compile fiasco" resolved. Adding dependencies
will use the
api
keyword instead of thecompile
keyword it used in earlier versions. All modules use thejava-library
plugin, which enables theapi
keyword for dependencies.- You can use the
implementation
keyword for dependencies in any module exceptcore
; this is supposed to have some benefits, but I'm honestly not sure what they are.
- You can use the
- You may need to refresh the Gradle project after the initial import if some dependencies timed-out;
JitPack dependencies in particular may take up to 15 minutes to become available if you're using any of those,
like gdx-gltf. In IntelliJ IDEA, the
Reimport all Gradle projects
button is a pair of circling arrows in the Gradle tool window, which can be opened withView -> Tool Windows -> Gradle
. - Like the official gdx-setup, the now-shut-down
jcenter()
repo will not be used in new projects.- In earlier versions, jcenter() was last in the list because of a different flaw it had that allowed impersonation. You may have guessed that I am not sad to see it shut down in favor of better alternatives. It's still annoying to have to deal with it closing on short notice, though.
- MacOS does not like the legacy desktop apps, showing all sorts of visual glitches.
It seems to work fine with LWJGL3, in part because that platform had special attention
paid to it so the
gradlew lwjgl3:run
command can work at all on MacOS.- Consider adding the third-party extension Guacamole to handle a special MacOS/LWJGL3 requirement (it
needs
-XstartOnFirstThread
to be passed to thejava
command, but Guacamole can handle this for you and your users). - Apps for end-users have to include a bundled JRE to be distributed via the Mac App Store, and it's generally a
good idea to distribute your JRE of choice, so you know what bugs to expect. If you bundle a JRE, you can set the
launcher to use
-XstartOnFirstThread
, and so don't need Guacamole for that.
- Consider adding the third-party extension Guacamole to handle a special MacOS/LWJGL3 requirement (it
needs
- Android hasn't been tested enough, and the generated manifest is probably not very good.
- You can modify the manifest, and probably need to do so if you want to submit an app to the Play store.
- Android Studio should have better support for recent Gradle versions if you use a beta release.
- The default path to the Android SDK is determined by your
ANDROID_SDK_ROOT
variable. If this variable wasn't set on the first time you ran gdx-liftoff, then the latest value entered for the Android SDK path will be saved in~/.prefs/gdx-liftoff-prefs
(that is, inside.prefs/
in your user home directory). Starting in 1.10.0.7, gdx-liftoff will pre-fill the Android SDK path withANDROID_SDK_ROOT
if it hasn't been set yet, but will use the last used path if there's a historical path. You can change any and all settings history by either editing~/.prefs/gdx-liftoff-prefs
or just deleting that file and having gdx-liftoff remake it.
See the architecture document for more details on how the application works internally.
When submitting pull requests, please format the code with the ./gradlew ktlintFormat
task.