Questions about the engine

Some (hopefully nontrivial) questions about the engine (JME3 on Android):


  1. When will the engine go stable for Android?



    1.5)General question: Would you consider the current state of JME3 stable enough to build a commerical game?


  2. Will there be a big difference between the beta and the stable release?

    Can the beta project files be used for the stable version without weeks of conversion?


  3. The documentation says the engine converts TouchEvents to mouse clicks, is multitouch still possible? (or are some TouchEvents lost if there is more than one per frame)


  4. Is GIT integration happening anytime soon?


  5. Are there any limitations to the Android version vs. the Deskop version? (Shaders, App lifecycle management, etc.)

    (Except the obvious ones like, less RAM etc.) Are they documented anywhere? Like ‘known quirks’ or something like that.


  6. Does the config chooser look for CSAA? It comes with very little cost on Tegra GPUs. (CSAA is the only option for Tegra GPUs, MSAA is not supported)

    ==> Looks like somebody thought about that but gave up on it? http://hub.jmonkeyengine.org/groups/android/forum/topic/filterpostprocessor/



    That’s all. I guess.
  1. Not even the gods know this

    1.5) Yes there are already commercial games available: https://play.google.com/store/apps/details?id=com.rampage.stacked&hl=en for example
  2. Yes, or without much effort, depends how much changes
  3. Multitouch is possible AFAIK
  4. Its been talked about, but nothing set in stone yet
  5. The android manual lists the main ones. Basically if you want a playable game on android for the majority of platforms, then you need to limit the amount of everything really, as its a weaker platform in general. Its best to have just a few objects, with little to no lighting, and use simple shapes with bullet, for optimum performance.
  6. Dunno
1 Like

1.5) I tried it already, it opened with a black screen and after one second it quit without any error messages, Asus Transformer Infinity (TF700), Android 4.0.3

Also the (now quite old?) demos don’t work for me (the jMonkeyengine examples in the store), they only work if I disable VBOs and the last two demos didn’t work at all.

The Desktop examples look really good, but the Android ones seem hardly working.

@mechanical said:
1.5) I tried it already, it opened with a black screen and after one second it quit without any error messages, Asus Transformer Infinity (TF700), android 4.0.3

Erf...it' s been tested on like 8 or 9 different hardware with adroid version going from 2.2 to 4.0.3 and never had this issue....
You sure logcat does not give some errors?

Other than that, there are plenty of leads to enhance the engine on android and they are currently under study/development.
Usually fill rate is very poor, so shading is very slow, you won't be able to run something designed for desktop without some adaptation.

Baking lighting as much as possible into texture is preferable. Only use lighting on dynamic object and make sure they never get full screen. Use vertex lighting as much as possible instead of pixel lighting.

Edit : and as you witnessed unfortunately, it's a bit difficult to make sure the game runs fine on every hardware/android version combination. It's nice to have a lot of friends with different android powered hardwares ;)

I know it’s offtopic to post you a logcat log, but there you go:



Native resolution of the tablet: 1920x1200, 1920px-72px (the emulated hardware buttons) = 1848 px for your app



All I did was tapping the app icon, there was no input until the app closed itself.

Android did not issue any textbox telling me the app had to be force closed.



Made with the catlog app.

(only process numbers 219 and 25606 are shown, afaik there are no important warnings or errors in the omitted log messages)



07-09 23:35:32.580 I/ActivityManager( 219): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.rampage.stackeddemo cmp=com.rampage.stackeddemo/.MainActivity bnds=[216,78][360,222]} from pid 547

07-09 23:35:32.650 I/ActivityManager( 219): Start proc com.rampage.stackeddemo for activity com.rampage.stackeddemo/.MainActivity: pid=25606 uid=10100 gids={3003, 1015}

07-09 23:35:32.660 I/dalvikvm(25606): Turning on JNI app bug workarounds for target SDK version 8…

07-09 23:35:33.010 I/JmeSystem(25606): INFO JmeAndroidSystem 23:35:33 Running on jMonkeyEngine 3.0.0 Beta

07-09 23:35:33.070 D/libEGL (25606): loaded /system/lib/egl/libEGL_tegra.so

07-09 23:35:33.100 D/libEGL (25606): loaded /system/lib/egl/libGLESv1_CM_tegra.so

07-09 23:35:33.100 D/libEGL (25606): loaded /system/lib/egl/libGLESv2_tegra.so

07-09 23:35:33.110 I/OGLESContext(25606): INFO OGLESContext 23:35:33 Display EGL Version: 1.0

07-09 23:35:33.110 I/AndroidConfigChooser(25606): JME3 using best EGL configuration available here:

07-09 23:35:33.110 I/AndroidConfigChooser(25606): JME3 using choosen config:

07-09 23:35:33.110 I/AndroidConfigChooser(25606): EGL_RED_SIZE = 8

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_GREEN_SIZE = 8

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_BLUE_SIZE = 8

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_ALPHA_SIZE = 8

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_DEPTH_SIZE = 16

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_STENCIL_SIZE = 0

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_RENDERABLE_TYPE = 5

07-09 23:35:33.120 I/AndroidConfigChooser(25606): EGL_SURFACE_TYPE = 3175

07-09 23:35:33.120 W/AndroidHarness(25606): WARNING AndroidHarness 23:35:33 Resolution from Window: 1.200, 1.848

07-09 23:35:33.210 D/dalvikvm(25606): GC_FOR_ALLOC freed 171K, 3% free 9263K/9543K, paused 41ms

07-09 23:35:33.210 I/dalvikvm-heap(25606): Grow heap (frag case) to 10.594MB for 1536016-byte allocation

07-09 23:35:33.250 D/dalvikvm(25606): GC_FOR_ALLOC freed 2K, 3% free 10761K/11079K, paused 29ms

07-09 23:35:33.290 D/dalvikvm(25606): GC_CONCURRENT freed 3K, 3% free 10850K/11079K, paused 4ms+2ms

07-09 23:35:33.310 I/AndroidHarness(25606): Splash Screen Created

07-09 23:35:33.310 I/AndroidHarness(25606): onStart

07-09 23:35:33.310 I/AndroidHarness(25606): onResume

07-09 23:35:33.320 I/AndroidHarness(25606): onPause

07-09 23:35:33.320 I/JmeSystem(25606): INFO JmeAndroidSystem 23:35:33 Storage Folder Path: /mnt/sdcard/Android/data/com.rampage.stackeddemo/files

07-09 23:35:33.330 I/JmeSystem(25606): INFO JmeAndroidSystem 23:35:33 Storage Folder Path: /mnt/sdcard/Android/data/com.rampage.stackeddemo/files

07-09 23:35:33.340 I/AndroidHarness(25606): onStop

07-09 23:35:33.340 I/AndroidHarness(25606): onDestroy

07-09 23:35:33.340 I/Process (25606): Sending signal. PID: 25606 SIG: 9

07-09 23:35:33.350 I/WindowManager( 219): WIN DEATH: Window{41a1b868 com.rampage.stackeddemo/com.rampage.stackeddemo.MainActivity paused=false}

07-09 23:35:33.350 I/ActivityManager( 219): Process com.rampage.stackeddemo (pid 25606) has died.

07-09 23:35:33.350 W/ActivityManager( 219): Force removing ActivityRecord{41a4ae88 com.rampage.stackeddemo/.MainActivity}: app died, no saved state

1 Like

uh…the app just shut down after starting :(. WTF…??



Thanks anyway for that log.

@nehon said:
uh....the app just shut down after starting :(. WTF..??

Thanks anyway for that log.

Before onStart() was called, the app only had 1/2 MB memory to start with (3% of 11079K). Probably once jME3 tried to initialize it wanted to allocate a lot more than 1/2 MB ...
  1. I’m using multi-touch successfully for 2 virtual joysticks. JME returns a pointerID that you can use to track which touch event the action is associated with.



    [java]

    private Integer verticalPointerID = null;

    private Integer horizontalPointerID = null;



    inputManager.addMapping(“Touch”, new TouchTrigger(TouchInput.ALL));

    inputManager.addListener(this, new String[]{“Touch”});



    public void onTouch(String name, TouchEvent event, float tpf) {

    boolean consumed = false;



    navClickLocation = new Vector2f(event.getX(), event.getY());



    switch (event.getType()) {

    case DOWN:

    if (!verticalMouseDown && verticalPointerID == null) {

    if (verticalNavStick.checkSelect(navClickLocation)) { // is the touch event on top of the vertical joystick

    verticalPointerID = event.getPointerId(); // record pointerID for MOVE and UP events

    verticalMouseDown = true;

    verticalNavStick.updateStick(0f, navClickLocation.y); // update vertical joystick graphics rotation

    for (NavigationListener navListener: navListeners) {

    navListener.onNavigationUpdate(verticalMouseDown, verticalNavStick.getNavDirectionPercent().add(horizontalNavStick.getNavDirectionPercent())); // send joystick movement to vehicle to update acceleration

    consumed = true;

    }

    }

    }

    if (!horizontalMouseDown && horizontalPointerID == null) {

    if (horizontalNavStick.checkSelect(navClickLocation)) { // is the touch event on top of the horizontal joystick

    horizontalPointerID = event.getPointerId(); // record pointerID for MOVE and UP events

    horizontalMouseDown = true;

    horizontalNavStick.updateStick(navClickLocation.x, 0f); // update horizontal joystick graphics rotation

    for (NavigationListener navListener: navListeners) {

    navListener.onNavigationUpdate(horizontalMouseDown, verticalNavStick.getNavDirectionPercent().add(horizontalNavStick.getNavDirectionPercent())); // send joystick movement to vehicle to update steering

    consumed = true;

    }

    }

    }

    if (!consumed) {

    for (SceneActionListener sceneActionListener: sceneActionListeners) { // touch not a joystick action, do other scene actions

    sceneActionListener.onSceneAction(

    SceneActionListener.ActionType.ACTION,

    true,

    tpf,

    navClickLocation

    );

    }

    }

    break;

    case MOVE:

    if (verticalMouseDown && verticalPointerID == event.getPointerId()) { // pointerID matches DOWN event for vertical joystick

    if (verticalNavStick.checkSelect(navClickLocation)) { // is the touch event on top of the vertical joystick

    verticalNavStick.updateStick(0f, navClickLocation.y); // update vertical joystick graphics rotation

    for (NavigationListener navListener: navListeners) {

    navListener.onNavigationUpdate(verticalMouseDown, verticalNavStick.getNavDirectionPercent().add(horizontalNavStick.getNavDirectionPercent())); // send joystick movement to vehicle to update steering and acceleration

    consumed = true;

    }

    }

    }

    if (horizontalMouseDown && horizontalPointerID == event.getPointerId()) { // pointerID matches DOWN event for horizontal joystick

    if (horizontalNavStick.checkSelect(navClickLocation)) {

    horizontalNavStick.updateStick(navClickLocation.x, 0f); // update horizontal joystick graphics rotation

    for (NavigationListener navListener: navListeners) {

    navListener.onNavigationUpdate(horizontalMouseDown, verticalNavStick.getNavDirectionPercent().add(horizontalNavStick.getNavDirectionPercent())); // send joystick movement to vehicle to update steering and acceleration

    consumed = true;

    }

    }

    }

    break;

    case UP:

    if (verticalMouseDown && verticalPointerID == event.getPointerId()) { // pointerID matches DOWN event for horizontal joystick

    verticalPointerID = null; // reset pointerID

    verticalMouseDown = false;

    verticalNavStick.reset(); // reset joystick graphics to center position

    for (NavigationListener navListener: navListeners) {

    navListener.onNavigationUpdate(verticalMouseDown || horizontalMouseDown, verticalNavStick.getNavDirectionPercent().add(horizontalNavStick.getNavDirectionPercent())); // send joystick movement to vehicle to zero out acceleration

    consumed = true;

    }

    }

    if (horizontalMouseDown && horizontalPointerID == event.getPointerId()) { // pointerID matches DOWN event for horizontal joystick

    horizontalPointerID = null; // reset pointerID

    horizontalMouseDown = false;

    horizontalNavStick.reset(); // reset joystick graphics to center position

    for (NavigationListener navListener: navListeners) {

    navListener.onNavigationUpdate(verticalMouseDown || horizontalMouseDown, verticalNavStick.getNavDirectionPercent().add(horizontalNavStick.getNavDirectionPercent())); // send joystick movement to vehicle to zero out steering

    consumed = true;

    }

    }

    if (!consumed) {

    for (SceneActionListener sceneActionListener: sceneActionListeners) { // touch not a joystick action, do other scene actions

    sceneActionListener.onSceneAction(

    SceneActionListener.ActionType.ACTION,

    false,

    tpf,

    navClickLocation

    );

    }

    }



    default:

    break;

    }



    }



    [/java]
2 Likes