I am thinking about adding AI scripting functionality to my game (http://www.ageofconquest.com). The goal is to let players create their own AI for the game. The game is turn-based, so the AI script will be called every time a new game turn is calculated.

AI Input:- a game objectAI Output:- a list of actions to execute on the gameConstraints:- Required: AI Script can be executed in Java (platform independent)- Required: prevent malicious code (e.g. prevent access to file system etc.)- Desired: limit AI functionality to just reading the game object and creating actions- Desired: AI editor with syntax coloring (what's good?)

What's the best strategy to create AI scripting for players? Use an existing language? Which one? Or roll my own?

Probably the easiest (for you) is to launch a separate sandboxed JVM and kill it after a second, if it hasn't terminated yet. You simply serialize some of your game objects, and load them in 'their' JVM (as read-only as it gets, no matter what they write/modify, it won't alter your real game JVM).

It might sound stupid, but it's like 30 minutes to implement, and that's it! Compare that to anything else.

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

How about launching the code in a separate thread instead of a sandboxed JVM? I would kill the thread if it doesn't finish after a second (like you proposed for the JVM). I can pass in a copy of the game object. It wouldn't matter if the AI would modify the game object copy.

Now, how can a prevent the AI code to access the file system/doing malicious stuff? If I load the AI script via a modified ClassLoader, would I be able to prevent the bad from happening?

I didn't allow any capticals in the sourcecode (also checking unicodes -- \uHEXX) and I stop()ed the Thread after 100ms. I remember Abuse came up with some obscure class in the JRE that started with a lowercase character, that did something really bad, and I limited the max source length.

So... not really a useful strategy to you, unfortunately.

FYI: scriptRunner.interrupt(); does nothing. you really must use stop() which will not properly release mutexes.

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

In regards to security: did you try to use the SecureClassLoader in Java when loading and executing classes? I think it would limit access to system resources for the class???

Well, if you look at the classes in java.io.* and java.net.*, you'll see that those permissions are only checked if there is a SecurityManager installed. That SecurityManager will interfere with your game too. Hence the idea of launching an external (sandboxed) JVM.

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

maybe a stupid idea...dono.... cant you use a custom class loader (force it to the user script) ? and only allow safe classes by checking if it is in your safe classes a list ? dont know hw it is possible but for example your script could only allow getSafeClass("Name") and prevent any Blabla.something() or new Something(), just a search and replace in the user source.

EDIT:

something like :

"Something." => not enabled if Something not in safe list"new "=> not enabledgetClass().newInstance() => replaced at compil time by getSafeClassInstance();

What i tested some days ago was to use Janino to dynamically compile scripts and run them with a SecurityManager that only permits using your game classes. you can't hide classes but you can prevent moders from using them and with Janino you can tell it to compile only class bodies and prevent the use of the import instruction.

You can control whether scripts are interpreted, compiled, cached, etc with context.setImplementation: http://pnuts.org/apidoc/pnuts/lang/PnutsImpl.htmlAlso, context.setVerbose is useful, and I like to call context.setWriter(new PrintWriter(System.out, true)); (the default PrintWriter doesn't autoflush for whatever reason).

So I assume the code will be running on the server, or in remote clients.

Where ever your potentially malicious code is running, would you really think the best solution is to 'plug all security holes you find' ? You'll be surprised how much effort people put into trying to find a vulnerability. In the end it is your game, and it is your responsibility that nobody gets they files corrupted or their creditcard number stolen.

My advice: play it safe and launch 1 sandboxed JVM for each AI player. In that sandboxed JVM you can kill threads each turn (if needed), for each player.

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

I did a serious 3 month project on dynamic scripting (ie an agent's script changes depending on its circumstances) and I found that home-brew was best. No compiler security issues, easier to read script (because it's dedicated to the context), and no WTFs from rhino, lua, pnuts &c...

script.run can manipulate the game object I passed in??? I.e. after the script is done, the game object has changed?

If your game object has methods that can be called to change the internal state of the object, then yes, the script could have modified it. Either don't provide those methods or make a copy. It is possible to intercept method invocations and other things using a Configuration and context.setConfiguration. This might be used in addition to the classloader.

If your game object has methods that can be called to change the internal state of the object, then yes, the script could have modified it.

Yes, that's what I actually want! Seems like Pnuts is the way to go. So, my assumptions from above how to create and run a script are basically correct?

I also checked FScript which looks nice but is probably too limited? Then rolling my own would take lots of time to implement. My goal isn't to create a scripting language but to add one to my game. Using an existing solution is probably the most feasible solution.

Once thing I noted about Pnuts is, it doesn't have any updates since 2007? Is there an official forum for it too?

Honestly, you could use any JVM scripting language (Rhino, JRuby, Jython, Groovy, blah). I like Pnuts a lot though! It has nice syntax that doesn't stray too far from Java (compared to the ridiculousness in Groovy). I also like that the Pnuts type system is the Java type system, many languages converted to run on the JVM come with their own type system.

Development on Pnuts started in 1997. It is stable and actively maintained. The java.net Pnuts mailing list is the best way to ask questions or discuss bugs. Any bugs found are usually fixed with 24 hours. You might check out this page:http://pnuts.org/articles/pnutsHighlights.html

I am aware of JavaScript for Java. As I am targeting Java 5, scripting is not available there yet. Also, the current version doesn't prevent people from executing malicious code. I am planning to run it on my server, so limiting script execution is quite important!

I am aware of JavaScript for Java. As I am targeting Java 5, scripting is not available there yet. Also, the current version doesn't prevent people from executing malicious code. I am planning to run it on my server, so limiting script execution is quite important!

Anyhow, I am going with Pnuts. I got everything to work nicely

Rhino is independent of Java 6 scripting APIs, and with a proper ClassShutter implementation, it's as secure as it gets. I bet the players will find JavaScript easier than Pnuts. But heck, I should mind my own business!

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

I am aware of JavaScript for Java. As I am targeting Java 5, scripting is not available there yet. Also, the current version doesn't prevent people from executing malicious code. I am planning to run it on my server, so limiting script execution is quite important!

Anyhow, I am going with Pnuts. I got everything to work nicely

did not kneew about Pnuts, It look really great

@Riven : your sig is every days more funny , what next ? oldness of the user ? credit card number ?

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