Java "games"

2001.10.31

A few months ago I had the chance to build a prototype online game. The game concept was based around an IRC-like text chat that connected to a dedicated game server. Since the game wasn’t intended to use fancy graphics, I elected to implement the client in Java. Like most of you, I grew up steeped in C and assembly; the last time I wrote a game in an interpreted language was when I wrote a trivia game in BASIC for the Commodore 64. So the notion of programming a game in an interpreted language rankled a little. Nevertheless, the experience was illuminating. I finally had a chance to cut through the hype and learn what Java game programming was really like.

The fantastic political infighting between Microsoft and Sun has resulted in two divergent Java codebases, each one with its own specifications and API. The technical aspects and the legal aspects of this conflict are well documented. Unfortunately, if your goal is to create a game that runs on the widest possible variety of browsers, you have to simultaneously ignore the advice of both companies and develop toward the least common denominator of the two.

Microsoft browsers including 4.0 and later include what they refer to as version 1.1.4 of Java. This version lacks some 1.1.x remote-procedure call classes, which you don’t need to make a game. Microsoft’s Java codebase seems to have forked at 1.1.4 from Sun’s. Sun continued JDK development through version 1.2 and version 1.3, later renamed to Java 2. So, while Sun is heavily marketing the download of Java 2 on java.sun.com, you cannot assume that it’s installed on every user’s machine. Microsoft has removed Java entirely from Windows XP. The first time Java is required, Windows XP offers to download it.

Minor version number changes in the Sun JDK releases are intended to be bug-fix releases. Therefore, code compiled with Sun’s JDK version 1.1.8 ostensibly works on any virtual machine versioned 1.1, but Sun’s release notes for that JDK don’t commit to that sort of backward compatibility.

Bottom line: if you want to write an Java application that runs with most Web browsers, use Sun’s JDK 1.1.8. If you don’t use any 1.1-specific features, you can use it to create an app that works with Netscape 3.0 and later as well as Internet Explorer 4.0 and later. Sun claims that JDK 1.1.8 is "deprecated." You’ll hear the word "deprecated" a lot when you’re working with Java. The true meaning of "deprecated" is "we’ve written a newer API that does basically the same thing as the older API, and we wish you’d use it without regard to the current installed base." Since it’s the only JDK that works with the majority of installed browsers, you might grab it in case it goes bye-bye. Sun apparently has no problem with dropping "deprecated" JDKs; if you want JDK 1.0.2, for example, you’ll have to ignore the scary language about it being unsupported.

I took a brief look at Visual J++. Don’t bother. The IDE I settled on was NetBeans 3.2, which you can download from www.netbeans.org. The IDE itself is unfortunately written in Java, and it makes my 700 MHz/256 MB machine creak. Fortunately, it’s free. It took some fussing in the Project Settings window in NetBeans to convince it that I really wanted to compile and debug using JDK version 1.1.8; NetBeans practically begs you to use the latest JDK. Since it’s written in Java, the NetBeans IDE tends to fall asleep periodically while the IDE does garbage collection. As far as I can tell there’s no way to force a Java program to garbage collect. There are several Java environment tweaks you can use to reduce this problem, but it still happens often.

There are two generic Java classes for handling GUI things like scrollbars, text menus, and buttons. The oldest and least advanced is called AWT, or Advanced Windowing Toolkit. The most advanced and most recent is called Swing. Swing supports colored text, text with non-trivial formatting, and more complex graphical layouts. Swing version 1.0.2 was introduced to be compatible with Java 1.1, and Swing version 1.1 was introduced with Java 2, but the Swing classes are not installed by default with MSIE. In other words, don’t use Swing; use the less advanced Advanced Windowing Toolkit.

Learning Java and writing Java code turned out to be pretty easy. I would guess that a decent C++ programmer could become reasonably proficient in Java in two weeks. If you want to create a string, you create a java.lang.String object. If you want to extract a character from it, you use the charAt() method. If you want to compare it to another string, you use the compareTo() method. If you want to see if it’s the same as another string without regard to case, you use the equalsIgnoreCase() method. You get the idea. Everything in Java is very objecty and very encapsulated, and if you want to modify a class you're supposed to subclass it without thinking twice. You may not muck with strings or other data structures directly. If you like looking at memory dumps and figuring out why your registers are getting trashed, you may well detest Java. You have to trust your IDE and your compiler when working with Java. There exists a gdb-like command-line debugger in the JDK, but it’s (you guessed it) deprecated.

Java strongly encourages the dynamic creation and destruction of C++-like objects. Stuff like zone memory management is not possible with Java. Even with my tiny chat app, Java periodically took time to garbage collect; the app just hangs for a second or two while this occurs. Try to imagine playing Java Quake, and a rocket’s coming toward you... and a little hourglass comes up saying, "Garbage collecting... please wait."

One of the early decisions I had to make about my app was whether to sign it. Java enforces many security restrictions on applications running on the virtual machine. Every time you pop up a Java window, there’ll be a little warning that says the window is an applet window and the user shouldn’t trust it. Warning! This game is not to be trusted! Basically, if you want to put a dialog box up without warnings or write to the filesystem or open up a socket to an arbitrary IP, you’ll need to digitally sign your app and get user permission before running it. The signature and packaging process is different for Netscape and Internet Explorer. Netscape wants signed .jar files, MSIE wants signed .cab files. If you want or need to sign your applet, the cheapest signature authority is Thawte.

Your unsigned Java app may open and close network sockets, but unless you’ve signed your app and the user has granted permission, these sockets may only be opened to the IP address from where the Java app was downloaded. So it’s possible to write an unsigned Java chat game, with the caveat that the IP address of the Web server must be the same IP address as the game server. You can either have one machine with an HTTP server and your game server running on different ports, or you can configure a firewall or redirector to handle this port redirection for you.

Very well, I made a Java game client that seemed to work on Internet Explorer 5.5. On a whim I tried loading it on my Windows 98 laptop. Surprise: one of my dialog boxes, originally neatly centered on the display, exploded to cover the whole screen. My AWT code was behaving differently from browser version to browser version. Of all the unpleasant surprises of Java game development, the nastiest one is this: every version of every browser is a different platform. Depend on it: whatever Java application you write will work differently (or most likely, not work at all) if you upgrade or downgrade or sidegrade the browser. The only sure-fire way to make sure your Java app works in all the various environments to test on them.

The best way I found of testing in multiple browser environments is through a really cool emulator called VMware. This is a very nice, fast, stable PC emulator. I set up four emulated PCs, each with different OSes and browsers on them, and I checked my Java app on each of them. I borrowed someone's Mac in order to test against the Mac versions.

Is Java useful for games? I would say that it’s less useful than your boss thinks it is. In my opinion, it’s only useful for games that are small, online, turn-based, low-graphics games. In other words, it’s great for creating unprofitable games.