I'm trying to pass a SpatialTranformer instance using the JGN system. I've been able to pass Vector3f by writing my own Message that breaks it down to it's atoms (3 float) on one end and then reassembles it on the other end, but this seems like a very painful way to go for a larger object like SpatialTransformer.
Any hints on how to do this for efficientlt for a larger objects? Perhaps an article you can suggest on this kind of thing?
Well, currently the only real option is to do what you're doing and pull it apart into primitives since JGN only supports primitives and String. I have intentions on adding arrays to this as well, just haven't done so yet. When that gets implemented you could (wouldn't necessarily recommend it for a fast-paced game) serialize the entire object and send it in a byte array over.
If it were me doing this, I would probably create a Message object that contains the getters and setters and then create a little utility that instantiates a new message object when passed a SpatialTransformer and sets all the values. Sure, it's a bit of work, but you need the primitives and you could add another method to your utility class that takes the message object and assembles a new SpatialTransformer on the other side.
If you have any other ideas let me know. If there's anything that could be added to JGN that would be beneficial also let me know. I will try to get the array support added to JGN this week, and if you decide to do something with that let me know so I can make sure it's a priority, otherwise, if I don't think there's anyone that cares about it, I might put it off. :-p
darkfrog
As for game networking, jsdt (java shared data toolkit) has support for object transfer and a very clean api, but it is peer to peer and not very actively developed.
The api design is well worth a look when implementing a networking lib imho.
Supports UDP, TCPIP and http for firewall penetration and even multicast with some extern lib
I would think transferring an object over the network would almost always be a bad decision in a game where networking performance needs to be extremely fast. Do you see any situation where that might not be the case?
I focused JGN on primitives because I assumed transferring anything else would just be too slow. As it is I'm not having any trouble with bandwidth, I'm actually more concerned with the amount of time the API takes to disassemble and reassemble messages. I'm using some reflection and I think that's causing it to take a upwards of a couple milliseconds to do the work and I'm looking to make it even faster. Though in most situations that is more than fast enough, I'm trying to make this fast enough to support even the fastest paced games. I have an idea how to solve the problem with a little dynamic compiling, but haven't had a chance to investigate it further yet.
darkfrog
an ObjectOutputStream is an easy way of serializing java objects(and arrays if you will)…though I recommend going the primitive way(as darkfrog says)…performance gains, memory gains and you know exactly what you send(which is often crucial)…It's also cleaner to debug
Agreed, but a pro knows what he does (or at least should) and uses the appropriate data representation, so for massively multiplayer internet - action games Your way is out of question, but for card games or chess or the occasional proof of concept demo or LAN games, streams, shared byte arrays and so on would come in handy.
just my opinion
Agreed, but if I can provide the majority of the capabilities in JGN then you get the best of both worlds (speed and ease-of-use).
I have just finished a test-case of dynamically generating, compiling, and loading classes on the fly using Eclipse's JDT API. I tried doing BeanShell first, but my test-case ran some computations 10,000,000 times and took 76 seconds to complete. I did the same thing with straight Java and it took 125ms. I was able to dynamically generate, compile, and load a class that ran at 125ms as well. Granted startup time is increased, but the performance gains should be phenominal. I will try to get some progress on this today as well as adding arrays to the API.
This method will be optional as it requires you to have the JDT jar in your classpath (which is about 3 meg) and increases startup time. It will be recommended for fast paced games, but other implementations can use the current method. Note that this does not have any JDK depencies as the JDT API actually does all the compiling itself.
darkfrog
Looking forward to seeing your examples with arrays and the JDT. My current project is turn based, so I'm favoring convenience over speed at the moment.
If you want ease with better performance, use Externalisation rather than serialisation. However, you will still get lots of padding of superflous field.
If you want both, then you will need to specify each field required for each request / response. Also may consider Meta Data around the fields - if you have a max of 128 in an int - dont transfer 4 bytes per the java spec of an int - make do with one byte.
Well, convenience will never be lost. How I'm currently writing this is if JDT is in the classpath then it will use it, if it's not it will revert to the old way. This way your code can remain identical and if it can find JDT it will have a slower startup but faster run.
I'm working on it right now and if all goes exceptionally well I might have it in tonight, but things rarely go exceptionally well. :-p
darkfrog
Okay, I have been working on this and have something functional but I'm still tweaking, so it will be at least tomorrow before it's released.
Early statistical improvements with a stress test sending 100,000 messages that contain 10 getter/setters:
- Reflection (Old Way): 15,204ms to send, 25,250ms to receive
- Dynamic Class Generation: 9,594ms to send, 20,750ms to receive
Though a pretty stout performance improvement I'm still working on making it even faster. I think with my physics networking I should see an even greater performance increase as there are so many getter/setter methods in the PhysicsMessage.
darkfrog
You know you can do dynamic loading of classes without JDT, don't you? And compilation can be done with tools.jar or by spawning a javac process - so no need for that long JDT starting times and 3MB lib…
Irrisor,
Yes, but I didn't want to have to require the JDK to be installed. The current way can be done with a standard JRE. Further, starting times are slower because it has to generate source code, compile, then dynamically load it. This would be the case using JDT or the JDK. Actually, JDT is faster (and in my opinion, quite a bit better for dynamic building) than the JDK is. Finally, I hope you're not complaining about a 3 meg jar in favor of tools.jar because over here in my 1.5 JDK tools.jar is 6.7 meg. :-p
darkfrog
true
(btw. you forgot to mention that Mac users don't even have a tools.jar :P)
Quite the concession you make my friend. :-p
BTW, I will be checking in the updates to JGN in a few minutes. I am going to hold off on releasing the changes until I've had a bit more time to do testing on every aspect of the changes. I have implemented some major speed fixes. I can now send 10,000 messages in just under 9 seconds and finish receiving in a little over 9 seconds. I think this is just about as fast as I could ever expect to get. My major speed issue now is just the sending and receiving of packets (which I don't have any control over), so I think it's tweaked now.
Also, support for primitive arrays, primitive wrapped arrays, and String arrays are now implemented and vaguely tested with JDT and reflection (kinda sucks since I had to write support in both areas doubling the amount of code).
Let me know if you have any problems.
darkfrog
For everyone planning on using this for a game, using a dead reckoning algorithm is extremely useful. Minimizes amount of packages having to be sent and hides latency. I’m using it to some extent and it works beautifully…
Good article on Gamasutra:
http://www.gamasutra.com/features/19970919/aronson_01.htm
Yeah, my alternative to dead-reckoning is physics networking. :-p
darkfrog
Just got the update. Is there an example in there of using JDT?
Yeah…all of them. :-p Using JDT requires no extra code at all…it just has to be able to find the JDT jar in the classpath and it will use it.
If you download the JDT zip found somewhere here: http://www.eclipse.org/jdt/index.html and pull the main jar out of it (about 3 meg) and just add it to your classpath you’re off and running. I need to look into the license on Eclipse and see if I can package JDT up for download from JGN.
darkfrog