[Solved] Windows close when new player connects

Hey monkeys,



I’m currently working on a multiplayer-Game and everything seemed to work fine… until yesterday evening:



when I start my server and connect clients to him random client windows close. example:

start client

connect player1

connect player2

connect player3 → player1 closes down



there is no System behind the client shutting down like ‘every 3rd client kicks the first connected’. Whenever i connect another client 0-3 other windows close down.



the closing window throws the following error:

Aug 13, 2012 4:56:24 PM com.jme3.app.Application handleError

Schwerwiegend: Uncaught exception thrown in Thread[LWJGL Renderer Thread,6,main]

java.lang.IllegalStateException: Scene graph is not properly updated for rendering.

State was changed after rootNode.updateGeometricState() call.

Make sure you do not modify the scene from another thread!

Problem spatial name: bubblehead-ogremesh

at com.jme3.scene.Spatial.checkCulling(Spatial.java:260)

at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:636)

at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:654)

at com.jme3.renderer.RenderManager.renderScene(RenderManager.java:654)

at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:965)

at com.jme3.renderer.RenderManager.render(RenderManager.java:1016)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:251)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:184)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)

at java.lang.Thread.run(Thread.java:722)



Aug 13, 2012 4:56:24 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup

Information: Deleting objects and invalidating state

AL lib: ReleaseALC: 1 device not closed

BUILD SUCCESSFUL (total time: 31 seconds)




I’m pretty much sure that theres a problem with how i add the new connected players to the game. currently it works as followed:

client recieves locationDatas(playerId/location/direction/…) from the server. and passes them on to my updatePlayerList method:

[java] public void updatePlayerList(LocationData datas){

if(multiplayerData[datas.getPlayerId()]==null&&datas.getPlayerId()!=client.getId()){

System.out.println(“new player”);

players[datas.getPlayerId()]=player2.clone();

playerNode.attachChild(players[datas.getPlayerId()]);

}

multiplayerData[datas.getPlayerId()]=datas;

}[/java](if the client ‘knows’ the player the multiplayerData[] is updated(this is the array where i store all players locations etc), otherwise a new player is attached to the playerNode, which is attached to the rootNode. I used an Spatial[] named players to make moving arround players more easy.)



another problem i faced was: How to add a new Player to the game the right way?

as you see i just made an array for all players. When a player logs in, he gets his own position in the array depending on his login id. But when a player logs out and in again he gets a new id. Since i want my server to run all day long the array would grow…and grow…and grow. since IDs are not reused and a lot of useless data will be stored on the server. (ehm…seems like I’m loosing track, sorry)





how did/would you, dear monkeys, manage adding/removing players/espacially spatials to the scene?

I would take a look at the wiki section about callables and multi-threading. I don’t think you can modify the scene graph from another thread directly.

1 Like

See this thread, the same solution will solve your issue.



http://hub.jmonkeyengine.org/groups/physics/forum/topic/concurrentmodificationexception-1/

1 Like

ty a lot. I’ll have a look at it :slight_smile:

again thanks a lot. thou i have no idea, what exactly I’ve done here its working now:

i turned

[java]public void updatePlayerList(LocationData datas){

if(multiplayerData[datas.getPlayerId()]==null&&datas.getPlayerId()!=client.getId()){

System.out.println(“new player”);

players[datas.getPlayerId()]=player2.clone();

playerNode.attachChild(players[datas.getPlayerId()]);

}

multiplayerData[datas.getPlayerId()]=datas;

}[/java]



into



[java] public void updatePlayerList(final LocationData datas){

if(multiplayerData[datas.getPlayerId()]==null&&datas.getPlayerId()!=client.getId()){

System.out.println(“new player”);

players[datas.getPlayerId()]=player2.clone();



app.enqueue(new Callable<Void>() {

public Void call() throws Exception {

playerNode.attachChild(players[datas.getPlayerId()]);

throw new UnsupportedOperationException(“Not supported yet.”);

}

});



}

multiplayerData[datas.getPlayerId()]=datas;

}[/java]



again. i have no idea if this is the way u wanted me/acx234(the guy on the other topic) to solve the problem BUT it’s working



let me tell you what i think it’s doing and them please tell me wether I’m right or wrong:

before:

i tried tu just add a Spatial to the rootNode/playerNode and this made the program stuck since he was rendering and suddenly had to render 1 mode object but since he already started rendering he gets an error

now:

i enqueue the action of adding the spatial so it’s added when the new frame(?!?) is about to be rendered//new loop starts



however. why do I have to throw an exception and what kind of exception should i throw?



(ty again)

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading

feels like I’m getting beaten up from you guys with those multithreading-stuff :smiley: i should probably put my project to rest for a day or two and care about the almighty multithreading :slight_smile:



thanks so far