Skip to main content
gamedev.net
🔒 Locked

[java] Game Engine Development in Java?

Started by ShotgunNinja Jan 19, 2010 at 2:34 PM 20 replies 6.1k views
Original Post
ShotgunNinja
ShotgunNinja
Hello everyone, I'm a C++/Java programmer with a couple years of experimental and practical programming experience under my belt, currently attending an engineering college as a freshman. So, what I thought I'd do was, I'd implement yet another 3D game engine in Java. I'm working off of the underlying implementation ideas represented in the Source engine of Half-Life 2, as I am trying to provide some similar features to the ones available from the Source engine. However, I ran into a bit of a snag in terms of running some of the engine mathematics routines, the short version being that "Java is slow, and good game engines are fast." So what I was thinking of doing was using the Java Native Interface to create a side-library in C/C++ which would provide a slightly more efficient solution, such as SSE routines on supporting Intel/AMD architectures, or for platforms without SIMD, just plain old optimized C routines, which still run a bit faster than Java when done correctly. Am I beating a dead horse here, or does this sound feasible? I haven't had the opportunity to perform any real benchmarking on this just yet, but before I try it, are there any outstandingly significant timing issues involved with JNI library support that would make this not work as well as just implementing routines in pure Java? Thanks for any help you can give. ~ "Shotgun Ninja" (name removed) ~ Freshman, Software Engineering ~ Milwaukee School of Engineering
smr
smr
I wouldn't worry about writing a native library until benchmarking has proven to you that it's necessary. The Java implementation of your math routines will undoubtedly be slower than your native versions, but I bet they will be fast enough. Check out jPCT, a Java 3D engine with a 100% software renderer (an OpenGL renderer is also available). The software renderer is very fast and best of all, it's compatible all the way down to Java version 1.1.
AverageJoeSSU
AverageJoeSSU
If you want to contribute something, you may be interested in making a game engine using javafx. there doesnt exist anything like that yet.

We don't support 3d yet but its coming.
------------------------------ redwoodpixel.com
ShotgunNinja
ShotgunNinja
Wow, first off, thanks for the fast replies.

Second, although I haven't explored either of these just yet, JavaFX sounds interesting enough to check out, and I'm definitely going to give jPCT a look-see. Plus, I think it'd be very cool to be the first to implement a JavaFX-based game engine, if what you say is true.

Also, when you say "3D is coming", what do you mean? About how soon should I expect it to be implemented, and what are the plans for it?
Fenrisulvur
Fenrisulvur
Quote:
Original post by ShotgunNinja
However, I ran into a bit of a snag in terms of running some of the engine mathematics routines, the short version being that "Java is slow, and good game engines are fast."

Not quite.

First of all, this depends on the types of routines in question - but overwhelmingly, mathematical programming is 97% high-level optimization, 3% implementation hacks. Writing the same routine in C is an example of an implementation hack.
And secondly, Java is probably the fastest "managed" language out there; but the Java specification is absolutely anal about floating-point accuracy, especially in regards to replicating results across platforms, so Java's Math routines can be slow. If your accuracy requirements aren't so demanding, you can write more efficient routines than Java's Math routines, in Java.

Quote:
Original post by ShotgunNinja
So what I was thinking of doing was using the Java Native Interface to create a side-library in C/C++ which would provide a slightly more efficient solution, such as SSE routines on supporting Intel/AMD architectures

This might work out for you - if you can leverage a specific machine instruction you might gain a significant performance boost. I wouldn't think it worth sacrificing WORA, though.

Quote:
Original post by ShotgunNinja
or for platforms without SIMD, just plain old optimized C routines, which still run a bit faster than Java when done correctly.

This will be a waste of time, most likely - which would be time better spent at the drawing board looking for real optimizations.
JoeCooper
JoeCooper
It depends on what you're doing, but you're not sacrificing anything by using JNI.

I started building our latest project in Java, and the Java Graphics API was simply too slow. I've worked with it a while and am aware of a lot of tricks, but it just plain would not paint fast enough and I wound up resorting to 3rd party libraries which invariably involved Java native interface.

The "write once run anywhere" is also a bit off. The "anywhere" means Mac, Linux, Solaris, AIX and other IBM machines nobody gives a rat's rear about. People are only going to actually run it on Windows, Mac and maybe Linux.

Apple maintains a separate, independently developed implementation of Java and you _do_ have to test on it because there are differences.

There are differences in the event behaviour that you might not be aware of if you're not actually testing on Apple's implementation. Layout bugs differ.

My experience has been that Apple's Graphics implementation is also a lot slower. We had no problem scaling up video playback all the way up to full screen using Sun's implementation on Windows on a Pentium III, but the same software was jerky and slow on an Intel Core Duo Mac.

Apple does not take Java very seriously. Java will not run on iPhone or iPod touch. They took ages to get Java 6 out and their Java, in my experience, was slower enough to warrant special attention.

If you use JNI and build for Windows and Linux on x86 & 64, and Mac on x86, x64 and PPC32, than the "anywhere" you sacrifice running on is some AIX mainframes or something.
Daniel L
Daniel L
Quote:
My experience has been that Apple's Graphics implementation is also a lot slower.

That's frightening -- I didn't think it it could get any slower. A few years ago I was writing a very simple 2D game and couldn't seem to do better than ~15 fps with Java 2D. After some profiling I realized that Graphics.fillRect was the bottleneck. That was with a 640*480 display! Caching the colored rectangles with volatile images mitigated the problem, but it seems rather silly to store a big monocolor raster in vram.
Fenrisulvur
Fenrisulvur
Quote:
Original post by JoeCooper
The "write once run anywhere" is also a bit off. The "anywhere" means Mac, Linux, Solaris, AIX and other IBM machines nobody gives a rat's rear about. People are only going to actually run it on Windows, Mac and maybe Linux.

I tend to have future-proofing in mind, but sure - if you're willing to write N amount of graphics implementations, you can target N amount of platforms natively. I think a WORA implementation is useful for five or ten (or more) years down the track when hardware will make light work of Java Graphics, but may not understand your blobs of machine code, though; and also as a fall-back in case your platform-specific implementations fail or get a little buggy.

As an example, most of the original Unreal Engine games were broken as early as 2005 (maybe earlier), roughly five years on from UT's release, largely due to hardware advances obsoleting the graphics drivers.
There were also CPU-related discrepancies which caused problems for some people, but essentially it's all the same thing - hardware moved on, and broke a generation of software. Develop for a virtual machine, though, and hardware moving on can only really break the virtual machine, which is actually an addressable problem.


Also, who the hell takes the Mac seriously these days? >_>

Quote:
Original post by JoeCooper
Java will not run on iPhone or iPod touch.

iPhone development is inherently unportable, you either write for the iPhone or you write for practically everything else. You can blame Apple for nerfing the platform.
JoeCooper
JoeCooper
Quote:
Also, who the hell takes the Mac seriously...


You mean the only other consumer platform that Java will actually run anywhere on?

We have several large customers who have standardized on Mac.

Quote:
these days? >_>


"These days"? I'd say that myself if it was 1998, but they're selling a LOT of computers now, at least in the states. These days, if any, are the ones where you ought to pay attention.

I understand what you're saying about future proofing, but it seems that what you mean by "Write Once Run Anywhere" is "it runs on Windows, will still run on Windows in 10 years, and should run on Mac in theory but I haven't checked cause who cares about Mac."

Maybe you should reconsider that slogan.

[Edited by - JoeCooper on February 3, 2010 7:54:47 PM]
LousyPhreak
LousyPhreak
Well I wouldn't say Java is slow. I am currently developing an application at work which renders a city model of Vienna in Java. The only native library used is lwjgl for OpenGL output, the rest is 100% Java.

We are pushing about 100M polygons per second on a 2.4 GHz Core 2 Duo with a Geforce 8800GT while streaming from about 5GB GPU-ready data from the disk. There is not much "game logic" in it, as it is only a flythrough, but there is still some CPU time left.

You might want to look at JMe (Java Monkey engine) which is a (somehow ;) ) working 3d engine in java.

Ps: we are developing on Windows and deploying on Linux (other OS not tested)
http://mitglied.lycos.de/lousyphreak/
JoeCooper
JoeCooper
Quote:
Original post by LousyPhreak
Well I wouldn't say Java is slow. I am currently developing an application at work which renders a city model of Vienna in Java. The only native library used is lwjgl for OpenGL output, the rest is 100% Java.


I would also say the Java is not too slow.

Only that their Graphics implementation isn't so hot, and Apple's is worse, so you need to use a 3rd party library - like LWJGL - and that will involve JNI.

I've looked at LWJGL and am considering it for future projects.
Momoko_Fan
Momoko_Fan
Have you seen jMonkey Engine? Currently it is considered as the best engine for 3D game development in Java. It is definitely possible to create a fast Java game engine.
Daniel L
Daniel L
Quote:
Original post by LousyPhreak
The only native library used is lwjgl for OpenGL output, the rest is 100% Java.

What's the rest? Loading models? I've used lwjgl's GL11 a bit and it seems like a very thin wrapper. No Javadoc tags or anything, just the GL11 signatures.

JVMs have come along way but I still think pure Java is slow, especially if javac is used with no optimizations. Lately I've been trying to get a ray tracer to run at a decent FPS on HotSpot. It spends far too much time checking bounding box intersections, resulting in about 0.4 FPS for 640*480. I'm using a pretty standard BB intersection algorithm which is used by some very fast C tracers. Even if I disable the ray tracing entirely, I just can't fill the display raster faster than ~20 fps without using any native code.

But as a general rule, I'm happy to sacrifice execution speed for wicked fast compilation.
JoeCooper
JoeCooper
Java will be slower by nature. Horses for courses. We'd feel really silly having this conversation about PHP, but only because nobody expects PHP to do these things.

Java is a business language if anything. Sun is going to put most of their efforts into making it run database servers and web servers and app servers fast, not raytracers. I strongly doubt they put nearly as much work making Hotspot optimize things like this.

Even if they did, Java doesn't really give you access to things like vector extensions or compile-time-type-punning... It will do a lot of run-time checks to make sure nothing ridiculous is happening, it will rely heavily on exceptions and dynamic casting.

You also can't really expect Hotspot to just figure out how to optimise things for SIMD. Even gcc won't just figure everything out. This upscaler I just wrote in C was just passable when I relied on gcc to optimize vanilla C, but using the vector extensions and a few SSE2 intrinsics really made it fly.

There was no simple way, even in C, to express that I wanted to convert RGB32 into a quartet of floats. The SSE version was 20% faster.

Conversely, a Java version would be much more work, computationally. The C version I had used compile-time type punning, while a Java version would need to make an int buffer, use bit shifts and masks and then cast one-by-one.

Sun's solution to all this, I might add, is to use native code. Java Graphics uses native code and hardware acceleration.
Momoko_Fan
Momoko_Fan
Quote:
Original post by Daniel L

JVMs have come along way but I still think pure Java is slow, especially if javac is used with no optimizations. Lately I've been trying to get a ray tracer to run at a decent FPS on HotSpot. It spends far too much time checking bounding box intersections, resulting in about 0.4 FPS for 640*480. I'm using a pretty standard BB intersection algorithm which is used by some very fast C tracers.

Not all C optimizations translate directly into Java. Generally speaking, game engines don't do all that much intensive work for pure speed to matter. Consider that most game engines are GPU-bound. Algorithm-based optimizations are more effective than low-level, language-based optimizations.

With all said, it is still possible to take advantage of CPU-based optimizations in Java, and without native code, using OpenCL:
http://www.jocl.org/

Quote:
Original post by Daniel L

Even if I disable the ray tracing entirely, I just can't fill the display raster faster than ~20 fps without using any native code.

Sounds like something is very wrong. You should be getting framerate in the thousands. Are you using active rendering with double buffering or are you overriding the paint() method?
JoeCooper
JoeCooper
JOCL's binaries are platform specific - they use native code.

You don't have to write it yourself, but you still toss any amount of write-once-run-anywhere you had; you must make platform specific deployments.

Quote:
Sounds like something is very wrong. You should be getting framerate in the thousands. Are you using active rendering with double buffering or are you overriding the paint() method?


It does sound like something is wrong. On Sun's Java 5 JVM and newer I have no trouble painting bilinear upscaled video to the full screen, even on a Pentium III.
Momoko_Fan
Momoko_Fan
Quote:
you still toss any amount of write-once-run-anywhere you had

Either way you still toss it. LWJGL uses native code to handle the OpenGL calls. Adding JOCL to the mix isn't going to change much. You'll be able to target Windows, Mac, and Linux with this combination, doesn't sound like such a bad thing to me.
Quote:
you must make platform specific deployments

No you don't. You can include all the native libraries in the same directory as the jar and it will work as one distribution. If you're deploying using an applet or web start, you just need to map the native libraries to your program and its done automatically for you.
JoeCooper
JoeCooper
I know you still toss it... That's my point, is that you don't actually lose anything... Ahh, nevermind.



You can deploy native libs with applets?
OffbeatPatriot
OffbeatPatriot
Unless your using hardware acceleration(lwjgl or jogl) Java is using software rendering right? So in defence of Java, isn't all software rendering slow?

I've been using lwjgl and I'm quite happy with it. Granted, the jni libraries keep it from being fully OS independent but all I have to is make sure someone gets the right jni libraries.

I've also been curious about the theory of JIT. If some code in Java gets executed several times the native instructions get cached and there is no need to convert from Java btyecodes to machine language any more(as I understand it), so would a line of code like the following,

for(int a = 0;a < 1000000000000;a++)
{
System.out.println(a);
}

Run just as fast as the C equivalent except for the initial loops that run from Java bytecodes?
Momoko_Fan
Momoko_Fan
Quote:
You can deploy native libs with applets?

Yes. How do you think all those 3d engine demo applets work?

Quote:
Unless your using hardware acceleration(lwjgl or jogl) Java is using software rendering right? So in defence of Java, isn't all software rendering slow?

I think you're confusing something here. The problem isn't rendering speed, its raw performance. E.g processing massive batches of data, like particles, vertices, or pixels (for the raytracer).
My point is that a game engine is rarely CPU bound if it's using hardware accelerated rendering so Java's speed is irrelevant there.

Quote:
I've been using lwjgl and I'm quite happy with it. Granted, the jni libraries keep it from being fully OS independent but all I have to is make sure someone gets the right jni libraries.

No, you don't have to worry about the libraries. As long as the native libraries are properly included it will all work without user intervention.

Quote:
I've also been curious about the theory of JIT. If some code in Java gets executed several times the native instructions get cached and there is no need to convert from Java btyecodes to machine language any more(as I understand it), so would a line of code like the following,

for(int a = 0;a < 1000000000000;a++)
{
System.out.println(a);
}

Run just as fast as the C equivalent except for the initial loops that run from Java bytecodes?

Yes, once a code block gets interpreted a certain number times it will be compiled into native code and from then on the native code will be executed for that block. Your example is correct for the most part except that printing to the console is slow in any language, but if you had some kind of complex math calculation running in there it will be compiled, yes.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.