Game logic scripting: Android vs PC

Hi

I am using Java JSR 223 with Groovy for scripting game logic. (Quests, Dialogs, Entity prefabs, Object actions,…)

For PC this is not a problem as I can compile and run the scripts fine but for Android, this does not work and I can not dynamically compile groovy scripts to .dex class easily. (This is not just Groovy specific and the same goes for Kotlin,…)

Interested to know about your solutions?

How do other Android games approach this? With Lua?

2 Likes

I did not use a scripting language, but I defined some simple definition files, which are used to store weapons, Bot AI, attack power and other information.
For each frame, I think that using script control logic will increase the cpu time overhead of android, so I coded it all in java code to ensure that there will be no more cpu time overhead.

2 Likes

This is the rub. Unless you use an interpreted language (which would potentially incur the performance issue that JhonKkk mentions) then you will always have this “compile at runtime” problem.

I’m not planning on releasing any of my stuff to android in the near future, but if I were then I would try to arrange the groovy scripts so that I can precompile them to .class files. (one of the benefits of the non-interpreted languages like groovy, etc.).

I will probably explore this for Mythruna also because with the number of scripts I will have the load time becomes pretty high. (The new engine serializes the blockset prebuilt instead of running the groovy scripts to assemble them and that’s a difference of countable seconds to less than a millisecond to load the whole set… and now I’m greedy.)

For my groovy scripts that rely heavily on certain types of DSL tricks, I’m going to experiment to see if I can serialize the class + objects and get around runtime compilation. (Also gives a bit of obfuscation I guess.) That wouldn’t necessarily work for Android, though.

Stylistically, over the years I prefer fewer DSL hacks anyway over more straight-forward groovy scripts… maybe with some injected preamble for common includes, etc. (which could pretty easily be rolled into a gradle precompilation task, I guess.)

4 Likes

I see, thank you, guys. :slightly_smiling_face:

Thanks, going to try it.

Do you have an idea of how to run the precompiled script?
Should I load them via ScriptEngine or Java ClassLoader?
And if I can still pass a Bindings?

Do you load all scripts at the app starting (Eager Loading) or load them when needed (Lazy Loading) or a mixed approach?

Never mind.

Appears that the compiled Groovy script .class already has a run() methods and accept a Bindings in the constructor.

So I suppose that should be fairly simple to load and init that with ClassLoader. :slightly_smiling_face:

1 Like

I do that kind of things using Json , xml & sqlite3 , you can easily bind data with keys to xml & xml is very fast as it is web based , but I prefer Json.

1 Like

Yes, so far. They all run at app startup and hook into what they need to hook into.

The original engine also had scripts that built out all of the block types which it ran at startup (built the meshes, set materials, etc.). I don’t do that at all anymore.

1 Like

Sorry if this is a stupid question!

Where would you put the scripts (I mean the compiled ones)?

Would you put them outside of your project codebase, somewhere inside a assets directory where you keep non-code assets files?

Probably depends on if I need to scan them or not. But if the application already has a config to say which ones to load then I’d probably just stick them in with the game classes.

Not really sure.

Edit: above presumes this is the ‘compile with gradle’ case.

1 Like

I see. Thank you so much for your helps :slightly_smiling_face:

@pspeed may I ask what groovy version you are using?

An older one, I think. Don’t go by that as I plan to do a round of upgrades at some point soon.

Why? Are you having some issues that you think are version related?

Probably not that important! After switching to groovy version 3.0 I noticed the compilation is a bit slower than versions 2.4 and 2.5. So just a heads-up :slightly_smiling_face:

1 Like

why don’t you use just plain java for scripting?

1 Like

I think the answer , is clean concentrated code :slightly_smiling_face: on backend, efficient for follow-up & easy to maintain.

1 Like

Yeah, I usually use java for developing the game systems and groovy for things like dialogs, quest, prefabs…

The benefit is I can use custom groovy DSL.

I got inspiration from Paul. :slightly_smiling_face:

Android is making a bit of pain here but fortunately, I can bypass this by precompiling the scripts.

Edit: But all in all these are yet experimental so might be changed :slightly_smiling_face:

1 Like

when I started writing my app I used groovy and reloaded scripts in runtime, so it was pretty nice and easy to develop an app, but at some point I realized that I can do same code-reloading for java and I don’t really need groovy… so now I don’t have this huge dependency =)

2 Likes

You can also use built-in HashMap<K,V> , it’s easier to use , faster & files are read/write using java regular I/O , so it’s great to ace it using java.util ,too , but donot place text data or database inside java code directly even if it’s static , from my opinion though .

This is the least interesting part of groovy.

The interesting part is that you can set it up to be more expressive so that 10 lines of Java code can be done in only two lines of groovy code or otherwise completely eliminate tons of boiler plate.

Especially for ES-based game logic, a little DSL goes a long way.

3 Likes