GUI's response time falling while connecting local clients

Hi, I’ve been trying to set up a lobby system for an RTS game. The basic idea is, one player launches the lobby as a host, and other clients join the lobby. Everything has been working fine until i started adding GUI components. Adding the ‘ready’ buttons worked, but when i tried adding SelectionBoxes (from TonegodGUI), strange things started to happen. When I launched one instance of the game and created the lobby as a host, the SelectionList’s worked fine. When another instance connected the game the response time for all gui elements in the LobbyAppState was around 5 sec. When all clients but the host disconnected, the long response time was still there. Only exiting to menu and entering the lobby once again fixed the response time. Sitll if somebody connected the GUI stopped working properly again.

I’m leaving the link to GitHub repo. here: https://github.com/lordkuba/jme3_test/commit/4418fda0bcb5a3bdccd8b19241076e201b2200c4

I created it specificly for asking this question.
The important file is LobbyAppState.java

The problem must be caused by the SelectionBoxes, but considering my lack of expirience it may be anything.

EDIT: The frame rate stayed at ~60

Not sure… that’s a lot of code to go through.

Your best bet is to either come up with a simpler example that shows the issue or run the profiler against your app to see where the time is going when it slows down.

I’ve used toneGodGUI’s selectListBox for my lil game’s lobby when it had a multiplayer lobby and had no such problem, so I don’t think it’s related to problems with that control.

Could it be that it has an onChange event that runs in circle? Have you tried disabling the listening while you update the list content and then enabling it again? Very sorry if it’s a stoupid idea :D.

What do you mean by “in a circle”?? I create the selectionBox in the initialize method and override the onChange method. If i understand correctly it executes only if something changes, and only once.

About disabling listening: No, but i believe it will have no effect because updating the list creates the SelectionBox object(when the client enters the LobbyAppState). The is no code at the moment to broadcast the changes made to other clients, so it’s not the network’s fault.

Another thing I don’t quite understand is this error i get when creating the selectboxes in the LobbyAppState constructor:

    kwi 20, 2015 7:03:22 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
	at mygame.LobbyAppState$2.onChange(LobbyAppState.java:148)
	at tonegod.gui.controls.lists.ComboBox.setSelectedWithCallback(ComboBox.java:382)
	at tonegod.gui.controls.lists.ComboBox.setSelectedIndexWithCallback(ComboBox.java:364)
	at tonegod.gui.controls.lists.ComboBox.pack(ComboBox.java:296)
	at tonegod.gui.controls.lists.ComboBox.addListItem(ComboBox.java:216)
	at mygame.LobbyAppState.<init>(LobbyAppState.java:157)
	at mygame.Main.simpleInitApp(Main.java:69)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:226)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:130)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:207)
	at java.lang.Thread.run(Thread.java:744)

BUILD SUCCESSFUL (total time: 8 seconds)

the part of code that fails is:

for(int i = 0; i < MAX_PLAYERS; i++)
        {
            teamLabels[i] = new SelectBox(this.screen, "TEAM" + i, new Vector2f(200, (this.app.getContext().getSettings().getHeight() - 650) + i*50), new Vector2f(100, 35))
            {
                @Override
                public void onChange(int selectedIndex, Object value) 
                {
                    if(Integer.parseInt(this.getUID().replace("TEAM", "")) == Main.client.getId())
                    {
                        Main.connectedPlayers.get(Integer.parseInt(this.getUID().replace("TEAM", ""))).setTeam(selectedIndex);
                    }
                }
            };
            
            System.out.println("TEAM LABELS FIREDD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            
            teamLabels[i].addListItem("No Team", "0");
            teamLabels[i].addListItem("Team 1", "1");
            teamLabels[i].addListItem("Team 2", "2");
            teamLabels[i].addListItem("Team 3", "3");
            teamLabels[i].addListItem("Team 4", "4");
            teamLabels[i].addListItem("Team 5", "5");
            teamLabels[i].addListItem("Team 6", "6");
            teamLabels[i].addListItem("Team 7", "7");
            teamLabels[i].addListItem("Team 8", "8");
            
            teamLabels[i].hide();
            teamLabels[i].move(0, 0, 1.0f);
            
            rootGuiElement.addChild(teamLabels[i]);
        }

If i cut out the addListItem part it runs correctly and shows the selection boxes. When I add it, it shows a null pointer exception in the first IF statement (“if(Integer.parseInt …)”). But then in the error log it points to the addListItem line.
I don’t really know what’s going on!

Which line is that?

Before that line, put some System.out.printlns of the values. NPEs are the easiest exceptions to fix because they show you exactly where the problem is.

It;s the first If statement.
I already followed that path earlier. It lead me to the freezing part. Main.client appears to be null as if not yet initialized. But if you look into the link in github, im using a similar for loop to init the CheckBoxes. There i have the same if statement and it throws no null pointer excepion. Th only problem is the addListItem which crashes the game’

EDIT: You can find the whole class LobbyAppState.java in the link in the original post

Well, it doesn’t just appear to be… it actually is null… you just have to figure out why.

Not sure where you are setting it and there was a lot of code, as I recall. If you are setting it as a connection listener then it might not be set until later… but really, you shouldn’t even be adding your lobby app state until after you are connected… right about the same place you set Main.client I guess.