Scripting for games using Java

Better than using some crappy scripting language for a game is to use Janino

http://www.janino.net/

an embedded java compiler and which can load java classes directly from java source.

The problem with this is nothing prevents a modder who creates some extension for a game to access the java.io.* package and do all sorts of nasty things without any restrictions.

My question is there a simple way to restrict a modders script when using Janino or other embedded java compiler as a game scripting solution?

How is Janino better than using a different JVM language? Java syntax can be had using BeanShell (though I don’t personally like BeanShell). Java-the-language is not very expressive, so I think you may be limiting yourself unnecessarily.

You should be able to use the Java Security mechanism. Methods that you don’t want users to call should check a permission that users don’t have. There are also ways to control permissions to file access, network access, etc.

Pnuts has some additional mechanisms:
http://pnuts.org/doc/secure.html
http://pnuts.org/doc/limitedclass.html
http://pnuts.org/doc/configuration.html
More on Pnuts:
http://pnuts.org/snapshot/latest/
http://pnuts.org/articles/pnutsHighlights.html

A crappy solution is to not directly convert the sourcecode into classes, but save the intermediate result to either a file or a byte[]. Then you can peek around the constantpool (you must write a parser…) and terminate any naughty attempt to take over your machine. That said, you can’t so much about “for(;;);”, only Thread.stop() will get you out of that.

So much for the problems of this ‘ultimate runtime compiler’ – scripting languages are not that bad after all.

It’s a very fast on-the-fly compiler. This means you get full speed. It also means you can script full classes and it also means that you can replace them with compiled versions as soon as you’re done with em.

So, you can for example prototype rather complex things (even integral parts of your framework) pretty quickly. E.g. model or image loaders, collision detection, physics, etc. The console of my scripting framework was also done like that for example.

Other JVM langauges (eg, Pnuts ;D) can compile to bytecodes on the fly. Of course, speed is going to vary depending on what the language is doing. I think you are saying that Janino compiled classes are exactly as fast as using bytecodes from javac?

[quote]It also means you can script full classes and it also means that you can replace them with compiled versions as soon as you’re done with em.
[/quote]
I write Java classes using a standard Java IDE (Eclipse). If I change the Java source for a class and save the file, the IDE recompiles the class and (assuming my application is running) it uses Java HotSwap to patch the bytecodes for the class in the running application. I can’t imagine Janino’s workflow can be smoother than this?

IMO, the real benefit to use a JVM language other than Java-the-language is for added expressiveness. There is also the benefit of being able to load code at runtime, when an IDE is not present.

So far, the only argument I could accept for using Janino would be:

  1. If you needed to compile Java source at runtime, with no IDE. But isn’t there a JSR for this that made it into the JDK? Does Janino provide extra funcitonality?

  2. If you absolutely needed the same speed as javac, and are willing to sacrifice expressiveness to get it. Then I wonder what the speed differences actually are in real world usage.

Thanks for the input. I will check pnuts. It looks a solid scripting language.

“1) If you needed to compile Java source at runtime, with no IDE. But isn’t there a JSR for this that made it into the JDK? Does Janino provide extra funcitonality?”

I have two requirements for a game scripting language 1) scripts can be compiled to bytecode and 2) it can be compiled dynamically. I know that java 1.6 has some support for dynamic compilation but i have a mac with with java 1.5 and i’m not sure if it works. Anyway it looks like Pnuts can do the job.

I think you are saying that Janino compiled classes are exactly as fast as using bytecodes from javac?

Yes. I never noticed any speed difference. (Complete classes.)

I can’t imagine Janino’s workflow can be smoother than this?

Well, it means you easily get a workflow like that (with instant turn-overs) on very dated or very weak machines.

Janino can also compile/execute statements or method bodies, which might be handy here and there.