Part 1 of this series appeared in the August issue of Java Developer's Journal (Vol. 8, issue 8).
JDJ: I'd just like to pick up on that 85% portability goal Jeff mentioned earlier. I'm just going on assumptions, but I think if you were developing a title for the PS2, GameCube, and XBox you would attempt to make sure that only the graphics and audio functionality were platform-specific and make the rest of the game as portable as possible. Seventy-five to eighty-five percent portability would therefore seem to be an achievable goal in C/C++, in which case Java has just lost one of its advantages, has it not?
Cas P: Usually I'm even more optimistic than Jeff about something here. I think I can achieve 100% portability. By focusing on a "pure Java platform" like the LWJGL (Lightweight Java Gaming Library), which, once you realize you're coding to the LWJGL Java API, not the underlying OS, you can achieve 100% portability with a little understanding. Technically, we're not "pure Java" according to Sun's definition, but when you look at the face value, what we have is a 100% cross-platform library with 100% open standards. We've got it working without glitches on Linux x86, and the Mac OS X port is coming along very slowly, as our contributor works for CNN and he's rather busy. I expect Alien Flux to run on the Mac once we get the Mac APIs - it won't run perfectly right now because I use only Win32/Linux-specific extensions. You still have to code for each platform, but you do it in Java, not in C. You have to know that WGL_EXT_swap_interval isn't going to be present on the Mac, and you'll need to call the Mac equivalent.
In Java 3D they've taken a more hide-it-away approach but this is a two-edged sword; on the one hand, programmers don't have to worry about the details of some aspects of cross-platform coding; on the other hand, it relies on the closed and often complex C coding going on in the background.
Let's not forget that killer feature of Java - the ability to download chunks of code, in particular, game mods that don't need to be compiled for every different OS. New weapons, new special effects, dynamic patches...it's all easily possible. If I may make another cloudy prediction here, I don't believe we'll really see the advantages of this until two things come together: ubiquitous broadband and Java on consoles.
Oh, and OpenGL on consoles too...
I'd really rather like to get a hold of the PS3 development team and quiz them about OpenGL support. It won't be too hard to get OpenGL drivers running on PS3. Some GL features might well be very slow, but the ones we all use all the time will be very fast indeed. And, of course, all the PS3 hardware can be exposed by OpenGL extensions. Or perhaps OpenGL 2.0 is the way forward there.
Whatever happens, I'd like to see LWJGL on PlayStation, or even XBox. Did you know that apparently the XBox was developed using OpenGL drivers from Nvidia? They switched to DirectX near the end because, of course, Microsoft didn't want that API in there.
Jeff K: I'm going to stick with 85% because I believe there is a qualitative difference between getting a demo running and a top-quality port of an A-line title. The latter, in my experience, invariably takes advantage of particular characteristics of the hardware platform. Since the hardware's performance characteristics are different, you'll probably want to retune the code. In addition, to be a top title you really want to show off the unique features of that platform. Between those two steps I'm thinking 15% of the code, but I might be overestimating. After all CyberStep did port what I consider to be an A-line title without a huge amount of work.
Designing portable C code is hard, thus it's a significant added expense. Look at poor Bioware with Neverwinter Nights; they were trying to write portable code. They used a "portable" graphics library (OGL) and it still has taken them close to a year to release their second platform (Linux) with their third (Mac OS X) still in development.
In contrast, we've already heard stories here of ports that took under a day in Java (Alien Flux, Jamid, Magicosm) and even when Cyberstep had to port their own native graphics and input bindings for GetAmped, they were done in a month.
I actually designed and maintained a portability layer in C for Crystal Dynamics. While you can write portable C code, it's actually quite difficult and requires a lot of diligence to keep it portable.
You run into all sorts of things you'd never expect. Just a few examples off the top of my head:
1. The size of types are platform-specific (how many bits an int is, etc.), requiring you to write your own type system on top of C.
2. Byte packing and endian conventions are CPU dependent in C, leading to potentially incompatible data. There are some techniques for dealing with this with macros but again it's ugly, extra work, and diligence is required.
3. The number of characters that are significant in an identifier is compiler-specific. (The standard only requires that it is at least 8. I had a compiler once that just truncated all my function names silently. It was 100% ANSI compliant.)
While you can write portable C/C++ code, it's difficult and the results are imperfect. Java has already empirically proved it's far better at this.
JDJ: Are there any features of the Java platform that you believe make it a better choice for games development than other alternatives?
Cas P: It's just easier and that's fundamental - it's easier to make something that works correctly in Java. It's not necessarily easier to make something that works faster, and you can spend a lot of time and hassle finding out how to make things fast enough, but at the end of the day, the IDEs and debugging facilities in Java are absolutely stunning. It's like the difference between those horrible 9-pin Epson dot-matrix printers that infested the planet the last decade and the ink-jet printers of today.
The IDEs available now - we all have our favorites, and I like Eclipse the most - are already more advanced than anything C++ has ever had to offer. This is due to one of the great unsung design wins in Java, which is its built-in debugging facility and, of course, all that lovely reflective information and stack tracing.
Of course, you could say debugging is just papering over the cracks in design but again, if you understand interfaces and inner classes and Java's take on the OO concept, you can pretty much design beautiful, simple, correct, and efficient code without resorting to that ridiculous UML that seems to have become so popular. I've seen projects with only 10 classes specified in UML. I've got hundreds of classes in Alien Flux and I know just about every line in every class! It's just so easy to put it all together.
Shawn K: Simply put, the language features make Java a better choice for games development, which is often the same reasoning it's a better choice for nongaming development. However, much of what many developers consider the big Java gains (exceptions, excellent debugging, runtime analysis, etc.) are available with good C/C++ dev tools; it's just that they don't know about them yet and they cost $$$.
GC (pointer control, illegal memory access), security, and portability are the last stand for Java's benefits in an ever-improving C/C++/C# world. And portability to the game developer is a bit "funny" in this space. For handheld game makers, Java is the clear choice due to portability. For PC/console, it's a different world. You can code C/C++ for a DirectX/PC game and port to the XBox console, so in that respect C/C++ is portable. Java can't do this. You can, however, move your Java game across Linux/PC/Mac OS X nearly. But what is the gain there for the game developer? Linux and Mac are not a compelling game sales platform. If "real" Java was available on consoles, the portability argument becomes a bit stronger.
Jeff K: Code correctness features provide major benefits in productivity and reliability of results. Late binding, which for the first time really makes reusable code work (and refactoring work), again leads to faster development and a more reliable product. Automatic code portability (be it 85% or 100%) is a terrific improvement from previous environments.
Ubiquity - related to portability but slightly different - in this case means that you can come to a new platform without learning how to code it from scratch.
David Y: I'm a big fan of Java, and that's after writing over a million lines of C++ in my career. Basically Java, as a language, offers many advantages over other languages. The quick list is: strongly typed, no pointers, single inheritance + interfaces (versus multiple inheritance), and portability. The JDK is a very rich API with many different sub-APIs that can shorten your development time (Java 2D, ImageIO, Java 3D, XML Parsers, etc.). For game programming specifically, Java is very nice for the organization and class hierarchy of your game system. Games are complex programs and it's that very complexity that begs for a language and platform that facilitates writing good code.
JDJ: Following on from that last question, what features are missing from the API that are essential (or would just make life easier) for games dev?
Cas P: I'd like to see something very like the LWJGL ratified into a J2ME profile of some sort. It does what it says on the tin after all and, indeed, does very little beyond providing what a games developer needs to get down and dirty with drivers. We've got a vector maths API in there but really this should have been part of the standard J2SE distribution by now. More generically than LWJGL, I'd like to see OpenGL become part of J2SE (although, see next answer, I'd like to see J2SE phased out). And OpenAL. OpenAL deserves support, lots of support.
If we could stray a little beyond the realms of purely API additions, I'd also rather like to see typedefs in Java. I noticed this problem when we were using ints as pointers in our LWJGL library. It's very easy to treat an int like an int, and add 1 to it and so on (kerassshhh!), not to mention a bit of trouble with overloading method signatures that take enums and ints. We'd really like to have been able to typedef it and make it completely opaque but without the overhead of an object.
One reason typedefs are missing from Java is there's a large crowd of people who would like to think that Java is the only language that exists - the pure Java crowd. At the end of the day, people who are doing some of the more esoteric and interesting things in Java end up having to talk to the rest of the world in the same way the rest of the world is written - in C and machine code.
Then there's this other group of people who think that Java was designed for some purpose and that purpose shouldn't change over time. They largely overlap, but there's another group of people who want to see Java become ubiquitous, and who think there's no reason why you couldn't use Java to do systems programming. Sometimes this group even manages to overlap one or both of the other two! What's needed here is a thawing of the ice, a relaxation of principles. We need to realize that without some pretty serious evolution in the near term, Java will lose some momentum to languages that are evolving in parallel. You can already see people deserting to C# because it's got some feature or other that's missing from Java. It's not a significant number yet because of all the other strings attached, but it'll only grow if we let the language Nazis and purists bicker all day long about why we can't have enums or const. enums and const mean something new - something that can't easily be expressed in the Java platform now. Sure, there are workarounds - define typesafe enum classes or make getter interfaces - but these are large, ugly, clunky workarounds, when we all know that one of the most important fundamental design goals of a computer programming language is to get what you want done using a grammar that is concise, efficient, and easy to
understand. A one-line enum definition is far easier to understand and maintain than 40 lines of inner classes defining a few typesafe enums.
I'd like to programmatically query capabilities of the VM and set them at runtime. I'd especially like to be able to query for and turn on incremental and concurrent collection and adjust heap size min/maxes, and I'd really like to be able to specify a millisecond-resolution throttle on concurrent collection activity and ask it to make an incremental collection at a specific point in time, during a SwapBuffers. This is pretty important. I do other things besides games with Java - I'm doing something for Abu Dhabi TV right now using the LWJGL; they need a caption-generation system. Unfortunately, as it's live TV I'm not allowed to skip a single frame ever. It's pretty scary having to worry about GC occurring. And it's very noticeable when it does.
Shawn K: Well, I would like to refer this question to the JGP (Java Games Profile) documents of the last two years. They say it all.
Jeff K: You can kind of just iterate down the list of DX features and check off what we don't have yet...things like Polled Controller Support, a standard way of hitting the rendering layer of 3D that includes cross-platform shader support and the ability to drop down to C code and do calls to platform-specific extensions, better game-networking support (a la DirectPlay), a way to get an environment up without pulling in all of the unneeded window manager stuff, better audio support, and some fixes/improvement to 2D (e.g., better transparency support).
This last one isn't really an API but a language "nice to have": better support for efficient bit and byte twiddling.
Cas P: Talking of better audio support - we could do with Ogg Vorbis getting into the API somewhere. I think, as it is, the transparency support in Java 2D is fine; it's just not really well suited to the underlying graphics APIs. Maybe a shift toward an OpenGL-like approach to the Java rendering APIs is what's needed - designed for hardware acceleration but not a requirement; 2D and 3D done with the same API. There's a lot of stuff in the 2D APIs that is really, really good. Java's font rendering is superb (although it needs Cleartype rendering, and soon).
David Y: This is a tough one. Sun doesn't have a "Game API," so the question would have to apply to the platform and language. Structs would, of course, be very helpful in this regard since it allows us to communicate more effectively with lower-level APIs like OpenGL. Another one would be more control over those things that affect our ability to render a consistent frame rate. To me this means things like:
Part 3 of this discussion will continue in the October issue of JDJ.
- Finer grain control over threading
- Higher resolution timer (which we sort of have in Java 3D 1.3)
- A much more efficient mechanism to get inputs (mouse, keyboard) because having it come through windows -> AWT -> Swing -> component -> gamesystem is awful and laggy and unpredictable
- Improved profiling
- Improved integration with JavaSound (i.e., MP3, etc.) with hardware streaming, midi, and synth - current sound uses too much CPU
- Finally, background file loading streams where we can more tightly control IO speed and CPU
The players are:
Jason R. Briggs: Java Developer's Journal contributing editor and your host.
Gerardo Dada: Metrowerks' product manager for CodeWarrior Wireless Studio.
Erik Duijs: Former musician/engineer/producer with a (games) programming passion, now an IT consultant. Author of the Java Emulation Framework (JEF) and CottAGE.
Shawn Kendall: Developed Java and Java 3D-based game technology demos for Full Sail, Sun Microsystems, and I.M.I. In 2002 founded Immediate Mode Interactive, LLC, a game technology company (www.imilabs.com).
Jeff Kesselman: Architect for game technologies, Advanced Software Technologies Group at Sun. He co-wrote Java Platform Performance: Strategies and Tactics.
Chris Melissinos: Sun's chief gaming officer and responsible for driving an industry-wide movement toward Java technology-based game development.
Caspian Rychlik-Prince: An IT consultant in the UK, who for the last 10 years has specialized in client/server systems with RDBMS back ends. He has just released a new game, Alien Flux.
Doug Twilleager: Chief architect of the Java Games Initiative at Sun Microsystems and one of the architects of Java 3D.
David Yazel: VP of software development of trading systems and portfolio management systems and a games developer for (and founder of) the Magicosm project (a 100% Java-based MMORPG).
About The Author
Jason R. Briggs is a Java programmer and development manager for a wireless technology company, based in Auckland, New Zealand. He is also a contributing editor of Java Developer's Journal.