Captive Imagination
September 10, 2010, 04:02:07 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Hosting change completed. Please send an e-mail to support@captiveimagination.com if you have any problems.
 
   Home   Help Search Calendar Login Register  
Pages: [1] 2 3 ... 5  All   Go Down
  Print  
Author Topic: Hi, my name is Elias4444, and I'm a programming addict...  (Read 7409 times)
0 Members and 1 Guest are viewing this topic.
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« on: February 13, 2006, 12:39:21 PM »

I just stumbled onto this project as I was desparately looking around for better ways to implement a networked multiplayer game. My own engine currently falls apart after 4 or 5 people connect, and I'm really hoping to push it up to 16. It's an action game, with players constantly in motion (set in space). Does JGN support that many users yet in that kind of setting? And how hard is it to implement?

P.S. I'm currently using LWJGL for all my graphics processing, if that makes any difference.
« Last Edit: February 13, 2006, 12:48:10 PM by elias4444 » Logged
darkfrog
Administrator
Inspired Imagination
*****
Offline Offline

Posts: 2650


View Profile
« Reply #1 on: February 13, 2006, 02:05:01 PM »

Yes, in fact, there is no imposed limitation to the number of users you can have connected.  However, that being said, there is a limitation with the convenience classes in NetworkingClient and NetworkingServer that make for the limitation being the MAX_VALUE of Short, but as long as you don't intend to have more than 32,767 players at any given time you shouldn't have much to worry about. Wink

If you download the source code and take a look inside the "test" package you'll find many examples of utilizing JGN and if you have any questions feel free to ask.

The basic building blocks of JGN are as follows:
  • Register messages, this is necessary for any custom message object you might create (ex. JGN.registerMessage(MyMessage.class, (short)1) - the second value being a distinct identification for that message);
  • Start the server/client (ex. UDPMessageServer server = new UDPMessageServer(InetAddress.getLocalHost(), 1000))
  • Create a message and send it (ex. MyMessage message = new MyMessage(); message.setValue("Blah blah blah"); server.sendMessage(message, remoteAddress, remotePort)Wink

I need to take some time to do a wiki page for introduction to this API.  Though it's actually quite simple once you understand the basics it might take a double-take to realize just how simple it is. Smiley

darkfrog
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #2 on: February 13, 2006, 02:09:26 PM »

Thanks for the reply! I've been looking at the wiki's basic example, but am already running into problems - although it looks like from your comments above that you've changed the API since then. I'll keep working on it. After suffering numerous headaches with my own networking code, something like this feels invaluable.
Logged
darkfrog
Administrator
Inspired Imagination
*****
Offline Offline

Posts: 2650


View Profile
« Reply #3 on: February 13, 2006, 02:19:49 PM »

The concept is simplicity.  I'll try to update the wiki, but that is simply a copy of the basic example in the tests in the source code if you take a look at that. Smiley

There's also a bunch more that show some more complex features you can do with the API in the tests if you get the source.

darkfrog
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #4 on: February 13, 2006, 04:33:49 PM »

Any idea why I'm getting this:

Exception in thread "main" java.lang.NullPointerException: null address || null buffer
   at java.net.PlainDatagramSocketImpl.send(Native Method)
   at java.net.DatagramSocket.send(Unknown Source)
   at com.captiveimagination.jgn.UDPMessageServer.resendMessage(UDPMessageServer.java:110)
   at com.captiveimagination.jgn.UDPMessageServer.sendMessage(UDPMessageServer.java:100)
   at com.captiveimagination.jgn.client.NetworkingClient.sendToServerUDP(NetworkingClient.java:223)
   at jgnnetworkers.DGClient.qEvent(DGClient.java:183)
   at mpgame.MPGame.switchtonextship(MPGame.java:409)
   at mpgame.MPGame.rezme(MPGame.java:1688)
   at mpgame.MPGame.loadStuff(MPGame.java:381)
   at mpgame.MPGame.begin(MPGame.java:237)
   at mainmenu.MainMenu.begin(MainMenu.java:665)
   at mainmenu.MainMenu.splashscreen(MainMenu.java:488)
   at mainmenu.MainMenu.main(MainMenu.java:1674)


It basically happens as soon as the client tries to send something.
Logged
darkfrog
Administrator
Inspired Imagination
*****
Offline Offline

Posts: 2650


View Profile
« Reply #5 on: February 13, 2006, 04:46:09 PM »

My assumption is that the InetAddress you're passing is null or invalid.

If that doesn't solve it post the message object you're trying to send and I'll see if there is anything wacky there. Shocked

darkfrog
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #6 on: February 13, 2006, 05:11:55 PM »

Looks like I just needed to call the connectandwait() function after establishing the connect with the server. I'm sure this is just a learning curve on my part at this point... but now I'm getting this:

Object: com.captiveimagination.jgn.server.ServerPlayerMessageListener@18600d6, MethodName: messageReceived, Var: com.captiveimagination.jgn.message.player.PlayerJoinRequestMessage@a0e990, callAll: true
java.lang.reflect.InvocationTargetException
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
   at java.lang.reflect.Method.invoke(Unknown Source)
   at com.captiveimagination.jgn.MessageQueue.callMethod(MessageQueue.java:193)
   at com.captiveimagination.jgn.MessageQueue.sendMessage(MessageQueue.java:160)
   at com.captiveimagination.jgn.MessageQueue.update(MessageQueue.java:89)
   at com.captiveimagination.jgn.MessageServer.update(MessageServer.java:86)
   at com.captiveimagination.jgn.TCPMessageServer.update(TCPMessageServer.java:38)
   at com.captiveimagination.jgn.server.NetworkingServer.update(NetworkingServer.java:99)
   at com.captiveimagination.jgn.server.NetworkingServer.run(NetworkingServer.java:123)
   at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
   at com.captiveimagination.jgn.JGN.get(JGN.java:923)
   at com.captiveimagination.jgn.JGN.convertMessage(JGN.java:695)
   at com.captiveimagination.jgn.TCPMessageServer.sendMessage(TCPMessageServer.java:127)
   at com.captiveimagination.jgn.server.NetworkingServer.sendToAllClients(NetworkingServer.java:279)
   at com.captiveimagination.jgn.server.NetworkingServer.sendToAllClientsTCP(NetworkingServer.java:257)
   at jgnnetworkers.DGServer.addNewClient(DGServer.java:355)
   at jgnnetworkers.DGServer.access$0(DGServer.java:322)
   at jgnnetworkers.DGServer$1.createRemotePlayer(DGServer.java:84)
   at com.captiveimagination.jgn.server.NetworkingServer.joinRequest(NetworkingServer.java:89)
   at com.captiveimagination.jgn.server.ServerPlayerMessageListener.messageReceived(ServerPlayerMessageListener.java:30)
   ... 12 more

I didn't see it in the examples, but do I need to "accept" the client connected with a specific call?
« Last Edit: February 13, 2006, 05:17:02 PM by elias4444 » Logged
darkfrog
Administrator
Inspired Imagination
*****
Offline Offline

Posts: 2650


View Profile
« Reply #7 on: February 13, 2006, 05:33:07 PM »

Take a look at these lines, I'm not positive, but it looks like they may be what is causing the NullPointerException:

Quote
   at jgnnetworkers.DGServer.addNewClient(DGServer.java:355)
   at jgnnetworkers.DGServer.access$0(DGServer.java:322)
   at jgnnetworkers.DGServer$1.createRemotePlayer(DGServer.java:84)

The examples work just fine on your machine?

darkfrog
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #8 on: February 13, 2006, 05:43:48 PM »

Haven't tried the examples yet actually.  Roll Eyes

That line is simply this:
Server.sendToAllClientsTCP(tempevent);

Let me ask you this though... how simple does the "BasicMessage" have to be? I've named mine "NetEvent" in order to save myself some recoding.. and it contains the following:

package jgnnetworkers;

import com.captiveimagination.jgn.message.Message;

public class NetEvent extends Message {

    public String message;
    public float[] data;
    public float sendTime;
    public int playerID;
    public int eventType;
   
   public NetEvent(float attime, int playerIDpass, int eventTypepass, float[] datapass) {
      sendTime = attime;
      playerID = playerIDpass;
      eventType = eventTypepass;
      data = datapass;
   }
   
   public NetEvent(float attime, int playerIDpass, int eventTypepass, String datapass) {
      message = datapass;
      sendTime = attime;
      playerID = playerIDpass;
      eventType = eventTypepass;
   }
   
   public NetEvent() {
      
   }
   
    public void setText(String text) {
        this.message = text;
    }
   
    public String getText() {
       if (message == null) {
          message = " ";
       }
        return message;
    }
}
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #9 on: February 13, 2006, 05:50:48 PM »

Ok, it definitely has something to do with my NetEvent class. I removed the other stuff, and it all worked fine (except that I don't get everything I need in the packets). How do I create a "BasicMessage" that'll transmit those fields I need?
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #10 on: February 13, 2006, 05:55:56 PM »

Ok, got it! You have to create a "set" and "get" for each variable in the class. It's working!!!!!

It's still slow for some reason... but it's WORKING!!!!!  Grin
Logged
darkfrog
Administrator
Inspired Imagination
*****
Offline Offline

Posts: 2650


View Profile
« Reply #11 on: February 13, 2006, 07:33:33 PM »

Yeah, I don't work with private variables...I'm a believer in private variables aren't visible for a reason so I won't touch them. :-p

I'm not sure why it would be going slow, all of my benchmarks peg this API at some pretty high speeds. Wink  Now, if you have JDT in the classpath you'll notice a few seconds lag in startup when the application first starts because it's dynamically generating source code and compiling it, but after that's done you go significantly faster.

darkfrog
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #12 on: February 13, 2006, 08:26:30 PM »

Yeah, I'm guessing it's slow because I'm porting over my old networking code to it. Right now, with client and server on the same box, I'm getting a 10,000+ millisecond ping time... yeah, I'm definitely doing something wrong. Tongue

My guess is that I'm launching it from within a class that was already threaded, and so I'm messing up with that somewhere. Now, if I only call the "start" method (rather than the startthreaded method), do I need to call the "update" method from within a loop? Or will I get better performance with it using it's own thread system?

(Heck, I'm still just excited that it's working and that I may not have to keep writing my own super streamlined network code. Tongue )
Logged
darkfrog
Administrator
Inspired Imagination
*****
Offline Offline

Posts: 2650


View Profile
« Reply #13 on: February 13, 2006, 08:40:53 PM »

Either way is fine.  Note that if you call client.update() or server.update() then you can make that call from within your graphical thread.  The biggest advantage there is that any MessageListeners you add will be processed then in your graphical thread as well, so you don't have to worry about the evil VM crashes when you try to do something with LWJGL in a separate thread (or in my case on what I'm doing right now, with ODE in the middle of its update which causes serious evils).

Typically I would suggest calling update from within your own graphical loop.

Well, I'm glad it's working for you. Wink  Feel free to make any suggestions as you come across things that you might have liked better from your old system that this may not yet have. Wink

darkfrog
Logged
elias4444
Full Member
***
Offline Offline

Posts: 110


View Profile
« Reply #14 on: February 13, 2006, 10:17:29 PM »

Well, I've solved the speed issues... but now the client disconnects after about a minute or so. Do you have some sort of timeout set or some sort of check that needs to occur regularly to keep the channels open?
Logged
Pages: [1] 2 3 ... 5  All   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.239 seconds with 20 queries.