Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Having Java as a scripting language?  (Read 4488 times)
0 Members and 1 Guest are viewing this topic.
Online theagentd
« Posted 2011-11-12 08:46:42 »

Okay, I've got to the point where I want to implement a scripting language. I want a very powerful scripting language, but it obviously has to be fast, so I thought to myself: "What's wrong with Java?". I mean, I can compile the scripts at runtime to bytecode, load it and run it at the same speed as normal code. It should beat any scripting language implementation when it comes to performance, plus be easier to implement.

I realize that I will need some good security for this. I need to disallow networking, reflection, file access, e.t.c, or people could create viruses in my game scripts! Shocked I'm also thinking of restricting class access to a white list. I've heard that these 2 things can be implemented with a SecurityManager and a custom ClassLoader, respectively.

Now, I have no experience what so ever with SecurityManagers and ClassLoaders and such stuff, so I don't really know how to use them. I've managed to compile some test Java code with JavaCompiler, but I don't really understand how to load the class after that. I've tried Google, but I couldn't find anything like this...

Myomyomyo.
Offline divxdede

Junior Member





« Reply #1 - Posted 2011-11-12 09:06:30 »

You should go with "scripting" feature of Java with a langage like Groovy that can be easily integrated inside a java program.
you can read this : http://groovy.codehaus.org/Embedding+Groovy

and do code like it in your java program

1  
2  
3  
4  
5  
6  
7  
8  
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
Class groovyClass = loader.parseClass(new File("src/test/groovy/script/HelloWorld.groovy"));

// let's call some method on an instance
GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
Object[] args = {};
groovyObject.invokeMethod("run", args);

Online theagentd
« Reply #2 - Posted 2011-11-12 09:35:30 »

Interesting! It even seems to be able to do object orientation too, which I will need! I'll look into it, but it seems a little complicated...

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline nsigma
« Reply #3 - Posted 2011-11-12 10:38:00 »

You could have a look at Janino http://docs.codehaus.org/display/JANINO/Home

As well as being an embedded compiler, which has the advantage that it will work with the JRE, it can now also wrap javac.  It manages the ClassLoader stuff for you, and it is possible to set a ProtectionDomain on the loaded classes.  It also provides the means to compile individual methods or expressions.

I use Janino as the basis for the live compilation in Praxis and it works really well.  I haven't yet looked at the security manager aspect of it - would be nice but not essential for my use case - if the user wants to destroy their home directory, I'm not going to stop them!  Cheesy

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Online theagentd
« Reply #4 - Posted 2011-11-12 13:19:30 »

You could have a look at Janino http://docs.codehaus.org/display/JANINO/Home

As well as being an embedded compiler, which has the advantage that it will work with the JRE, it can now also wrap javac.  It manages the ClassLoader stuff for you, and it is possible to set a ProtectionDomain on the loaded classes.  It also provides the means to compile individual methods or expressions.

I use Janino as the basis for the live compilation in Praxis and it works really well.  I haven't yet looked at the security manager aspect of it - would be nice but not essential for my use case - if the user wants to destroy their home directory, I'm not going to stop them!  Cheesy
This looks just perfect. Nyehehehe... (<--- my experimenting laugh) Groovy looks interesting too, but I'll start with Janino for now.

EDIT: This code freaks me out.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
package dam.test;

import org.codehaus.janino.ExpressionEvaluator;

public class JaninoTest {
    public static void main(String[] args) throws Exception{
        ExpressionEvaluator exp = new ExpressionEvaluator("10 + 5*3 + dam.test.JaninoTest.getValue(\"stat\")", int.class, new String[0], new Class[0]);
        System.out.println(exp.evaluate(new Object[0]));
    }
   
    public static int getValue(String name){
        return 5;
    }
}

Myomyomyo.
Offline nsigma
« Reply #5 - Posted 2011-11-12 14:46:24 »

EDIT: This code freaks me out.

Why? Is that not exactly what you'd expect?

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Online theagentd
« Reply #6 - Posted 2011-11-12 15:30:28 »

Well, yeah, but the power is overwhelming. xD Hahaha...

Okay, so I've got my little compile test running, and I've also made a custom SecurityManager that denies everything (I'll make it toggle-able eventually). Is there any way to restrict access to a whitelist of classes? I'd like to restrict access from everything that isn't needed. This is to serve as an extra security layer (paranoia xD), but also as a hint to scripters to keep the scripts simple. Basically to send the message that if you can't do it with the available classes, you're either not supposed to be doing that, or you're Doing It Wrong. I think I heard someone mentioning that this could be done with a custom ClassLoader, but I don't see how to do that at all. How do I even create a ClassLoader? T___T

Myomyomyo.
Offline nsigma
« Reply #7 - Posted 2011-11-12 16:01:48 »

Well, yeah, but the power is overwhelming. xD Hahaha...

Okay, so I've got my little compile test running, and I've also made a custom SecurityManager that denies everything (I'll make it toggle-able eventually). Is there any way to restrict access to a whitelist of classes? I'd like to restrict access from everything that isn't needed. This is to serve as an extra security layer (paranoia xD), but also as a hint to scripters to keep the scripts simple. Basically to send the message that if you can't do it with the available classes, you're either not supposed to be doing that, or you're Doing It Wrong. I think I heard someone mentioning that this could be done with a custom ClassLoader, but I don't see how to do that at all. How do I even create a ClassLoader? T___T

hmmm ..... power! ......  persecutioncomplex

It might be worth looking at this bug report http://jira.codehaus.org/browse/JANINO-66  The Sandbox attachment might be useful in terms of setting up an unprivileged context.  Along with that, the mentioned auxillary classes are set in SimpleCompiler.setParentClassLoader(..) which is a superclass of ExpressionEvaluator (and the other evaluators).  You should be able to restrict access to just JVM classes using the BOOT_CLASS_LOADER field in SimpleCompiler.  It may even be possible to pass a ClassLoader that doesn't load anything, and pass all the classes you want people to be able to load in the auxillary classes array.

As I said before, I haven't tried any of these things out myself yet.  Good luck!  Wink

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Online theagentd
« Reply #8 - Posted 2011-11-12 16:51:46 »

I'm using JavaSourceClassLoader to load .java files, and it actually had a ClassLoader constructor argument. I did this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
    private class RestrictedClassLoader extends ClassLoader {
       
        public RestrictedClassLoader(ClassLoader parent){
            super(parent);
        }
       
        @Override
        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            System.out.println("Loading class " + name);
            if(
                    !name.startsWith("java.lang.") //for all basic classes
                   && !name.equals("java.io.Serializable") //String extends this I think
                   && !name.startsWith("compiling.") //The package of the script(s)
                   && !name.startsWith("dam.test.") //The script object implements an interface from this package
           ){
                throw new SecurityException("Bad class!");
            }
            return super.loadClass(name, resolve);
        }
    }

It seems to be working. I also added the SecurityManager thingy, and it all seems to work fine. I'll have to make a "Hack my script engine" contest before I release the game if I ever get that far. xD

Thanks for your help Nsigma, and thanks to Divxdede too!

Myomyomyo.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #9 - Posted 2011-11-12 17:23:59 »

You forgot to exclude reflection Kiss

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline avm1979
« Reply #10 - Posted 2011-11-12 17:25:49 »

Sorry to hijack the thread a bit... I've been using Janino for a while, and ran into an odd bug - it seems to not be able to handle break/continue inside a loop. It will compile that code fine, but then dies on the next compilation unit with this stack trace:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
 org.codehaus.janino.JaninoRuntimeException: Cannot "set()" Offset more than once
   at org.codehaus.janino.CodeContext$Offset.set(CodeContext.java:1178)
   at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:1009)
   at org.codehaus.janino.UnitCompiler.access$1000(UnitCompiler.java:104)
   at org.codehaus.janino.UnitCompiler$5.visitForStatement(UnitCompiler.java:870)
   at org.codehaus.janino.Java$ForStatement.accept(Java.java:1537)
   at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:888)
   at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:914)
   at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1999)
   at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:789)
   at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:770)
   at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:464)
   at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:357)
   at org.codehaus.janino.UnitCompiler$3.visitPackageMemberClassDeclaration(UnitCompiler.java:312)
   at org.codehaus.janino.Java$PackageMemberClassDeclaration.accept(Java.java:770)
   at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:319)
   at org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:288)
   at org.codehaus.janino.JavaSourceClassLoader.generateBytecodes(JavaSourceClassLoader.java:203)
   at org.codehaus.janino.JavaSourceClassLoader.findClass(JavaSourceClassLoader.java:157)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at com.fs.starfarer.loading.scripts.ScriptStore$1.run(ScriptStore.java:85)


Has anyone had much experience with it and managed to work around the problem (or not run into it at all)?

Online theagentd
« Reply #11 - Posted 2011-11-12 18:53:18 »

You forgot to exclude reflection Kiss
Excluded with the SecurityManager, but I'll be using a whitelist later.

Sorry to hijack the thread a bit... I've been using Janino for a while, and ran into an odd bug - it seems to not be able to handle break/continue inside a loop. It will compile that code fine, but then dies on the next compilation unit with this stack trace:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
 org.codehaus.janino.JaninoRuntimeException: Cannot "set()" Offset more than once
   at org.codehaus.janino.CodeContext$Offset.set(CodeContext.java:1178)
   at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:1009)
   at org.codehaus.janino.UnitCompiler.access$1000(UnitCompiler.java:104)
   at org.codehaus.janino.UnitCompiler$5.visitForStatement(UnitCompiler.java:870)
   at org.codehaus.janino.Java$ForStatement.accept(Java.java:1537)
   at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:888)
   at org.codehaus.janino.UnitCompiler.compileStatements(UnitCompiler.java:914)
   at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:1999)
   at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:789)
   at org.codehaus.janino.UnitCompiler.compileDeclaredMethods(UnitCompiler.java:770)
   at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:464)
   at org.codehaus.janino.UnitCompiler.compile2(UnitCompiler.java:357)
   at org.codehaus.janino.UnitCompiler$3.visitPackageMemberClassDeclaration(UnitCompiler.java:312)
   at org.codehaus.janino.Java$PackageMemberClassDeclaration.accept(Java.java:770)
   at org.codehaus.janino.UnitCompiler.compile(UnitCompiler.java:319)
   at org.codehaus.janino.UnitCompiler.compileUnit(UnitCompiler.java:288)
   at org.codehaus.janino.JavaSourceClassLoader.generateBytecodes(JavaSourceClassLoader.java:203)
   at org.codehaus.janino.JavaSourceClassLoader.findClass(JavaSourceClassLoader.java:157)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at com.fs.starfarer.loading.scripts.ScriptStore$1.run(ScriptStore.java:85)


Has anyone had much experience with it and managed to work around the problem (or not run into it at all)?
Uwaaaa... Sounds horrible! Keep me updated!!!

Myomyomyo.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #12 - Posted 2011-11-12 22:37:56 »

You forgot to exclude reflection Kiss
Excluded with the SecurityManager, but I'll be using a whitelist later.
You can use reflection with any security manager. The security manager is only notified when you do something 'forbidden' like accessing a private field.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #13 - Posted 2011-11-13 06:04:30 »

What about javascript? You can implement it almost exactly like java, and it will take parameters. Does not need compilimg.

Offline Nate

JGO Kernel


Medals: 145
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #14 - Posted 2011-11-13 08:28:47 »

+1 Janino. -1 Groovy (pile of junk).

Online theagentd
« Reply #15 - Posted 2011-11-13 09:00:47 »

You forgot to exclude reflection Kiss
Excluded with the SecurityManager, but I'll be using a whitelist later.
You can use reflection with any security manager. The security manager is only notified when you do something 'forbidden' like accessing a private field.
I'll use a whitelist in the end anyway, so it should be okay. That code was just for my test.

What about javascript? You can implement it almost exactly like java, and it will take parameters. Does not need compilimg.
It needs to be fast, so not having compilation needing compilation is a bad thing in this case.


@Avm1979
I managed to reproduce the error. Goddamn it! Is there a bug report for this problem already, or should we hurry up and make one?
EDIT: Yay! http://jira.codehaus.org/browse/JANINO-147

Myomyomyo.
Offline nsigma
« Reply #16 - Posted 2011-11-13 12:02:08 »

You forgot to exclude reflection Kiss
Excluded with the SecurityManager, but I'll be using a whitelist later.
You can use reflection with any security manager. The security manager is only notified when you do something 'forbidden' like accessing a private field.

@Riven.  Can you clarify what the issue with reflection would be?  How could you access anything that you couldn't with normal code anyway, as the SecurityManager will (should) stop you accessing other classloaders / private fields?  This is a sincere question, btw - it's not an area of Java I feel I know a lot about.

@Avm1979
I managed to reproduce the error. Goddamn it! Is there a bug report for this problem already, or should we hurry up and make one?
EDIT: Yay! http://jira.codehaus.org/browse/JANINO-147

Dang, was just going to reply and point you to that!  Seems fixed in 2.6.2, but that's not released yet.  Incidentally, could you post an example that will reproduce this.  Have tried in Praxis but can't seem to force this error - incidentally, that's with the last release of the 2.5 branch, and using ClassBodyEvaluator.  I wonder if downgrading to 2.5 is a short term fix?

Incidentally, I personally like using the ClassBodyEvaluator for what you're doing because you don't have to name classes, and more importantly you can force a particular superclass / interface.

Best wishes, Neil

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Online theagentd
« Reply #17 - Posted 2011-11-13 12:28:17 »

Sorry, my code is currently more similar to scrambled eggs than to actual code. I basically hackingly merged two different test programs. Go figure... T_T

It's easy to reproduce though. Just create two java files, with the first one containing a method with a while(true)-loop with a break; to exit it. Then load both of them with a JavaSourceClassLoader (the while-break one first) and bam! JaninoRuntimeException!  Cry

Myomyomyo.
Offline avm1979
« Reply #18 - Posted 2011-11-13 15:39:18 »

@Avm1979
I managed to reproduce the error. Goddamn it! Is there a bug report for this problem already, or should we hurry up and make one?
EDIT: Yay! http://jira.codehaus.org/browse/JANINO-147

Thanks for verifying, and tracking that down! Thing is, it's been over a year since 2.6.1 - wonder if 2.6.2 is going to get released at all. Ah, well, keeping my fingers crossed.

... Just create two java files, with the first one containing a method with a while(true)-loop with a break; to exit it. Then load both of them with a JavaSourceClassLoader (the while-break one first) and bam! JaninoRuntimeException!  Cry

Yep, that's all it takes. Kind of surprised it took this long for someone to run into that, tbh.


+1 Janino. -1 Groovy (pile of junk).

I started out using Groovy for scripting in Starfarer and had all sorts of trouble, from compilation speed to code compiling and then dying at runtime. It was all resolvable, more or less, but added up to being a huge pain. Janino, on the other hand, worked very smoothly.

As an added bonus, you can use your Java IDE of choice for the scripts. I've set up my projects like this: a core project, an api project, and a scripts project. Both core and scripts depend on api, but core does not depend on scripts. That way, you get all the compile-as-you-type support from the IDE - but at runtime, since core doesn't depend on the scripts project, it doesn't see the IDE-compiled class files and can use Janino to compile them on startup. Works like a charm, and forces a clean separation of what's accessible to scripts vs not.

Online theagentd
« Reply #19 - Posted 2011-11-13 23:15:44 »

Damn, the last new version was indeed released in June 2010... >_< Stupid world!

I read on the front page that you can make it use JavaCompiler instead.
Quote
JANINO can be configured to use the javax.tools.JavaCompiler API (available since JDK 1.6), which removes the Java 5-related limitations.
Nothing anywhere on HOW to actually do that though. -_- I suppose it would require a JDK on the computer, but it would at least be a workaround until the next version is released, whenever that happens.

Myomyomyo.
Offline avm1979
« Reply #20 - Posted 2011-11-13 23:39:55 »

Yeah, that requires the JDK. Which is a no-go for me because of the license - you can't redistribute it.

Ahhh. Very frustrating. Still, can be coded around by just not using break/continue... some people say that's good coding style, anyway, though I'm not one of them Smiley

Online theagentd
« Reply #21 - Posted 2011-11-14 00:02:26 »

I got the JavaCompiler version working...  Commented out lines are the equivalent Janino compiler code. rcl is my restricted class loader.
1  
2  
3  
4  
5  
6  
7  
8  
//import org.codehaus.janino.JavaSourceClassLoader;
import org.codehaus.commons.compiler.jdk.JavaSourceClassLoader;

...

        //JavaSourceClassLoader loader = new JavaSourceClassLoader(rcl, new File[]{new File("").getAbsoluteFile()}, null);
       JavaSourceClassLoader loader = new JavaSourceClassLoader(rcl);
        loader.setSourcePath(new File[]{new File("").getAbsoluteFile()});



Yeah, that requires the JDK. Which is a no-go for me because of the license - you can't redistribute it.

Ahhh. Very frustrating. Still, can be coded around by just not using break/continue... some people say that's good coding style, anyway, though I'm not one of them Smiley
What's wrong with "Please download the Official Java JDK from Java.com to be able to run this game."? You could even have the game download it for you from Java.com?

Myomyomyo.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 783
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #22 - Posted 2011-11-14 00:10:11 »

JDK is not available on java.com

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline ra4king

JGO Kernel


Medals: 345
Projects: 2
Exp: 5 years


I'm the King!


« Reply #23 - Posted 2011-11-14 00:13:33 »

http://download.oracle.com/otn-pub/java/jdk/7u1-b08/jdk-7u1-windows-i586.exe

Offline sproingie

JGO Kernel


Medals: 202



« Reply #24 - Posted 2011-11-14 00:13:44 »

You may not need the whole JDK.  If JSR199 is available as a redistributable download, the eclipse compiler implements the javax.tools.Compiler interface too, and that's bound to have less bugs than Janino.
Offline avm1979
« Reply #25 - Posted 2011-11-14 00:46:33 »

What's wrong with "Please download the Official Java JDK from Java.com to be able to run this game."? You could even have the game download it for you from Java.com?

Call me crazy, but I prefer to have the players run the game using the same JRE that it's been tested against. Besides, stuff should "just work" as much as possible - a manual step like that means someone will inevitably screw it up and need help, or get mad because the JDK installer installed crapware on their computer (which it does). Everyone is happier when the player doesn't need to do anything special to get the game running Smiley

You may not need the whole JDK.  If JSR199 is available as a redistributable download, the eclipse compiler implements the javax.tools.Compiler interface too, and that's bound to have less bugs than Janino.

Hmm, that may be worth looking into. Thanks for the suggestion!

Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #26 - Posted 2011-11-14 03:50:26 »

Here's a crazy thought; What about just using java, as with your original intent?  Roll Eyes
You'll get plenty of speed, and features won't be hard. You'll get to call all of your objects directly, and it supports all kinds of fun things.

Does it need to be accessible by players? Read/write, kind of?

Online theagentd
« Reply #27 - Posted 2011-11-14 03:54:31 »

The scripts are to be part of game maps (it's a strategy game) like unit stat calculation, on-hit scripts, campaign triggers, e.t.c, so in theory I could just force people to download JDK for the map editor and keep the compiled Java scripts in the map file, avoiding any compilation during map loading.

Myomyomyo.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #28 - Posted 2011-11-14 04:01:31 »

I don't think making modders download a full JDK is all that much of a stretch.  Players certainly shouldn't have to.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #29 - Posted 2011-11-14 04:02:25 »

The scripts are to be part of game maps (it's a strategy game) like unit stat calculation, on-hit scripts, campaign triggers, e.t.c, so in theory I could just force people to download JDK for the map editor and keep the compiled Java scripts in the map file, avoiding any compilation during map loading.

Why are they scripts? Do you want the player to change them? Do you have people writing these, that can't program java?
If no, I see no point in making them scripts.

I would just use the js-script-manager, and do this:
1  
ScriptManager.getScriptManager().invokeWithFailTest(o.getScriptString(), player)


..and you could script it like
1  
2  
3  
function doShizzle(player) {
        player.getBackpack().addItem(Items.HEAVY_ASS_SWORD);
}


I mean.. just make it easy for yourself Cheesy I don't think performance is going to be a problem this way.

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

TehJavaDev (12 views)
2014-08-28 18:26:30

CopyableCougar4 (24 views)
2014-08-22 19:31:30

atombrot (37 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (29 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (27 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (33 views)
2014-08-08 02:01:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!