This article is from the upcoming issue of The Cursor: Game Developer Life
The intended audience is game programmers and executives weighing the values and risks of Java development.
(c) 1997 by Dov Jacobson and Steve Capell of Big Fun

 

Java for Games?

What is Java?

Great languages arise from great visions. Smalltalk unveiled the concept of object-orientation. LISP revels in recursion. C is Kernigan & Ritchie's vision of elegant minimalism. FORTH invented the tinkertoy brilliance of threaded interpretation.

Java is unusual. It has a great vision, but that vision goes beyond a sense of language aesthetics. Java was created to support the mantra of Sun corporation: The Network is the Computer.

 

In a tightly interactive network, the resources of your computer, (data, bandwidth, CPU cycles, peripherals, …and even you) are shared with similar resources throughout the system. Interesting perspective for an organizational network of workstations, (an engineering shop or an animation studio) like Sun was talking about in the 80's. But now the motto takes on greater depth as we watch all the world's networks fuse into the Internet.

 

Around the world, all the different species of computers are interlinking. It becomes important to find a way for them all to work together. HTML was a start, a way to share some simple data. But as we know, the exciting part of computers is not viewing screens, but playing software. How can all these different computers share functional code?

Java was created to be a universal computer language. This is a fairly impossible goal, but Java has a good plan: The mechanism by which Java makes itself machine-independent is by inventing an ideal CPU. Java compilers create "machine code" for this CPU. Java Interpreters are "virtual machines", that simulate the well-defined behavior of the theoretical Java Machine.

 

This strategy is hardly unique. The first 8088 IBM-PC in 1981, arrived with two competing operating systems. One was based on P-code, a universal machine language from university theorists. The other was a quick-and-dirty mess called DOS from a little company in Seattle. DOS was considered a temporary expedient while we waited for the ideal P-system to mature. But something went wrong and we still are living with that temporary system.

 

That same Seattle company has its own vision of the Internet, a vision that collides head-on with Sun's worldwide network of diverse computers each with special strengths but able to communicate with a common language. The conflicting vision from Redmond is a world of networked computers all running WindowsNT.

 

What's in it for me?

 

The web

It is easy to see why an email system or a stock-trading program would be good candidates for JAVA development. Interoperability and connectivity are critical in such serious applications. But games? Why would you even consider putting away the latest release of DirectX and loading up the JDK?

 

Java makes your game a native-born citizen of the Web. You pay a lot for this, as we will see. But if you are on the Web, it is a whole new world:

 

Anyone, anywhere, can immediately run your game. Call up a stranger and tell him your URL. A minute later, you hear your own game's intro music coming back across the phone. You schedule matches in Greenwich Mean Time because the players are sprinkled across the globe.

 

Not just geeks. Anyone who can click a browser can start your game. No explicit downloading, installation and compatibility issues¾ it is just there. This is especially valuable if your intended audience is beyond the hard-core 13-35 male gamers.

 

This new Webcentric world is extremely friendly to game updates and patches. These can happen invisibly to the player. A game which can readily and transparently update itself is a very new thing. It leads inevitably to a new vision of the relationship between player and developer.

 

The "Network is Computer" vision comes to life in Java's networking library which not only makes connectivity easy, it makes it a snap to read a file anywhere in the world by its URL and even to spread out the application across multiple machines with remote procedure calls!

 

And, of course, Java also gives you, for free, cross-platform compatibility. You write code once, and it runs in Windows, runs on Macs, runs under Unix. (In theory. Your mileage may vary, as the actual implementations on various platforms are at different stages of reality.)

 

Though the market share of minor OS's is small, they are very underserved game markets. Interoperability and web delivery makes it easy and cheap to penetrate these obscure markets. In fact, the vendor never needs to know what hardware his customers use.

 

And we can soon expect machines on the Web which only run Java! WebTV is the leading example of the upcoming generations of Internet appliance. These TV set-top (or set-integrated) boxes will be the Internet equivalent of the game console. They reside in the living-room and are associated with family play, not work. And they will have native architectures which are neither open nor uniform. They will be addressable only as Java machines. In fact, many people expect these to be Java machines at the chip level - using special Java CPUs now in development.

 

A Sturdy Modern Language

Beyond the overriding global interconnected vision, there is a more modest set of arguments

for using Java.

 

Java is a more evolved language than C++. Like C++, it inherits much of its syntax from C. But while C++ is clearly the product of grafting object oriented mechanisms on top of a simple procedural language, Java feels more integrated, Object Oriented from the ground up, and unlike C++ it does not attempt to be a true superset of any other language.

 

Java's designers worked hard to maintain a very solid multithreaded environment where it is easy and natural to treat parallel tasks as independent processes. All the tools of a real-time system are provided. In particular, data contention safeguards allow two threads to share common data objects without collision.

 

Another Java feature, is garbage collection. Memory is recycled when its data is outdated. This feature is typically overlooked by language creators because it isn't pretty or elegant and can be considered outside the responsibility of the language. The Java designers are clearly willing to get their hands dirty.

 

Designers usually are loathe to allow anything to corrupt the beauty of their pattern. But Java's creators have been willing to make compromises: For instance, they disallowed operator overloading, (the practice of redefining the meaning of symbols like + or *). This was one of C++'s most sexy features, although easily abused. But operator overloading is very attractive in string manipulation. Compare bathhouse="bath"+"house" with bathhouse=strcat("bath","house") . So an exception was made for strings!

 

This is disturbing to a purist, but of great practical utility to a code-cutting professional. This attitude is seen throughout the language where the troublesome beauty of exotic constructs is chopped away in the name of getting the job done. Multiple-inheritance? Replaced by the simpler interface mechanism.

 

In Java you bundle your code into packages which help you organize your classes in a very lucid way. The programmer is supported with many other features - such as auto-documentation and the standard archiving and compression that makes Web delivery less of a nightmare.

 

Safety Features

 

Like a Volvo station wagon, Java emphasizes safety rather than speed. This is not very appealing to the typical game developer, whose cubicle usually has posters of Ferraris. (But of course the typical developer can be found under that poster deep into the night, under a pile of Mountain Dew cans, chasing elusive bugs while the company management explains away another deadline slippage.)

 

Since you can't remove the safety features, consider their value.

 

By far, the bulk of these features are meant to protect the user and his computer from you and your software. They present hideous obstacles to development. But they are a great boon to distribution.

 

We live in a world that fears viruses and Trojan Horses and buggy code. Nothing is more feared that an alien executable coming straight off the Web. Players are far more likely to introduce strange software onto their computer if it comes wrapped in the prophylactic protection of Java. Like the lady says: No glove, no love.

 

Some features enforce clean code and actually protect the programmer from bugs, both by reporting errors and by simply making some errors impossible to code. Every C programmer has lost days of his life chasing the random havoc of a pointer error. In Java this will never happen. There are no pointer errors because there are no pointers. Similarly, Java will prevent you from writing past the edge of an array. To get a memory write bug you have to practically do it on purpose.

 

Even then, Java will save you from yourself by rigidly enforcing type definitions. It's nice to have the seatbelts and airbags, but of course, they come with a price.

 

 

What will it cost me?

 

Performance

 

Java stands out as a new language with plenty of potential to make life easier for software developers, but is it a good choice for games? Games have traditionally pushed personal computers to their performance limits, and Java has many performance limiting aspects that you don’t find in C, C++, and assembly language. Whether or not your game requires more oomph than Java can muster depends on many factors.

 

Perhaps the most influential factor in Java performance is the fact that it is an interpreted language. While bytecodes in the Java virtual machine language are similar to the instructions used by standard CPUs, they are executed by a Java virtual machine instead of a CPU. This process requires many native machine instructions per bytecode, which means that your code will run at a fraction of the speed it would have run if written in a compiled language and run on a PC.

 

But good news is on the way. Modern browsers support Just-in-Time (JIT) compilation, a technique in which the Java virtual machine compiles methods into native machine code on demand. Whenever a method is called, if it has not yet been compiled, it is compiled then and there. Netscape Navigator 4.0 currently supports JIT compilation, and other browsers are sure to follow.

 

While JIT compilation gives your programs the potential to run at speeds that approach their C language counterparts, it is important to consider other factors that could dampen your Java performance. Unlike C and C++, in Java it is impossible for a program to use an object as if it belonged to a different class, unless the classes are closely related according to Java's rules. In order to enforce this , the runtime environment must perform a check whenever an object is cast to one of its subclasses. This may not seem too important but abstract data types tend to be generalized to the base class for all objects, which means they have to be cast when retrieved. Similarly, C and C++ offer no bounds checking on array accesses, while Java is careful not to step outside array boundaries, increasing the cost of every access to an array element.

 

Games have ever increasing graphics demands, from copying large amounts of graphics data for smooth animation to fancy texture-mapped 3D. If the graphics are created without the aid of special hardware, there is almost always tightly woven hand-coded assembly language in critical areas of the code. Although it is not difficult to hand-code Java bytecodes, the results cannot compare to native assembly language: the Java virtual machine still requires another level of translation before execution. And there is the extra cost of array bounds checking. Your best bet is to use the Java libraries, which combine native library code with driver support for graphics hardware to provide good performance. Currently the supported operations include copying of bitmap data between images and to the screen, which can be used to develop graphics based on 2D techniques. The world of 3D is not so promising. Java has yet to provide standard support for 3D graphics, so the options are limited. Microsoft will be providing Java support for DirectX in Internet Explorer 4.0 but its lack of standardization among browsers would severely limit your market. There’s no question that 3D support, including use of available hardware, will eventually be part of the standard Java libraries, but it may be a while yet.

 

The Sandbox

 

From the developer's point of view, Java applet security restrictions can cause a lot of suffering. . The primary goal of the Java security model is to protect users of the web from hostile applets. In general, Java applets are restricted to run within a security "sandbox", in which a variety of library methods are inaccessible. For example, applets in the sandbox cannot write to the user's disk, or communicate with other computers on the Internet or access things like the MIDI device ( common features in a game). Working around the sandbox restrictions can result in horrible solutions to otherwise simple problems. Applets can get out of the sandbox using digital signatures, which allow the user to be sure of the identity of the provider of the applet. If the user trusts the provider then security restrictions can be loosened.

 

Unfortunately, the security model put forth by Sun in Java version 1.1 was not satisfactory, so Netscape and Microsoft have scrambled to come up with a more robust security model. Er, two robust security models. At least in the short run, applets that need to run without strong security restrictions will have to include custom source code and packaging for each security model. The Netscape security model requires code to make calls to a special API, and to be digitally signed and packaged in a JAR archive file. The Microsoft security model does not require any changes to source code but does require special signing and packaging in a CAB archive file.

 

Growing Pains

 

An aspect of using Java that could easily be overlooked is the headache associated with using nascent technology. If you are used to integrated environments that have all imaginable features and run like a well oiled machine, the Java tools can take some getting used to. They tend to be slower, buggier, and have fewer features than their C++ counterparts. On the positive side, the speedy Symantec Café compiler slices through code at more than 500 lines per second on a P133, making full compiles of medium size codebases quite snappy. Its a good thing too, because the dependency analysis is not always correct.

 

Another thorn in the developer’s side is the constant evolution of the Java standard libraries. The changes between versions 1.0 and 1.1 were significant, especially in the Abstract Windowing Toolkit (AWT), and since most browsers still only support Java 1.0, porting must be timed carefully. A saving grace is Java’s deprecation mechanism, which allows classes, fields, and methods to be labeled in the source code as outdated, presumably replaced by newer entities. The compiler uses this information to tag the class file, and issue warnings when deprecated entities are used. Thus changes in the Java libraries do not cause your favorite methods to be removed. Some of them will become deprecated, but there is no tremendous hurry to replace them. Even in the AWT shake-up between versions 1.0 and 1.1, backward compatibility was maintained so developers can postpone the architectural overhaul required to use the new AWT in the way it is meant to be used.

 

 

Learning Curve

 

Although learning Java is made easier by its similarity to C++ (a consideration that was apparently built into the design), there are a variety of new concepts. Unlike most C++ programs, Java programs are intrinsically multithreaded; threads are built into the language and a few threads are already running before your applet code is even run. You can limit the degree to which your program uses threads, but Java encourages you to embrace these useful objects and it quickly becomes burdensome to avoid them. For example, sockets in version 1.0 had undesirable blocking behavior that could only be worked around by dedicating a thread to read data from the socket. As soon as threads are in the picture, it becomes an important issue to avoid situations in which multiple threads simultaneously (and erroneously) manipulate the same object. Java provides a mechanism, the synchronize keyword, for making a method inaccessible to more than one thread at a time, but its not a no-brainer to get used to using it. Incorrect usage of synchronization can fail to provide exclusive access to all critical sections of an object or cause deadlock. Other issues of learning overhead generally follow from the need to learn a new set of libraries including user interface components (the AWT), basic data structures (of which there are few in standard Java), string operations, etc.

 

Do I do it?

Don't even consider Java unless a commitment to the Web is demanded by your marketing plan and central to your game design. Be certain that it is the Web you need, not just the Internet. Simple Internet connectivity can be gained more easily with other languages. And hypertext hype, electronic delivery and game-site links can all exist in a Web marketing scheme without a Java product.

Don't even consider Java if your game is an action game, or a 3D pixel-fest or any other genre where you must compete in graphic performance. The standards will always be set by games whose technology Java cannot begin to approach.

But if your game vision is about a shared world more than a fast or fancy one¾ if your marketing plan is totally devoted to the World-Wide Web¾ if you are eroding the line between website and gamefield¾ if you have a vision for a new kind of game where the strengths of the Web are important and its handicaps are tolerable¾ if you are ready to break with what you (and all your peers) know will work and look for something new¾ then Java is a good vehicle for your journey.