Hi, welcome to the community
Yes, JMonkey engine is unit testable even with current implementation!! Just like other Java application…
[ I’m also admit that I’m a fan boy of google java tools because you may later recognize it, let’s name Guava, Guice and Caliper. But here come the goods…]
I see you are a new comer and relatively new with Java tech, JME3 tech so i assume you asking for serveral questions about concepts, how tos and why should i together…
1)What should be tested in a Game for god sake? What is a Testcase look like?
2)How do I make something from outside? How do I inject data, assets, codes and my drugs…?
3)Why should I use this techs but not other.
1)What should be tested in a Game for god sake?.. What a Testcase look like for empty brainer…
Predicates
Predicate is some question you may want to know if your game is or is not, a condition which at one state the game's objects may sastify. Ex: In this area there should be more than ten monsters?
Functions
Functions are Predicates usually work with a formal system. It usually look like if you finish StateA with a condition then should be StateB.
Ex: You may want to know if a you exchange an item for 5$, you should have 5$ in your pocket. After MainMenuState should be InGameState
Behaviours
Behaviours are more attribiary things, which can be composed by several Predicates and Functions together. Behaviour usually need a Coordinate system or a Specification to resolve.
Ex: Your character should turn left if you hit Left key. But it stay still or jump up.
Graphics
Graphics behaviours and graphics aspects are the most difficult thing to be tested.
Ex: Your character should turn blue when you hit the blue bubble.
When it come to graphics, the test case and the way machine (by instructions of developer) actually do to capture the state of the game may be various and pretty ridiculous. For example, if you want to check if your character turn blue right after the hit, you capture the screenshot for the specific moment and save out as name “Check if character is blue”. A Tester (human or machine) later come to the server and just check and report the issue back.
That’s said in general, a Test can be about any thing… but here I will share some of my experiences working in a large scale game issues tracking system, from that you may have an idea of what you want as a result of a Test:
- The Tests are scheduled incremental with development phases and involve peoples and machines.
- There is already quite tons of specifications and checklist for a game to check to.
- The issues if found also be reported back in a big server with images, sounds, description and even data dump to help the tester, developers visualize or reproduce the issue again.
Now talking about code side only, and unit test only, about functions for example:
“Did the StateA change to another StateB with my input?”
-What you may already had are JUnit and Mockito.
You may need Guice for DI (instead of Spring in the name of holy monkey…) and may be also Capiler.
Steps:
@Test
public void stateChangeTest() {
class StateA{
private ActionListener actionListener = new ActionListener() {
public void onAction(String name, boolean keyPressed, float tpf) {
if (name.equals("changeState") && !keyPressed) {
stateManager.remove(StateA.getInstance());
stateManager.attach(StateB.getInstance());
}
}
};
}
SimpleApplication app=new SimpleApplication(“MyApp”){
public void simpleInit(){
StateA firstState=StateA.getInstance();
stateManager.attach(firstState);
inputManager.addMapping("changeState", new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addListener(firstState.getInputListener(), "changeState");
}
public void simpleUpdate(float tpf){
assertTrue (stateManager.hasState(StateB.class));
}
app.start(JmeContext.Type.Headless);
}
This kind of TestCase are quite boring and to some people it’s even ridiculous. What you may see it’s not touch real-time aspects and graphics of a game yet… Later, now just move on
- How do I make something from outside? How do I inject data, assets, codes and my drugs…?
First, better get some patterns in JME3 straight.
Hooks:
you should learn that the Application is embeded in a Context and obey a cycle and timing ticks from the SystemListener. Your code better hook within Applications update, State’s updates, Control updates…
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:update_loop
Compose things:
A lot of things are Spatials, composed Spatials result in a Node (extends Spatial).
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:spatial
Load things:
Assets are loaded via AssetManager via
https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:asset_manager
Now if you want to do something from the outside. Yes, I’m talking about Dependency injection. DI somethings are cool but not very suitable with Application as the Target.
My “milion dollars advice” is to make your own Context class and inject things into it instead, and later interprops with JME3 system.
[java]
class MyGame extends SimpleApplication{
class Context{
@Inject
EventBus eventBus;
@Inject
LoadingCache<AssetKey,Object> assets;
@Inject
Set<Services> plugins;
@Inject
Set<Manager> managers;
}
}
[/java]
In this example:
I have a working Application which is ready to use and fully function at the time of injects.
I use Guava Cache and Guice to setup assets.
I use Guice to locate Services with Multibindings
I use Guice Scope.Singleton inject to setup my Managers.
Those Guice Module of course using Application facilities like AssetManager, StateManager, InputManager, RenderManager underlying.
Futher more you can rig up Input with Annotations inject, Make Cinematic with Event inject and unit test those…
IF you still insist to wrote up an application which use DI by default, learn an sostiphicated DI framework like Guice, you can see a lot of similaries of abtractions phases of Application with Guice internal phases to rig those two together. If you go along this path, you did exactly what I did with my game framework for large scale game called Atom framework :).
Note: Some JME3 phases may look alike, work alike and abstractional similar to those in DI and IoC phases but not for general Java usage, it work with JME3 specific data types. So you see Bootstrap, Loading, Injections, Composing… with different names only.
Anyway, hope this help you in getting your head around the problem. Nice day.