The Joys and Perils of Mass-Market Java Games

From summer of 2004 to summer of 2006 I worked on an on-line casino with a Swing-based GUI. The project was a great development adventure – filled both with incredible joy of creation and terrible agony of support. Here is a list of my positive and negative experiences from using Java/Swing for on-line games.

Parts of this text have been sleeping on my hard drive for a long time, actually, and you will notice that some references have been published on SwingWiki a year ago – but the article simply could not be wrapped till the project ended.

First, let me give a very rough and short introduction into the world of on-line gam(bl)ing for those that have never stumbled upon it. Casino games are typically 30-40 megabyte applications that you can download from the Net or order on a CD. The applications are are basically just a very thin front end as far as the application logic is concerned. To prevent fraud, all games are executed on the server, which handles game logic, accounting and connects to payment providers. The shop window of on-line casinos is (obviously) a web site that enables punters to register, pay in money, request payouts and check up on how other players are doing.

Our clients insisted on having both the server and GUI client developed in Java, and wanted a minimal client that could be easily downloaded – none of that 40 MB elephant stuff. Though I’ve spent a lot of time developing Swing applications, most of those were business tools where layout and colours did not make much of a difference. In games however, specially in those that should be addictive, eye candy is everything. At first, I was a bit puzzled with the request to have everything done in Java, but I was open-minded about giving it a try.

Benefits of the Java on client

Java was the only logical choice as the server platform, so using it both on the client made our life much easier. We could “embed? a gaming server in the GUI application and test everything locally from Eclipse, without much packaging and copying, or connecting to servers. GUI and the games could run in the same JVM, same debugger, so problems could be solved quicker. Using ClassLoader to fetch images and translations enabled us to use the same client code for development (when the files are in local directories), testing (packed into JARs, but local) and distribution (packed into JARs, fetched over HTTP). GUI team helped test game service objects before the server plumbing was even finished, so both server and client teams benefited greatly from this equation. Enthusiasm was the feeling of the day, as we were, for a change, programming something fun again.

Swing fit the job nicely

Here is a couple of screen shots just to give you a feeling of we were doing. Click on any image to enlarge it.

CrapsLobbyRoulette

SlotKeno

I expected that we would have to do most GUI widgets ourselves, but on the end the only custom code were animated labels (and even that was based on Jlabel). Swing objects, combined with icons, were quite useful for most of the operations. Though you cannot recognise JToggleButton and JButton in the screen shots – those classes control all the action. We used buttons for more/less everything – from push-buttons on the slot machine to cards, coins, and even a digital girl at the roulette table. Turn off the background, lose the border, kill the margin and set icon image(s), and you will have a nice looking object on the screen with all the benefits of flexible Swing event processing. JButtons support separate icons for pressed and disabled states, which came in quite handy. JToggleButton was also quite useful for poker cards – when the users clicked on the card (to change it) image automatically changed, and they could play with it as much as they liked. We just read the button state on the end to see which cards should be changed.

Automatic layout management did a nice job for control/button panels, where things get turned on or off. We did not have to care about positioning and re-positioning buttons during the games, just set their visibility to true or false. It might not sound like much, but this saved us really a lot of time – because the combinations of active/visible buttons for some table games get a bit crazy. However, for most games we had to position elements manually to fit in with the background, but mixing manual positioning (null layout manager) with automatic layout management for control panels did not work as expected. On the end, we just implemented a dummy layout manager that positioned it’s elements manually, and enabled sub-containers to perform automatic layout management.

Antialiasing and transformations were another nice surprise. They are quite decent – so we did not have to implement all fonts as sequences of images (though for some bigger ones this was necessary). This enabled us to use Java labels to display text both on status panels, but also “in images? such as roulette and craps table and on the Keno screen (both with perspective transformations). Another benefit of this was much easier internationalisation – since we could use regular text objects, internationalisation was pretty much out of the box.

Building a HTML-based help system also proved to be quite useful, since we basically re-used the help pages on the server.

Never show a mock-up

Though the next paragraph is not Java related, this story would not be complete without it. Everything was going better than planned and we had the basic server framework, two games and most of the GUI programming for those games done in two months. Very happy with our progress, we organised a demo with some mock-up game layouts (graphic designers were taking their time and did not have proper images ready by then). That’s when I’ve learned, the hard way, that a picture is worth a thousand words. I’ve heard and read that sentence a million times before, like you have just read it, but never really appreciated the truth behind it. All our programming achievements vanished in a second – clients hated the mock-up layouts so much that they wanted to cancel the entire project. I’ve learned a painful lesson that day and swore never, ever, under any circumstances, to show clients a functional prototype again. After two weeks of politics and re-negotiations, the clients agreed to give us another chance. This time, in order not to take any more risks, I asked them to Google for some images they like, and our designers produced very, very similar layouts. This proved to be a good practice for avoiding embarrassment, and I strongly suggest it whenever the visual aspect of your applications should appeal to the client.

Embracing change

First delivery included four games packed in a downloadable application. As project progressed, more games were added, we developed an applet and a ‘free play’ version and the casino went international (translated into eight languages including Japanese). Casino transformed from singleplayer into a multiplayer system, and messaging tools were added to enable punters to chat while losing money. An external messenger was also developed to enable punters to chat while they are not playing. It’s interesting to measure the choice of the client platform by the effort it took to embrace such changes.

Adding multiplayer capabilities mostly affected the server, client application took some minor changes and was extended a bit to allow chatting. So, in that case, client platform choice was more or less neutral.

Using Java for client platform helped significantly for the free play version, since we just had to clean up the “local? game server used for development and use that in the client, so free games could be played without connecting to the normal server. Had we developed the client in any other language, server modifications to allow playing without actually spending money would cut through the core of the system, and probably take months to implement.

Going from a Swing application to an applet also proved to be relatively easy, we just re-factored the main screen and the way application life cycle was controlled.

Messenger was a bit more tricky, since we had to enable punters to minimise it into the system tray, which meant accessing system resources and going outside of the safety model (and compatibility) of a JVM. This was also not a major problem on the end, but we lost a week or so making everything work with JWS.

Internationalisation was relatively simple, as we were using Swing objects for most of the text on the screen.

Not for the mass market

However, not all was that easy. Initially, we used property files for labels and configuration. Property files strictly contain ISO-8859-1 characters, which was unusable for Japanese. Unicode characters can be encoded into property files using a special syntax, but that made the round-trip for correcting translations very painful. On the end, we moved to storing translations into XML files and built a wrapper over them to provide the ResourceBundle interface.

We decided to use Java Web start as a distribution platform, because ‘self-installing’ and support for Windows and Linux were required, and JWS promised to save us from implementing our own incremental upgrade system. This was my greatest disappointment. We had minor problems with JWS straight from the start – occasionally it did not recognise that files were updated on the server, but we modified the packaging scripts to work around that. ActiveX component for Internet explorer could download the JVM along with our application if punters did not have it, but for other browsers (and Linux), this feature did not work. All of that was, more or less, still a minor nuisance. Then, bugs like 5074530 kicked in – on some client systems, JWS would not download the correct JVM. By that time, the sound library relied on 1.4.2 features, but JWS insisted on running the application on 1.4.0 if that was already installed. It took us at least a month to figure out the problem. For some German clients with Windows XP, application simply did not want to start from Internet Explorer, though it worked quite fine from Firefox.

Small differences in Linux/Windows/Mac implementations and JVM versions were a constant source of problems. When 1.5 appeared, it was a nightmare. Due to some strange problem between sound libraries and JVM, we lost synchronisation with sound effects, so Roulette sound had to be turned off for a while, until we found a solution that worked both on 1.4 and 1.5.

Maybe Flash would have been better

On the end, my feelings about Java on-line games are a bit mixed. Using Java as a client development platform certainly has great benefits in terms of 3rd party tool and library support, testing and packaging. Swing did the job – no doubt! We were able to achieve all the bells and whistles that clients asked us to do, probably with more code than in Flash, but on the other hand, we developed the free play application logic with less code.
However, distributing a Java game turned into a nightmare, especially with troubleshooting and supporting all the crazy combinations of systems and software. Write once – run anywhere turned out to be a false promise if you cannot control the exact version (and subversion) of the JVM installed. Bundling a JVM with the software was not an option for our clients, and that still would not solve incremental software updates.

Would I do it again? Don’t think so. For business applications, in a controlled environment, Java does an excellent job. Traders are most concerned about the figures, and they will live a day or two with a GUI error, even longer if you provide them with a workaround. Software environments in companies are more-less consistent, and you know when the platform will be upgraded. With games and Internet-wide distribution, you don’t have that kind of privilege – clients will expect everything to work on all obscure platforms, and players will have a range of different JVM versions with tiny, but painful differences. Next time, I would probably do the GUI in Flash.

I'm Gojko Adzic, author of Impact Mapping and Specification by Example. I'm currently working on 50 Quick Ideas to Improve Your User Stories. To learn about discounts on my books, conferences and workshops, sign up for Impact or follow me on Twitter. Join me at these conferences and workshops:

Specification by Example Workshops

Product Owner Survival Camp

Conference talks and workshops

8 thoughts on “The Joys and Perils of Mass-Market Java Games

  1. Interesting article. I got the pointer from the posting you made on comp.lang.java.gui. Thanks for taking the time to share this.

  2. I developed a time-management system (applet/webstart based), the project is currently leaving its beta phase.

    It was written to stay java-1.1 compatible (yes with all those crazy netscape and microsoft vms), and although it uses a custom lightweight toolkit based on AWT (lwvcl) it was a horrible job.

    We ended up developing complex communication frameworks which took care of all the pitfals of those crapy JVMs and ended up using only very basic features of java like Vector’s and Hashtables (actually non-synchornized self written versions) – but most interaction with the core libs was done via our frameworks.

    However on the other side I am quite a bit proud seeing a MSJVM loading that 900kb beast (its supports plugins, so the main-jar is about 500kb), or waiting 30s till MSJVM’s jit has compiled all the classes on an Athlon800, because it cannot load the application interpreted when running with JIT turned on.
    Man times have changed, if I see my client running on java-1.3 I can’t believe how great even 1.3 is compared to what happened in 1.1 ;)

    lg Clemens

  3. I’m not surprised about the problems you found using Swing for such application; instead I am surprised you end up with it! :)
    Swing is a wonderful toolkit for developing classic GUI applications like editors, browsers etc., but for game developing, even if it apparentely represents a good “shortcut”, it is not by far the best solution.
    Leaving away widgets facilities, with a little more effort, straight Java2D would have been IMHO a more logic approach.

  4. Hi – thanks for the comment but I think that you missed the point. Swing did an excellent job – the trouble we experienced was mainly due to JVM incompatibilities and JWS bugs, nothing to do with GUI widgets.

    Gojko

  5. Great post,
    Agree 100% with “Never show a mock-up”! I’d even go further and say don’t show it to a technical guy too!

    Most of your experiences are quite familiar to me, although I reached slightly different conclusions. I think your approach with Swing was great since you could support i18n features such as BiDi and accessibility rather easily unlike the case if you had chosen Java2D…

    Java Web Start was and is a huge dissapointment to me as well, its better with Java 5 (and has pack200 which is GREAT) but its still buggy. On the bright side I did file quite a few bugs and it seems some work is done for Mustang so hopefully this won’t be as bad with Java 6+.

    I don’t think I’d go with Flash in future projects though Java is moving forward and by the time your next project comes out most of these issues will be solved (others will arise but thats always the problem). There are a few new things since you did your project that would make Java more attractive: Java 5 (and Mustang), Pack200, Matisse etc… I think the true weak spot in Java SE today isn’t Swing, its the deployment problem.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>