Scripting languages in JME3

Over the past few weeks I have spent a considerable amount of time looking at jmonkey and all the epicness that you guys have put into it. It seems to be a solid game engine written in Java (awesome feature right there :smiley: ) and best of all its free. Its exactly the kind of this that I was looking for, to help me and a few friends make a little project.

A single-player RPG to be precise. A big part of doing so, in my eyes is having a scripting language that can be used even by people other than programers, in order to add quests, dialogs, items, AI interactions, random events, cut scenes, and other such things. Not to mention by using a scripting language you can see modding of your game as a viable option should you ever feel like you want to implement that.

So, not being a programming guru, or a professional game developer, I turn to the community :slight_smile: . How would one implement a scripting language into JME3?

I noticed that mainclain is working on a single player RPG Chronos World with scripting in Jython. (Awesome work on that btw :smiley: ), so it can be done, Im just wondering how and what main obstacles would appear on the way.

Thanks in advance! :slight_smile:

If you are a Java programming mostly and not that familiar with Python (and even if you are), I still highly recommend groovy.



Since now there is an official topic for this subject, I will repost my code snippet here:



This will let you integrate any jsr-223 compatible scripting engine just by picking the engine name:

[java]

import javax.script.;



ScriptEngineManager factory = new ScriptEngineManager();

ScriptEngine engine = factory.getEngineByName(“groovy”);

engine.eval( new FileReader(“myfile.groovy”);

[/java]



As long as groovy-all.jar is on your classpath then the above should work. Java 6+ includes JavaScript by default and most other Java scripting languages have support for jsr-223. I don’t have the jython references handy but it should be just as easy as the above. Put the right jar on the classpath and use getEngineByName(“jython”) instead.



If you want to add your own objects accessible through the scripting engine then you can do something like:

[java]

Bindings bindings = engine.createBindings();

bindings.put( “rootNode”, rootNode );

engine.setBindings( bindings, ScriptContext.ENGINE_SCOPE );

[/java]



Then your scripts will have access to “rootNode”… though this is perhaps not a best practice, I’m just trying to use an object every JME user should be familiar with.



Furthermore, groovy allows you to extend classes at runtime to add new methods… including operator overloading.



This is an example of adding some operator overloading to Vector3f:

[java]

import com.jme3.math.
;

Vector3f.metaClass {

multiply { Vector3f v -> delegate.dot(v) }

multiply { Float n -> delegate.mult(n) }

plus { Vector3f v -> delegate.add(v) }

}



Number.metaClass {

multiply { Vector3f v -> v.mult(delegate) }

}

[/java]



It’s not complete as it only provides support for n * vector, vector * n, vector + vector, and a dot product by using vector * vector but it’s a start. This kind of thing would make certain types of AI code read better.



I could go on longer but it’s best to pick specific use-cases at some point and try stuff out. Where scripting best fits will largely depend on the type of game… I’d think an RPG could make great use of scripts to avoid having to hard-code object behaviors, etc… For example, when a user clicks on an object to “activate” it or whatever, you could load the script and call its “activate()” function.

2 Likes

I guess you have read the topic “RPG Chronos World”



http://hub.jmonkeyengine.org/groups/free-announcements/forum/topic/singleplayer-rpg-chronos-world-wip/?topic_page=3&num=15#post-138983



in which I and some monkeys messed around with some ideas of scripting.



I also guess you had time to do research and already known the basic Logic framework which existed in JME3. So I try to type things that I also researched for a long time and share here for advices:



Now, let’s consider some approaches which we can do for our “game logic framework” and “scripting framework” if it’s really necessary by answer following points/questions :



1. Let’s image your world!

You have a RPG world (as you mentioned above).



a. Is your world big?

“Big” means various of objects have to be made and prepare before the player enter your game. It also means a lot of kind of things you have to do (modeling , texture , animation, scripting …)

Advice: As you said you have a small team intend to make game for fun and studying purpose. Please keep your game world small !

My thought: As my current project is an adventure and puzzle game, my game world is relatively small. I just make some room (house,cave) and throw in props, then the script comes …



b. Is you characters intelligent?

“Intelligent” means your characters have a lot of knowledge to the world around them. Your main character know how to open a door, and also know how to explode a bomd… Your evil NPC know how to prevent the hero reach the gate… There are various of technique can solve the problem:

* rule-base world :

[java] FOR (NPC1:NPCgroup))

IF condition THEN NPC1.do(action)[/java]

// Pos: good with large world MMORPG , clear rule such as exchanging , trading , fighting !

// Fact: usually use with database

// Cons: Big and hard to get right, a lot of affords needed!

* Finite State Machine:

in loop

[java]{

switch (state)

case1 { do(action1); changeState(2); }

case2 { do(action1); changeState(3); }

}[/java]

// Pos: good with FPS , fast and easy to tweak , have a lot of research and success story

// Cons: The NPC is too damn smart, lack of unexpected or “learned” behaviour.

a lot more …however they are all difficult to reach with just a small group… IMO, the research in this area (some open source code…) mainly in C++, not in java , and in java is not really usable yet…

Advice: TRY SCRIPTING !

My thought: In scripting, the “rule” and the “action” is made by provide the connection between related object on the fly … The more detail explanation come next !



2. Making your world in Logic Term:

You have drawn a lot of beautiful assets for your game or just use Boxes for Place Holder, it doesn’t matter. Because we re talking about Logic World:


+ Assume that your RPG game has room (house, cave) and landscape (forest , street ) . So, what exactly are they mean in "Logic term" : Obstacles and container and trigger... OK , spend a few second to thought about those stuff...
+ Assume that your RPG also got creature (what the h3ll the world without moving things) ... So, they are also : obstacles , trigger and ... actor.
+ All these things can have Attribute like: cost, health, weight, strength and so on...
+ And other things belong to the underground system like: Navigation ,Time , Score System,SaveLoad ...
Now the explanation :


Obstacles: is the entity have ability to collision and prevent other thing to come through it.
Container or Room: entity that culling things that outside of it. Everything else out of the box is unknown!
Trigger: entity which can be positional or frequency but have condition. When the time come or position reached, the condition is tested then Trigger fire...
Actor: entity which can react with outside situation. The basic methods it has are "beingHit()" or "beingReach()" by an Object and "do(Object)" which in turn react the Object .
Action which Actor make in fact is another thing which involve in the "Logic framework" and is the most important of all. Action is the unit of the progress of game play. Image your game like a "list of sentences like a dialog":
Actor1 do Attack the Wolf
Wolf do Attact Actor1
Actor1 do runLeft
Wolf do Chase Actor1

Another example: // for dialog
Girl1 do Talk "I'm scared"
Boy1 do Talk "Shit. They're coming!"
Girl1 do runLeft
Boy1 do fire Wolf1

Attribute : provide the material to compute equation to simulate the real world...
i.e:
Plus (+) or minus (-) Health to describe the Result of Fight
The weight value affect the gravity of Physic, and the force of a jump that can kill a mushroom like in Mario
Navigation, Time and Score , SaveLoad System : extra things we have to make when the game evolve. Navigation is for deciding the direction which shortest or most easily to reach, Time System is the measure and separate each Action ... , Score System decide what information of the game is need to compute the score and save it, which need a SaveLoad system who can serialize all stuff to load back next game time.

3. Code your World:
a.Know what JME3 already does for you:

For new monkey should take a look at :
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:custom_controls
JME3 provide a very "smart way" to implement Logic. It's Control which tied with Spatial. Since Spatial can have various of Control, It's easy to extend it like so:
Spatial1.addControl(new AttributeControl());
// add a Control which do compute the Attribute for ya
Spatial1.addControl(new ContainerControl());
// add a Control which hide things when players are outside! <= Also called a portalControl
Spatial1.addControl(new ConversationControl());
// add a Control which support talking stuff , load XML , load saved name, registered value;

b. What you have to do :
* Choose a scripting language :
Groovy or Clojue or Jython , depend on your need and your personal skill in those languages.
My choice was Groovy since I know all the language but I'm dumb in all! :p . So I choose the language which is most well-supported in embedding in java. And may be the most powerful at the moment!

* Know the basic concept of scripting : (Sorry I just give Groovy links, maybe others monkeys can help me complete)


- How to setup things:

[java]import javax.script.*;
....
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("groovy");
engine.eval( new FileReader("myfile.groovy");[/java]
- How to register/ declare and binding:
[java]
// call groovy expressions from Java code
Binding binding = new Binding();
binding.setVariable("foo", new Integer(2));
GroovyShell shell = new GroovyShell(binding);
Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");
assert value.equals(new Integer(20));
assert binding.getVariable("x").equals(new Integer(123));
[/java]

Take a look at Groovy website :
http://groovy.codehaus.org/Embedding+Groovy
http://groovy.codehaus.org/Bean+Scripting+Framework

(Part 1 stop here cause it's too loooooooong ... :p)
1 Like

(Part2)

How to actually make things work:

Scripting is actually a method which can describe abstractly by an idiom “When things happen, read the scroll oh I mean the script …!” :stuck_out_tongue: May be you heard it from some epic tales !



That’s it! It provide a way to connect entities on the fly.



So basically one Actor just have sended a message by the system to notify that another object try to contact with it. The message contain an ObjectType so Actor know how to deal with the coming situation.



By being flexible in running Action (script) in the first Actor or the second Actor (the situation of The knife cut the Apple or vice versa ), we can create very complicate situation, extremely more than any “FSM” or “RuleBase” mentioned above!



My approach here is just a most simple mechanism, when the game grow, more complicated things come, but the basic can almost still the same…



# Declare and bind the most basic and important object:

  1. WorldManager and its Worker (s)…

    binding.setVariable(“worldManager”, app.getWorldManager());

    binding.setVariable(“simpleNPCWorker”, app.getWorldManager().getNPCSimpleWorker());

    binding.setVariable(“stageManager”, app.getStageManager());

WorldManager cares for creating, manipulating spatial and every lighting, physic stuffs but nothing related to logic, and acting,knowledge,point,attributes ,,,etc of the character.
simpleNPCWorker and other Worker(s) care for some simple task involve in the script affect acting, such as open door, turn on/off light, touch, rotate the billboard..
stageManager care for making decision between player and NPC through very simple rule, and the most powerful director affect the logic of the game, who can say "to the next level","kill that NPC immediately", it's the heavy carrier for the scripting system.

My thought: Code all of these class in java is a pretty good idea but I'm coming to do some part of stageManager in Groovy cause it provide more flexibilities .

That's enough for the basic system.
2) Bind the Main Character
binding.setVariable("mainHero", stageManager.getHero());

Similar as above, you code some part of the mainHero in java (hard code), such as basic movement, basic chase cam, basic weapon handler, remember to code them as good as you know they need to be extend in script !!!!!! Spend a few sec think about what I just said !

That's it, you should extend the movement , the chase cam, the magic fire and other things in script. The power is in your hand now!

3) Bind the "list" of NPC :
If there are a lot of NPC with a same type, you code all of them with the same script or decide to have a simple "goal-driven" or "FSM" (a simple one, OK)

Remember to provide the method to access each of NPC if need
and some random, un-similar, un-expected behaviors for more realistic feeling...

# XML are good but , what if JME SDK is awesome?
:p
In the SDK, you can add script Code through UserData, that's the method i'm doing now in my game.

Not necessary to make some extra XML and extra job for loading things for dialog. With a simple Groovy Editor which is support seamlessly in Netbean Platform and UserData in SceneComposer, you can make you Spatial move for real in notime, :p

Advertisment: My upcoming video of my game will show that feature which can be very interesting to watch! :p
1 Like

(Part3)

Sorry for my annoying persistent …



Thought we can still divide the logic management to 3 layers with the mechanism I describe above.


  • RuleBase : stageManager decide who to punish, who to reward in common way (or in law)
  • Scripting : Player/NPC interaction , Trigger , Dialog
  • FSM (or Goal-Driven): NPC behavior.



    Now consider this situation, and tell me what do you guys think of?


A group of guard NPCs are moving around and watch to prevent trespassing. 100 feet is the default sight which player is recognizable by a normal guard. An officer has 140 feet sight and the superior has impressive of 200 feet even in the dark!


1) The stageManager can provide intelligent in a form of awareness in "Guard rule" like:
// Guard rule
"NPC can see Player in (NPC.sight)"


and then provide notification to specific NPC if need.
[java]
// stageManager
for (NPC1 in GuardNPCList)
if (distance(player,NPC1)<NPC1.sight)
NPC1.alarm();[/java]

so stageManager must know that GuardNPC has "sight" attribute and "alarm" method?

2 ) Script can do :
// Guard script:
if (stageManager.find(player,this.sight)!=null) alarm();
// Ask the stage manager did he got a clear view of the player by ray checking or some...
or simpler :

if (distance(player,this.pos)<sight)!=null) alarm();
//It's more natural because only the guard know what he know ...

3) FSM do more deep interference to the object job :
[java]
// stageManager
for (NPC1 in GuardNPCList)
if (distance(player,NPC1)<NPC1.sight)
NPC1.setState("alarm");[/java]

[java]
// Guard FSM
switch (state)
case "alarm": { fireToTheSky(); ringTheBell(); }
...
[/java]

Thank you so much pspeed and atomix! :slight_smile: I am closer to end of the tunnel now. :stuck_out_tongue:

So, to clarify a few things. The game world in my team’s eyes is of medium size (<- semantically null statement right there :stuck_out_tongue: ). What I mean by this is that we want to have a landscape which seems large and explorable. However, the large part will very much be a illusion(using skybox, un-climbable mountains, etc.). Having that said we still want to have 2-3 villages and one bigger “city”, in which the events of the main story occur.

Currently we are in the brainstorming stage and programming/scripting/modeling is not an issue, however I like to know whats coming, hence all my research.

I’ll add on to this by clarifying our intentions with the game. The game is like you said some thing more of a learning experience,both for me and the members of the team. I think it’s a great way to learn programming, working in teams and all the other numerous skills that you would learn throughout the development cycle. If we see that we can create something decent and of value then I think we will be more than happy to sell the game for $5-$10 on steam or what not. However this is not the sole point of the project, and personally I would not be bothered if this merely becomes something for a portfolio or just a nice memory.

Once again thank you very much, there’s a huge amount of information in the replies above and it will take be a while to process all of it, in the mean time if anyone else has anything else to add please feel free :slight_smile:

@atomix: really good read. let me add what I have learned so far this week.



First of all a really good book on this topic: http://www.amazon.com/Scripting-Mastery-Premier-Press-Development/dp/1931841578/ref=sr_1_1?ie=UTF8&qid=1313315893&sr=8-1



The first chapters describe real problems that can be solved easily with scripting, and the main conclusion it makes: a game engine should not have any logic hardcoded about the game itself. Game Content is just another type of asset like models, textures, music. This way if you can build an engine that uses scripting in an efficient way, you are free to write as many games as you can, just change the “content”. :wink:



Also a good point in the book is that you should choose your language to fit your needs. It uses two different approaches: sequential and procedural. If you just need a command based scripting engine to describe your gui, then you are better off create your own processor for it. If you have to deal with variables and conditions / loops, then choose a procedural language like groovy, jython, closure or even javascript. Finally I made this latter work with my project nicely. I know the language from my web development experience, it can do everything I need right now, and it’s built into java. :slight_smile:



Though I’m still fighting to find the right way to create the host API, I’m already able to create scripted network listeners and yesterday I just created my first item skeleton through javascript. :slight_smile: The main advantage of javascript is it can be compiled later into java class files, just like groovy, so no performance is lost.