Networking woes

@Empire Phoenix There is a reason networking is said to be around 4-10times harder. What you could do is just screw a good networking code and use objectstreams + tcp, and patch everything together for a first game. Then after that see the errors and rewrite around 80% of it.(You will do this anyway if you want to have good code)

I suspect that I’ve essentially got the networking bit fixed up. I can send and receive several types of messages, and I think I understand how it all works. (once again, I really appreciate all the help.) The issue now is that I never knew that multithreading was ever going to be an issue. Like I said, I’m fairly experienced with Flash Actionscript, but that handled multiple chains of logic for me. Honestly, when I got the networking thing down, I thought I could proceed with building my test up, unaware that only initialise and update can modify the scene.

If you can help me figure this out, I’ll be out of your hair until the next totally unexpected thing comes up. :slight_smile:

(Sidenote: Yeah, this thing will probably go through quite a few rewrites until I’m happy.)

Well just get acces to your main class, a (dirty but simple) solution would be in simpleinit

public static MyApplication INSTANCE;


simpleInit(){
INSTANCE = this;
}

then you can access instance from everywhere. (When your project grows larger you will probably see the downsides of this, but untill then you can continue, and learn more, so don’t worry for now.

Darnit, it’s still giving me an error. Am I putting the code in the wrong place?

(I took your instance advice almost verbatim.)

[java] private class ClientHandler implements MessageListener<Client>
{
public void messageReceived(Client source, final Message message)//if a message is received,…
{
//…some irrelevant stuff before this…
if (message instanceof NewPlayerMessage)
{
INSTANCE.enqueue(new Callable<void>()
{
public void call() throws Exception
{
playerObject newPlayer = new playerObject();
// do something with the message
NewPlayerMessage instructions = (NewPlayerMessage) message;

                    newPlayer.setPlayerName(instructions. getName());
                    newPlayer.setPlayerLocation("entry_point");

                    //set a ton of stuff to do with my extension of a node, newPlayer


                    players.add(newPlayer);
                    //return null;
                }
            });
            
            
                   
            
            
            System.out.println("new player");
        }
    }
}

[/java]

Well you shouldn’t take them work by word, but try to get what the idea behind this is. In this case try to understand why I made that field static accessible

That code shouldn’t even compile. Try to solve the compile time errors first, they are directly shown in the editor (for example you put void with a lowercase first letter, you need the object Void with a capital letter).

@Empire Phoenix said: Well you shouldn't take them work by word, but try to get what the idea behind this is. In this case try to understand why I made that field static accessible
A static field belongs to a class, not an instance. Therefore, it is accessible from more places, as a specific instance does not have to be referenced or created. Yeah, thanks! I'm doing it almost word-for-word... I replaced the class name with the name of my own class, commented it for my future understanding, and inserted the proper segment into my init.

Out of curiosity, (for future understanding, I’m more than happy to use this trick now) why shouldn’t I create a static copy of the project? Is it just too much information flowing around?

@normen said: That code shouldn't even compile. Try to solve the compile time errors first, they are directly shown in the editor (for example you put void with a lowercase first letter, you need the object Void with a capital letter).
*Facepalm* OK, will fix that and get back to you in a few minutes.

I was talking about a compile-time error, but did not have the proper vocabulary to describe it. I could not understand the error the editor presented me with, and consequently could not further tinker with it. (though I did try)

No more errors showing in the editor. Fingers crossed.

By the way, is there any snazzy term for a “facepalm error”? I know IT has BTCAK (between the keyboard and chair)

Curses. OK, here’s my error:
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,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: Root Node

Any ideas? As I understand it, this should work, because I’m using a callable…

[java]

private class ClientHandler implements MessageListener<Client>
{
public void messageReceived(Client source, final Message message)//if a message is received,…
{
if (message instanceof NewPlayerMessage)
{
INSTANCE.enqueue(new Callable<Void>()
{
public Void call() throws Exception
{
playerObject newPlayer = new playerObject();
// do something with the message
NewPlayerMessage instructions = (NewPlayerMessage) message;

                    newPlayer.setPlayerName(instructions. getName());
                    newPlayer.setPlayerLocation("entry_point");

                    Sphere mesh = new Sphere(32, 32, 10);
                    Geometry geom = new Geometry("A shape", mesh); // wrap shape into geometry
                    Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");   // create material
                    geom.setMaterial(mat);                         // assign material to geometry
                    // if you want, transform (move, rotate, scale) the geometry.
                    newPlayer.attachChild(geom);   
                    rootNode.attachChild(newPlayer); 
                    newPlayer.setLocalTranslation(new Vector3f(0, 10, 0));


                    players.add(newPlayer);
                    return null;
                }
            });
            
            
                   
            
            
            System.out.println("new player");
        }
    }
}

[/java]

Yeah, the code looks okay, make sure you don’t make changes elsewhere (e.g., you store the players in a list, do you modify them afterwards?)

OK, thanks. I’ll do some searching through my code in a little while.

So, someone sees a picture of Mt Everest in a magazine and they decide the world must look pretty cool from up there. They want to climb it. They’ve walked up lots of big hills before so they think they have a basic understanding of how to do it. Right away the rush out and buy hiking boots and a big backpack. Now they have a problem. The hiking boots are a little confusing to tie and the backpack the store sold has all of these places for different equipment that that our would-be mountain climber doesn’t understand.

So he goes to the “Mt Everest Climbing Forum”, joins up, and starts asking questions about how to tie his hiking boots and what good things should be put in a backpack. As they tell him that his boots are kind of wrong for the trip, mentioning that he will need things like oxygen bottles, climbing gear, ropes, etc… it becomes clear to them that he’s never really climbed a real mountain before.

It is logical then that people start jumping in and responding that he might want to climb some smaller mountains first. Can you imagine how difficult an actual Mt Everest climb would be for someone who has never been in that kind of weather, never rock climbed, never hiked more than a few miles, etc.?

This is where we are coming from. We can see how very basic your Java skills are. The types of questions that you are asking, the inability to sort out the answers easily, etc. all show that you’ve only scratched the surface of Java and even Object Oriented programming in general.

3D game programming is already hard. Networking will make that 10 times harder.

You should start with a simpler game project. For example, a decent Java programmer with JME experience could write a simple Asteroids clone in a few hours. If you do not even know how you’d put such a thing together then how long do you think it is going to take for you to work out the most complicated kind of game?

If you have the skills, these types of simpler projects won’t take long. And if you don’t have the skills, they will teach you the skills. Everything you learn by making a proper Asteroids clone will be directly applicable to your next game project.

The resistance you get here is because this is not a “Learn Java” forum. There are dozens of Java forms that would serve better for that. We read and post to these forums because we want to help people learn and use JME or solve tricky game programming problems. Given the shear volume of folks who go from “Hey, playing this game is cool.” to “Gee, I wanna make a game, too”… if we didn’t give a little pushback then this would turn into a Learn Java forum and quickly swamp all of the legitimate questions. (Worse yet 90% of those folks will rapidly figure out that writing games is too much harder than they anticipated and give up… wasting all of the time spent mentoring them.)

You at least have some game making experience and are ahead of most who choose this path for the first time. Still, use some simpler projects to learn Java and then come back to your grand idea. If that’s too much work then you weren’t going to finish the grand idea anyway.

This clarifies the angst immensely. I totally see where you guys are coming from.

On the other hand: given a 3d environment, where should I start? I did the tutorials (well, most of them. I kinda skipped a part that I knew I wouldn’t need for a long time), which seem like a logical place. I spent a weekend learning what I could about networking.

So, is trying to create a multiplier environment where two blobs move around a “grand scheme”? If this is the case, perhaps I should wait six months and learn more Java.

Think of this: It’s taken two days of banging heads into walls to basically get where I need to go. (Thanks again, it worked (sort of) and I think I can sort through most of the rest on my own.) Most of the other threads on this sub-forum (troubleshooting) are 2-4 days since the last response. Since this is the case, I doubt I am holding anyone back. (If I have taken up so much time that it has become difficult to help other people, I am truly sorry.)

If it’s all right, I’m going to stick around for a little while. I understand your position, so If I become pestersome in the future, please redirect me to someone who is willing to answer more basic questions.

Have you guys considered making a “totally new to JMonkey” forum? I would have gone there instead, had I seen one.

Just to make clear what I thought I was getting into:
-use an existing server/client framework I built to send messages to another machine.
-use the simple stuff I already learned in the tutorial to move two blobs. (setLocalTranslation)

Obviously, it went significantly further than that.

Thank you all very much, hope I haven’t been too much of a pain, (maybe) see you around.

PS: If I can get this working smoothly, I might see if I can write a beginning-to-end tutorial to duplicate it. Prevent someone from having the exact same issues. again.

EDIT: Just a side-note: When you suggested that I “learn java before writing a game”, I had absolutely no idea what to do with the suggestion. Learn Java? What part? Take a few tutorials? which ones? See, to me taking a java class was more than equal to “a few tutorials”. If there was one specific area of deficiency, I could have googled it and spent a day learning whatever. Without any further specification however, I had no real option but to keep plugging away. You’re correct: both programming and game development require a great deal of persistence.

@ulfgur said: Have you guys considered making a "totally new to JMonkey" forum? I would have gone there instead, had I seen one.

80-90% of this thread so far would have had to have been covered by a “totally new to Java” forum since they were Java issues and not JME issues.

@ulfgur said: EDIT: Just a side-note: When you suggested that I "learn java before writing a game", I had absolutely no idea what to do with the suggestion. Learn Java? What part? Take a few tutorials? which ones? See, to me taking a java class was more than equal to "a few tutorials". If there was one specific area of deficiency, I could have googled it and spent a day learning whatever. Without any further specification however, I had no real option but to keep plugging away. You're correct: both programming and game development require a great deal of persistence.

Write an Asteroids clone… in Java… using JME. It’s the single simplest game one can write and the knowledge is 100% transferable. Everything you learn about breaking down your game into controls and app states, etc. is 100% useful.

…and if you can’t complete that project, the mountain will be impossible.

Hey, odd little problem. When I load a model in as a .obj:

Spatial randomObject = assetManager.loadModel(“Models/XXXX.obj”);
randomObject.setUserData(“str”, “lollipop”);

then use getUserData(“str”); when picking, the program returns lollipop like it should. But if I reconfigure it to a .j3o, it returns a null. I’m happy to ignore this for now, and just use .obj, but It’d be good to know if it will come back to bite me when I convert everything to .j3o later.

What do you mean by “reconfigure it to a j3o”? Spatials can always have UserData and with j3os you can even define it in the editor. No reason why it would be as you say.

Probably it was loaded as a Geometry before and the SDK probably turned it into a Node with a Geometry child when converting to j3o. Just a guess. Collisions always happen on Geometry so if you set user data on the Node you won’t see it unless looking up the parent chain.

You can find this covered about 3 times a week if you search for “picking”, I guess.

@pspeed said: Probably it was loaded as a Geometry before and the SDK probably turned it into a Node with a Geometry child when converting to j3o. Just a guess. Collisions always happen on Geometry so if you set user data on the Node you won't see it unless looking up the parent chain.

You can find this covered about 3 times a week if you search for “picking”, I guess.

From the behavior I was getting, this sounds about right. I searched on the forum, found a thread to help, accidentally lost it, and can’t find it again. :lol: I think I can implement that later without too much trouble. Thanks.

Due to a relatively stupid coding accident (forgot to back up my files before making some major changes), I’ve lost some progress and run into a new issue.

When a client joins, my server begins to lag horribly, but the client is unaffected. (the client being unaffected may be due to it calculating only it’s own movement physics) Messages quickly pile up and the server crashes with an “out of memory” error. The weird thing is that this didn’t happen before I made unrelated changes. (I moved from extending node to assigning controls)

Any idea what the problem might be? Any part of my code that deserves inspection?

@ulfgur said: Due to a relatively stupid coding accident (forgot to back up my files before making some major changes), I've lost some progress and run into a new issue.

When a client joins, my server begins to lag horribly, but the client is unaffected. (the client being unaffected may be due to it calculating only it’s own movement physics) Messages quickly pile up and the server crashes with an “out of memory” error. The weird thing is that this didn’t happen before I made unrelated changes. (I moved from extending node to assigning controls)

Any idea what the problem might be? Any part of my code that deserves inspection?

Sounds like you are somehow blocking your listeners.

You should really develop with at least local source control. (and regular backups) After 20+ years developing with some kind of version control system I cannot fathom how folks develop without this safety net.

@pspeedYou should really develop with at least local source control. (and regular backups) After 20+ years developing with some kind of version control system I cannot fathom how folks develop without this safety net.
Like what? I mean, I regularly back stuff up, but is there a program that will do that for me? Today's breakage was fairly unusual for me, because I'm pretty paranoid about backing it up... but then, safety nets are for the exception, not the rule.
@pspeed said: Sounds like you are somehow blocking your listeners.

Blocking my listeners?

By that do you mean slowing them down, or turning them off? I’ve got a couple for-loops inside the message listener that’s causing the lag. Would that cause the problem?

something like this?

[pseudocode]
for(all my players)
{
room = player(a).getControl.getRoom();
name = player(a).getControl.getName();
if((room = message.room)&&(name != message.name))
{
message.setReliable(false);
server.broadcast(Filters.in( server.getClient(matches player a), message));
}

}
[/pseudocode]