[iOS] Multiple issues (and solutions/workarounds) trying to run jme3 app

yes I am testing right now, and it look all good up to now, I’m well impressed
will report back when I’ve published it on App Store

1 Like

Update 1:
Hi, so for the first test which was to compile and run the basic game template with a box and font using the nifty example.

When I compiled it, I did have to add the empty class for awt as you suggested then it compiles fine. It also runs perfectly on iPhone11 running iOS 14.4 and iPad 3 running iOS 9.5
The official verdict is. “BACK OF THE NET!!!”

1 comment would be that ios.jar.excludes in ios.properties probably needs a revisit. I added this line to cut down the size a bit.

lwjgl-platform-natives-*.jar, \

Also, I used XCODE 12.4 (latest) on Catalina for iOS v14.4 to compile it but it’s worth noting that the last version of XCODE that includes JAVAVM framework headers is XCODE 12.1
Therefore I downloaded and extracted 12.1 (you don’t need to install it) and copied the folder JavaVM.framework from there and placed it inside XCODE12.4
I suppose it probably should be held somewhere else locally for when Xcode is upgraded but I didn’t want to make any changes to the JME project while I was testing.
Anyway, that worked.

I’m now going to incorporate it into Chatter Games and re-publish on App Store and will let you know.

1 Like

Thanks for the update.

I’m glad the simple test worked properly for you. What really surprises me is that you run it properly in iOS 9 and you didn’t get the " _objc_alloc_init" error. Maybe there’re some differences between real devices and the simulator :thinking:

Yes, all lwjgl stuff could be removed to reduce app size, I didn’t notice this setting in ios.properties.

About latest XCode not including java headers, maybe we should add this in the ios documentation page

Having latest changes into a real game will be awesome so we will know if there’s any issue with it. Waiting for your comments :wink:

1 Like

Ok, so started re-working the UI for iOS as I want to use 1 UI for all devices. I wrote a full native UI for iOS but it’s too time consuming to mantiain two.

I’ve been using ToneGodGUI because Nifty was horrible to use as the editor has more bugs than “I’m a celebrity get me out of here”.
Now I’ve had another try with Nifty, I’ve remembered how bad is it especially as the IDE editor wont work anymore and hasn’t for several years.
Do you know if Lemur works in iOS as that seems to now be the UI of choice. ToneGodGUI won’t run on iOS and I think it’s a proguard problem but I can’t get to the bottom of it. So I’ll try Lemur.

Note: while I don’t have direct experience with iOS or Android, I know that the thing that trips folks up on Android is the groovy styling language. So I just thought I’d point out that Lemur does not require the groovy styling if you just style things in Java code instead.

…other than that, Lemur is nothing special and is just another code library using JME directly. (Edit: it doesn’t even use any custom shaders or anything… by design for exactly these sorts of reasons.)

I’ve not tested anything apart from niftygui. Everything I’ve done with it was by manual editing xml files and java code so I don’t have experience with the editor although I’ve read that it’s not working properly

For Lemur, if you look at the “Getting Started” guide:

Skip the section: “Initializing a Default Style”

…and everything else should basically create an unstyled GUI that works. Probably the System.out.println() in the example won’t do much, though.

Reduced example desktop app:

package mygame;

import com.jme3.app.SimpleApplication;
import com.simsilica.lemur.Button;
import com.simsilica.lemur.Command;
import com.simsilica.lemur.Container;
import com.simsilica.lemur.GuiGlobals;
import com.simsilica.lemur.Label;

public class GuiDemo extends SimpleApplication {

    public static void main( String... args ) {
        GuiDemo main = new GuiDemo();
        main.start();
    }           
    
    @Override
    public void simpleInitApp() {
            
        // Initialize the globals access so that the defualt
        // components can find what they need.
        GuiGlobals.initialize(this);
            
        // Create a simple container for our elements
        Container myWindow = new Container();
        guiNode.attachChild(myWindow);
            
        // Put it somewhere that we will see it
        // Note: Lemur GUI elements grow down from the upper left corner.
        myWindow.setLocalTranslation(300, 300, 0);
    
        // Add some elements
        myWindow.addChild(new Label("Hello, World."));
        Button clickMe = myWindow.addChild(new Button("Click Me"));
        clickMe.addClickCommands(new Command<Button>() {
                @Override
                public void execute( Button source ) {
                    // Do something
                }
            });            
    }    
}

…translate as appropriate.

1 Like

I have noticed an issue with the iOS implementation. Sorry I should have noticed before but it was on a black background so I didn’t spot it was not stretching to the full size.

Also, if found the bit of code that fixes the issue with the rotate event not resizing on the first time in. You are correct to check if the renderer has been initialised or not, because if you try to do a reshape then it will crash with a null renderer that hasn’t been created yet. This is more apparent on slower devices.

But you can’t just ignore the reshape request because it will never happen until the device is either rotated manually or the app comes back from the background.

Therefore I just store the reshape width and height for the next cycle or whenever the renderer is avsilable.

@Override
public void appReshape(int width, int height) {
    logger.log(Level.FINE, "JmeAppHarness reshape");
    AppSettings settings = app.getContext().getSettings();
    settings.setResolution(width, height);
    if (renderer != null) {
        app.reshape(width, height);
        resizePending = null;
    } else {
        resizePending = new Vector2f(width, height);
    }

    if (input != null) {
        input.loadSettings(settings);
    }
}

In the App Draw method we just see if there is a stored reshape request and action it.

@Override
public void appDraw() {
    logger.log(Level.FINE, "JmeAppHarness appDraw");
    if (renderer == null) {
        JmeContext iosContext = app.getContext();
        renderer = (GLRenderer)iosContext.getRenderer();
        renderer.initialize();
        input = (IosInputHandler)iosContext.getTouchInput();
        input.initialize();
    } else {
        if(resizePending != null) {
            appReshape((int)resizePending.x, (int)resizePending.y);
            resizePending = null;
        }
        app.update();
	    if (autoFlush) {
            renderer.postFrame();
        }
    }
}

I declare the resize pending variable as

protected Vector2f resizePending = null;

I don’t understand where the issue is. The code you’re publishing is the exact same code of current JmeAppHarness (sdk/JmeAppHarness.java at master · jMonkeyEngine/sdk · GitHub)

Also the reshape request is not ignored but postponed to next draw event having a proper renderer

Sorry went on the wrong track. See if this happens on yours and might be an answer why some devices don’t seem to update/fire the rotate notification.

I found that devices from iOS 10 onwards don’t seem to first the notification for rotate when running from XCODE but if you disconnect the device and try running the app normally it works. This is probably a bug with XCODE. Can you check if this is only happening to me or is it a general issue?

Sorry for the late reply

At least for all my tests, mostly using the simulator because I only own an old iPhone 5S the rotate event was run and the screen was properly resized (in different simulators running different iOS releases and in the physical iPhone). If I can get other devices to check I’ll post here with my results

About the iOS >=10 + xcode, it hasn’t happened to me, in my iphone running 12.x it worked connected and disconnected. Same here, if I ever get more devices I’ll get back with the results