Resizable Applets and Applications with LWJGL

Some posts before, in the comments section, Gornova asked me to write about resizable Applets if I had some time. As I never used resizable LWJGL Applets, I had to do some research. This post is to show what I found.

(note: LWJGL version 2.8.2 was used for all the tests I made).


LWJGL Applets are similar to LWJGL Applications, they work using a class named Display which uses an AWT Canvas component. On desktop, you create a JFrame or similar and add inside a Canvas, on Applet you just create the Canvas and add it to the Applet. Unless you want some custom behavior, I believe that is the common usage.

(note: using fullscreen is a different case but has no meaning for this post)

How to resize an Applet

To resize an Applet on the browser, two possible ways are, use Javascript to change the applet tag sizes or just configure the HTML applet tag to adapt to its container size, so if you resize the browser window then all corresponding HTML components are resized.

The other way around, suppose you have a way inside your game to choose the game resolution, you will have to communicate that to the Browser, probably calling a Javascript function from your Applet to let the Browser react to the change.

How to handle Applet resize

If you are working with LWJGL directly, then it depends a lot of how which kind of layout are you using for the container of the Canvas object. For example, if you chose a layout which grows to the parent container size, then each time you resize the container, the Canvas will be resized. If you chose another layout, then maybe you will call Canvas.setSize() by hand.

However, you need to react to that change in your game, to do that the best way (imho) is use a similar approach LibGDX does. What LibGDX does is, its stores the current Canvas size on each iteration of the main application loop, on the next iteration, if the Canvas size is different to the stored, then it calls a resize() method to tell your game the screen size changed.

Another way is to create a ComponentListener and add that to the Canvas component so each time the componentResized() method is called you resize your game. However as all the AWT stuff runs in another thread you need to store the new size and process the resize in your LWJGL thread to avoid problems.

What to do inside your game

The very basic approach is to just modify the OpenGL viewport of your game, then the game is scaled to the new size and, in some cases, that should be enough.

	glViewport(0, 0, width, height);

However, You may want to take care about aspect ratio since just scaling the game could look ugly. One option is to modify the viewport in values to maintain the aspect ratio you want, for example:

	glViewport(0, 0, width, width / aspectRatio);

You could also provide different common aspect ratios (4:3, 16:10, 16:9, etc). However, I believe the best option is to provide fixed commonly used resolutions like 640x480 or 800x600 instead.

In some cases you could want to adapt your game elements, for example GUI stuff, where you may want to maintain the element sizes and move them accordingly over the screen instead just scaling them.

Then, you have to take care of the user input. As mouse location is dependent on the viewport size, you will have to take that in mind when interacting with part of your application, like the GUI stuff, after a size change. For example, LibGDX Camera uses the current viewport size when using project and unproject methods (which allow you to transform world coordinates to viewport coordinates and vice versa).

Not so sure as I am not an OpenGL expert but if you work different cameras (model + projection matrices) you probably need to update them in order to render everything in the correct way. I have to go deeper in this issue.

Optionally, you may want make other changes when reacting to the resize like loading HD assets if you go to a higher resolution and vice versa.

Some issues

  • You have some glitches if you do resize in real time (tested myself, but cant find references right now). However, in general nobody does this so it is not a big problem.
  • I believe Applet resizing is not working on mac yet.


Handling all the mentioned things when resizing LWJGL Applets and LWJGL Applications depends a lot on the game you are making, in some cases the basic approach work fine and should be easy to implement.

Despite the article was focused mainly on LWJGL Applets, great part of the findings can be applied to LWJGL Applications as well.

This post is only to show some basic experimentation I made on the subject, as I said before, I am not an OpenGL nor LWJGL expert, so some assertions could be wrong. If you have more experience and want to contribute your opinion, feel free to do it.

Thanks and hope you like the post.

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

JNLP Applet Loader

Now that we talked about the LWJGL Applet Loader, we want to talk a bit about the JNLP Applet Loader. In a quick description, the JNLP Applet Loader is an adapter of the LWJGL Applet Loader to make it work with JNLP files.


All of our games were previously released through Web Start and New Generation Plug-In Applets using JNLP files and we wanted to use LWJGL Applet Loader in an easy and seamlessly way.


Our solution was to create an Applet to parse the JNLP file and with that information, create the parameters needed in order to run the LWJGL Applet Loader.

Right now, it works with two parameters:

  • al_jnlp : an URL used for telling it where to find the JNLP file to use in order to launch the game. First, it downloads and parses the JNLP file and with the information provided, and with that, it creates all LWJGL Applet Loader parameters (al_jars, al_main, etc).
  • appendedJarExtension : a String suffix appended to all jar and natives dependencies in order to let the LWJGL Applet Loader to download optimized with pack200 and gzip files while it doesn't process the content encoding for pack200 and gzip stuff.

You can find the project on github with the name of jnlpappletloader. It is a maven project, and right now, as it depends on a custom distribution of the LWJGL, it will not compile for you at least you configure your local maven repo with the required dependencies. Once the LWJGL is on maven central repo, the idea is to depend on it directly.

The best part is that now we can run any of our already deployed games by making a simple applet like this:

<applet code="com.gemserk.jnlpappletloader.util.jnlp.applet.JnlpAppletLoader" archive="jnlpappletloader-full-0.0.4-jar-with-dependencies.jar" codebase="" width="640" height="480">
  <param name="al_jnlp" value="">
  <param name="appendedJarExtension" value=".pack.gz">

Here is a working example of one of our games using the JNLP Applet Loader (it will look exactly as any other game using LWJGL Applet Loder).

One disadvantage of using the JNLP Applet Loader is the extra time consumed to make the JNLP file request and to parse it vs just using the regular LWJGL Applet Loader. However, using the JNLP Applet Loader lets you to use one centralised JNLP file for all your game's launch configurations through different deployment options. Also, if you deploy your game in several portals like Games4j, GameJolt, your own page, etc, and you make a change of your game's launch configuration, your change is automatically replicated because all of them use the same configuration file.

Note that the project is highly coupled to LWJGL Applet Loader, it will not work for any Applet (it should be named something like JNLP Adapter for LWJGL Applet Loader).

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

LWJGL Applet Loader

In a previous post we talked about Java Games deployment options, in this post we want to talk about one custom solution provided by the LWJGL: the LWJGL Applet Loader.

The LWJGL Applet Loader is an Applet which performs a lot of common deployment tasks:

  • It shows a nice and customizable loading screen when deployment is being processed, with detailed messages for each task: downloading file.jar, extracting file.jar.gz, etc.
  • It downloads all required dependencies. If they are compressed using gzip, LZMA or Pack200, it extracts them.
  • It has a cache for all your dependencies so if one dependency is not modified on the server, then it is not downloaded again.
  • It configures the Java library path to load all your native dependencies.
  • Finally, it runs your game's applet.

A feature in mind when developing the LWJGL Applet Loader is that it should start as fast as possible, for that, the jar of the Applet Loader should be really small. The idea is to speed up all the Java loading screen so it can show quickly your custom loading screen.

It provides a lot of parameters in order to let you customize deployment stuff, like which natives dependencies you need for a specific platform, the logo and progress bar, etc. Full documentation of the parameters is on the API docs and you also have a great tutorial at LWJGL Wiki.

This is how it looks when loading an Applet using the LWJGL Applet Loader with the default loading screen:

note: Even without customization, it looks much nicer than Java default loading screen.


  • It lets you customize loading screen, and create Applet using natives support in an easy way.
  • It starts fast. This avoids some browser freeze bug when starting a Java Applet, like Firefox on Linux platforms.
  • It handles different compression options like gzip and LZMA, it also handles Pack200 jars.
  • It works on Mac OS, that is a big difference versus running New Generation Plug-In Java Applets, because they are disabled on Mac OS.
  • It is open source and the guys maintaining it are always open to receive patches and improvement ideas.


  • Pack200 and compression stuff is not done automatically, you have to specify exactly which file you want to download (example: you have to specify that you want to download somedependency.jar.pack.gz instead of having the Applet Loader to detect automatically which version to download by receiving the content encoding from the server).
  • Assumes you need native dependencies, so you need to fill some Applet parameters even if you don't need them. (we want to add an RFE for that)
  • It doesn't use the same cache other Java Applets or Java Web Start use. That means you have to download twice one Applet distributed using LWJGL Applet loader and Java Web Start, and it will cost you double space.

To see LWJGL Applet Loader working you can try one of our games here (warning: link could be broken in the future) or you can try a working and stable version of a game using LWJGL Applet Loader here, its name is Minecraft, don't know if you know about it.

In one of the next posts we want to talk in detail about another deployment option we mentioned before, now that we have some experience using it: getdown.


VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

Games as Applets 3

Following our Games as Applets series, we want to talk about the Wordrpess Page Template we are using in order to deploy our games as Java Applets inside the Blog.

WordPress Custom Fields

When creating a new blog post or page, the creator can add metadata using WordPress Custom Fields, to be processed later by the PHP templates associated. In our case, we are using the following custom fields:

  • applet_height - height of the applet.
  • applet_width - width of the applet.
  • applet_screenshot - URL to a screenshot of the game
  • jnlp_url - URL to the JNLP for launching the game.

WordPress Page Templates

After adding metadata to our posts or pages, we need to make a WordPress Page Template in order to process it. In our case, we created a PHP template for our games deployed as Java Applets using the structure explained in our last post about Games as Applets. Our games template looks like this file.

Note: I didn't want to put all the PHP file code directly in the post because it is too large.

This is how we get the post metadata:

	$jnlp_href = get_post_meta($post->ID, "jnlp_url", true);
	$applet_width = get_post_meta($post->ID, "applet_width", true); 
	$applet_height = get_post_meta($post->ID, "applet_height", true);  
	$applet_screenshot = get_post_meta($post->ID, "applet_screenshot", true);  

And this is how we pass the values to the javascript:

<?php echo '

' ?>

Once the page template is created, if we want to add a new page for a game, we only have to select it from the templates list and voilá.


Using WordPress Page Templates and Custom Fields, we can reduce the information of the game's page to game's related information only, and move all common logic and information between game pages to the page template.

This is how it looks to edit a game page:
Game Page being Edited

Note: there is no applet tag or javascript in the page.

Also, if we modify the page template, we have all game pages updated, that could be really useful if you need to fix a bug or make an improvement to the page but could be a problem in case we introduce a new bug.

One problem not resolved yet is if you want to change the WordPress Theme, you will have to migrate the page template. I don't know exactly if you can create a page template theme independent.


VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

Ways to deploy a Java Game

When you develop Java games for PC, you have different ways to deploy them. We want to talk a bit about some of them.


The user has to download the game to run it on his machine, probably it comes with an installer to install the game before he can play it.


  • The game can be played offline when it has no online requirements.
  • User knows where the game is installed and sometimes decides where he wants to install it. They also can uninstall the game.
  • It is the only way to deploy a game in portals like Steam, Altitude Game is an example of that.


  • Users have to download a patch each time there is a new version. As a developer, you can implement something to download patches and apply them.
  • As a developer, you have to implement an installer. Also, you have to make different installers for each platform, an example of that is Revenge of the Titans (ROTT) from Puppy Games.
  • You have to create patches and deploy new files to be downloaded each time you have a new version of the game after a bug fix or new feature. Else, you force people to download large files each time you have an updated version.
  • Java Runtime Environment (JRE) must be installed or you have to embed JRE with your game. In the second case, your game file becomes bigger, for larger games that is not a problem but for small games embedded JRE could be, for example, 300% of the game size (at today, JRE weight is about 20MB). Even though there could be a JRE installed, being able to execute your program directly depends on a good configuration of the JRE within the OS. To solve that, developers usually generate a native wrapper that detects where the installed JRE is, and if it is not installed prompts the user to download one, or reports the error to the user.


Java Applets works inside the browser, as well as other web technologies like Flash and Unity. Users only have to open a page with a Java Applet inside and it is loaded by the web browser. Minecraft is an example of a successful Java Applet Game (it has other deployment options as well).


  • Users only have to follow a link to play the game. No game install is required.
  • Users are always playing the latest game version, because it is being downloaded from the server.
  • As other web technologies, you can add information or even ads to your applet page without having to put that inside the game.
  • Java Applets are as powerful as a Java Desktop application.
  • New Generation Java Applets accepts Java Networking Launching Protocol (JNLP) files (more info on next blog posts).
  • Pack200 and GZip compression support to reduce jar download sizes (only using plugin2).


  • JRE must be installed on the client machine. However, nowadays you can assume the required plugin is installed on most of the client machines.
  • You need a web server to deploy your game jars or you have to use a games portal like GameJolt or Games4j.
  • Dependning on the Java Applet technology you are using (plugin2, etc), firefox can freeze when the applet is loading, or could not work on Mac OS (more information on next blog posts).
  • As a developer, you need to sign your jars with a certificate if you want to have full access (to do extra stuff like writing a configuration file on user's home folder).
  • If you ask for full access, a security dialog box is displayed. It tends to scare users, if you have a valid certificate then it is a bit less scary.

Web Start

Java Web Start is some kind of mixing between the last two. As developer you use a JNLP file to describe which resources must be downloaded. Users only have to click on a JNLP link and then the game is opened automatically by Java Web Start.


  • Users only have to follow a link to play the game. No game install is required.
  • Automatically downloads the latest version of your game from the server each time the user wants to play a game.
  • It has a cache for downloaded resources, so if you only update one jar then it is the only one downloaded by the user's machine the next time the user opens the game.
  • As a developer you can specify to run the game offline.
  • It has a clean way to specify your game's resources using the JNLP file.
  • Pack200 and GZip compression support to reduce jar download sizes.


  • Some browsers are not configured correctly (for example, Google Chrome) and they don't open the JNLP automatically using Java Webstart, they just download the file.
  • Same thing with certificates and signing as the Java Applet.
  • As a developer you need a web server to put all your game's resources, we don't know any portal which accepts JNLP games yet.
  • Java Webstart Cache and Log files are difficult to find on user's machine.


Getdown is a custom solution made by Three Rings in order to replace Java Web Start technology due to its limitations, as it is explained on Getdown's project Wiki. We lack experience and information about this solution, so the pros/cons section could be a bit empty.


  • Open source, that means you know what is happening, and you can collaborate, something impossible with Java Web Start.
  • Working examples of mmo games like Sprial Knights from Three Rigns and Tribal Trouble 2 from Oddlabs.


  • It is custom made. That means, as a developer you have to be aware that if something goes wrong you may have no support (note the conditional). But can't say it is really a cons because with Java Web Start you don't have any support at all from Oracle's team.


  1. Altitude Game -
  2. GameJolt -
  3. Games4j -
  4. Getdown -
  5. Java Plug-In Technology -
  6. Minecraft -
  7. Oddlabs -
  8. Pack200 -
  9. Puppy Games -
  10. Revenge of the Titans -
  11. Sprial Knights -
  12. Steam -
  13. Three Rings -
  14. LWJGL Wiki -

UPDATE: added link to LWJGL wiki page about how to distribute LWJGL Java Applications (most of them applies for Java Applications in general)

VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)

Games as Applets 2

Talking with kappaOne, one of the LWJGL developers, he pointed us that our applet solution has one problem. When js is disabled or it has failed to load, then the applet tag is not written, then the game is not loaded.

In order to fix this problem, we adopted part of his solution. He always creates the applet tag for the game and then hides it using js. If for some reason js fails, then the applet starts automatically.

The new html needed looks like this:


<div id="applet" class="applet" align="center">
	<applet id="gameApplet" width="800" height="600" code="" archive="">
		<param name="jnlp_href" value="" >

And this is the modified js with a merge between his solution and ours:


var width="800";
var height="600";
var jnlp_href="";
var screenshotUrl="";
var appletTag;

var requiredVersion = '1.6.0_10+'
var attributes = { code:'',  width:width, height:height} ; 
var parameters = {jnlp_href: jnlp_href}; 


function hideApplet(){
	var appletbox=document.getElementById('applet');
		appletTag = appletbox.innerHTML;

	if (navigator.appName == 'Microsoft Internet Explorer') {
		var params = "";
		var p = appletbox.getElementsByTagName("PARAM");
		for(var i=0; i < p.length; i++) {
			params += p[i].outerHTML;
		appletTag = appletTag.replace("</APPLET>", params+"</APPLET>");

	var isRequiredVersion = deployJava.versionCheck(requiredVersion);
	var text = ""
	var callback = ""

	if (isRequiredVersion) {
		text = "Click to play"
		callback = "showApplet()"
	} else {
		text = "You don't have java plugin enabled, click to install"
		callback = "installJava(\'" + requiredVersion + "\')"

	// adds the screenshot inside the applet div
	var screenshotDivHtml = "<div id=\"screenshot\" class=\"play\" onclick=\""+callback+"\" style=\"width:"+width+"px; height:"+height+"px;\">";
	screenshotDivHtml += "<span>"+text+"</span>";
	screenshotDivHtml += "<img id=\"screenshotImage\" src=\""+screenshotUrl+"\" alt=\""+text+"\" width=\""+width+"px\" height=\""+height+"px\">"+"</img>";
	screenshotDivHtml += "</div>";


function showApplet(){
	var appletbox=document.getElementById('applet');
	appletbox.innerHTML = appletTag;

function installJava(version) { 

You can see a working example here.

Thats all.

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)

Games as Applets

As you may know, we are publishing our games in two formats, Applets and Webstart. Applets works in a similar fashion as a Unity or Flash applications does, you open the web page and the game loads inside it. Webstart applications starts as a desktop application, outside the browser.

In this post we will explain how we deal with Java Applets. One thing we didn't like about applets is that they starts as soon as you visit the page, sometimes you want to visit a game page only to see some information or read comments, etc.

We created a workaround for that, it consists in showing a game's screenshot with a text "click to play" and whenever a player clicks on it, the game is started.


Our solution consist in a css with the styles to show the screenshot with the text and a javascript with the logic to change the screenshot with the Java Applet.

First we have styles to show the text over the screenshot and highlight it whenever the user moves the mouse over it.


.play {

.play span {
	color: white;
	font-size: 80px;
	text-align: center;

.play:hover span {
	color: white;
	text-align: center;

Then, we have some javascript to create the screenshot div dynamically, and to replace it with the applet tag when the user clicks on it, or send the user to install the needed version of Java if he hasn't installed yet.


	var requiredVersion = '1.6.0_10+'
	var width = "640"
	var height = "480"
	var screenshotUrl = "floatingislands03.jpg"

	var url = "launch-applet.jnlp";
	var attributes = { code:'org.newdawn.slick.AppletGameContainer',  width:width, height:height} ; 
	var parameters = {jnlp_href: url}; 

	var isRequiredVersion = deployJava.versionCheck(requiredVersion);
	var text = ""
	var callback = ""

	if (isRequiredVersion) {
		text = "Click to play"
		callback = "startGame()"
	} else {
		text = "Click to install Java"
		callback = "installJava()"

	var screenshotDivHtml = "
"; screenshotDivHtml += ""+text+""; screenshotDivHtml += "\""+text+"\""+""; screenshotDivHtml += "
"; var appletElement = document.getElementById('applet'); appletElement.innerHTML += screenshotDivHtml; function startGame() { var screenshotElement = document.getElementById('screenshot'); var appletElement = document.getElementById('applet'); appletElement.removeChild(screenshotElement); var oldwrite = document.write; var newHtml = ''; document.write = function (str) { newHtml += str; } deployJava.writeAppletTag(attributes, parameters); document.write = oldwrite; var realAppletElement = document.getElementById('realApplet') realAppletElement.innerHTML = newHtml } function installJava() { deployJava.installJRE(requiredVersion); }

Also, we will need to add two divs to the html to make the javascript to work.



That's all, if you want to take a look at a working example, click here.

VN:F [1.9.22_1171]
Rating: 5.0/5 (2 votes cast)

Signing JARs for Applet and Webstart

We are developing our games using Java and deploying them as Applets and Webstart applications.

By default, applications launched with Java Webstart or as an Applet run in a restricted environment. We are using some technologies which require unrestricted access like Lwjgl, Jinput and custom ClassLoaders. In order to have access to these features, every jar must be signed with a certificate.

Once the jars have been downloaded on the client machine and the signature is validated, the user is requested whether he trust or not the provider of the certificate and if he wants to accept it permanently.

In the beginning, one option is to generate a new certificate every time we sign the jars of an application but this means that although the user might have accepted a certificate permanently, he will have to accept the new one.

A better option is to generate a certificate once and use it every time we sign an application, so that whenever the user accepts our certificate permanently he won’t be bothered again.

A way to create a certificate and manually sign an application with it is explained at Sun's Java Documentation.

In our case, we are using maven as our build tool with maven-webstart-plugin to automatically sign our jars. This plugin allow us to use both options.

In order to easily choose between them, we configure the plugin using properties instead of fixed values, so we can override them with profiles. Using the default values of these properties, the plugin generates a new certificate each time.
If we want to make a public build, we activate a maven profile overriding these properties to use an existent certificate used by all of our applications.

Here are some snippets of our configuration files:

pom.xml - maven-webstart-plugin configuration


		<!-- default values if gen is true -->



We use our company name as a prefix for the property keys in order to have a common scope when setting the values.

pom.xml - default values

	<!-- Properties for keystore generation  -->

settings.xml - profile declaration


In order to build an application for deployment, you can activate this profile from the command line using:

mvn package -PuseDeploymentCertificate

If you have any questions leave a comment.

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)