Realizing Java's Promises
Looking at Java simply as a programming language, it has nothing special to offer game developers over other object-oriented languages such as Smalltalk or Eiffel. In fact, traditional mud languages such as LPC already provide strong support for building traditional multi-user games. In last month's column, I discussed how the Java virtual machine architecture promises to help game developers rethink the way they develop multi-user Internet games. Java requires some external support, however, in order to realize those promises.
In order to keep state information across time, a game needs to manage some sort of data storage system. Traditionally this is done through a home grown database system or through specially designed flat files. While this works for providing rough object persistence, such systems are proprietary in nature and a nightmare to design complex queries against. With this summer's completion of the JDBC database connectivity standard, Internet games can be enabled to take advantage of the power of relational and object-relational databases.
Another standard that JavaSoft is developing at the same time as JDBC is the Java Remote Method Invocation (RMI) specification. RMI provides an API for calling methods in object instances located on remote servers. For example, the game server can trigger client machines to load instances of the objects stored on those machines. Even though the instances are found on the client machine, they can be treated as if they were on the server machine without writing any socket code.
Being mostly free and requiring a high-degree of portability, multi-user games have traditionally avoided the otherwise ubiquitous relational database as a solution for state persistence issues. Using a third-party database solution in a game ties developers to technologies which may or may not exist on the systems of those using the server. For example, if Tim Hollebeek, the primary developer behind MudOS, were to change the MudOS server to depend on a Sybase backend, he would be making it nearly impossible for everyone who currently uses MudOS to continue using it since most do not have access to any commercial database, much less Sybase specifically.
Another solution might be to write an interface to every potential DBMS that people might use. Assuming he had access to all of these different database engines, he certainly has better things to do with his time. Existing multi-user games have thus avoided this issue by creating custom data storage systems.
In order to bring the power of existing relational databases to game developers, a Java server needs to provide database access in a manner that does not depend on the DBMS being used nor that requires writing different code for every potential DBMS. Java now realizes these needs through the Java Database Connectivity API, JDBC.
Since its inception, Java has actually been a poor vehicle for database access. As a response to this deficiency, JDBC is likely the most important addition to Java since the JDK 1.0 release. It attempts to provide application developers with a SQL-level API that is simple and consistent with the rest of the core Java class libraries. This object model shows the interfaces of JDBC and how they relate (see Figure 1).
Specifically, JDBC defines these interfaces in the java.sql namespace which individual database vendors implement to provide access to a specific database. The only current JDBC implementation is one for the SQL database, though this will change over the summer as the JDBC API is frozen and enters its final approval phase.
Any application written only against the JDBC interfaces using SQL-2 compliant SQL will be portable against any potential DBMS for which an implementation is written. This sort of portability is clearly ideal for game developers who often have no choice with respect to data storage.
Of course, some developers might think requiring a relational backend for a game server to be a bit of overkill. After all, most of game data storage simply involves saving object state information across application instances. As a game developer myself, however, I have found that games do not use complex queries because it is not possible, not because no need for them exists. And a game does not need a full Sybase or Oracle backend in order to work. Simple games can use the lightweight mSQL engine, whereas more complex systems can make use of Postgres95. Both database engines are free for non-commercial use, and Postgres95 is even free for commercial use.
The Potential of RMI
Remote Method Invocation, or RMI, is a specification for allowing Java based object distribution which is currently in a very alpha design stage. While the alpha specification is extremely limited, it is also very promising. The underlying goal behind RMI is to allow object instances to exist anywhere on the Internet and communicate with other object instances simply by making a method call. In addition, actual object references may be passed across Java virtual machine boundaries in order to allow other remote objects to invoke methods in them. All of this requires no socket programming on the part of the developer.
Each class which may exist as a remote object must have its methods defined in a remote interface which it in turn implements. A special Java application called rmigen in turn generates a remote version of the object implementing the same interface. Both client and server ends refer to the interface for making calls without a care for whether it is dealing with the actual object instance or simply a remote reference.
The primary task of most Internet game servers is to listen to a socket and await player connections through clients like telnet, TinyFugue, or Pueblo. Upon making a connection, all of the communication between a client and the game server is handled as strings passed through a socket. RMI completely makes obsolete this function of a game server.
A potential mud would instead start as a web applet for the user. The applet might contain user interface classes that are responsible for displaying game objects. In a simple application, you have a single window which knows how to display room information. In connecting to the game, the applet makes method calls to objects already instantiated in the server process which has been running continuously on the server machine. Though the web applet and server application run on separate machines, they interact as if they were the same process on the same machine.
Unfortunately, RMI is not quite ready for this scale of use. The first alpha release contains many temporary limitations which make building actual production applications impractical. Instead, this release is designed for JavaSoft to get user feedback on the basic design of their system. Future releases of RMI promise to remove these limitations and allow for the potential to become reality.
About the Author
George Reese is the Games & Graphics editor of Java Developer's Journal.