3d transform data thru socket

What would be the best way to send my location data from the client to the server and back again?

I have tried 3 different client server setups and just cant find a working scenario.

I have a client app that is “playable” and will gladly send the source to anyone who would like to critique or advise on how best to network it. Just email me if you would like to see it. I am at worldbuilder@comcast.net

Piece of cacke to get something generic up and running. It really depends on what technology you want to use. Personally I wouldn’t recommend RMI for this. All you need to do is encapsulate your positional data into bytes on the client, send that data to the server, and have the server multicast that information to the other clients.

Note: this will get you something running quickly. It is however, NOT the best way to solve the problem. Scalable server design is not something that can easily be addressed in a single thread, and it is something that is integral to the design of your application. Get your basic example up and running (look up Socket and ServerSocket for quick ways to handle this) and the pop open a thread in the networking section when you’re done.

I do just want something up quickly. Where I was running into probs was getting the rotation on Y from the client and sending it. AND when to grab that data fro the client , ast what pint to send it and how often.

I was using a Movement behavior and Keyboard behavior. Cna this be done from a behovior or should I wirte a non-behavior class for it.

I understand the basics of client/server activity, just not with a java3d client.

Did I lose ya?

There for sure, as so often, is no single answer.

I personally transmit hand-coded position/kinetics data for a full 6dof motion applying a deadreckoning scheme that considers up to 2 derivatives.
The dead reckoning automatically tells me when to send data (not so often hopefully), avoiding latencies caused by fixed time slices.

My ‘server-loop’ is triggered when I received data on one or more lines (when the Selector returns 0).

This way, theres no (or only few) latency introduced by the server, although sometimes a small integration time would be nice hopefully resulting in less messages to send.

Technically I transmit them with the NIO api, which is told to be the most efficient these days. Not more than 2 threads are needed. Maybe only one on a server (wait-for-message, handle-it, wait-for…).

Now it depends on your needs. If you e.g. have a simple Quake-like motion you can be even off sending just motion commands (go left, forward, turn …).

Many games even do this in fixed timeslices. Thats brute force and ugly to the max, but it deservs simplicity :))

Did I lose ya?

[quote]Technically I transmit them with the NIO api, which is told to be the most efficient these days.
[/quote]
Efficiency is not the same as performance. More specifically NIO is the most scalable, since the non-blocking nature does not require you to spawn a new thread per client. But that scalability comes at a price, performance.

So, if your non-NIO system would only ever have a couple of client threads (as opposed to the thousands needed for a web server), NIO overhead is probably not worth it.

My current game app runs very smoothly. You drive the “cube/avatar” and turn right or left, forwards or
backwards. As long as a kep is pressed, you are moving, multiple key combinations give you combined
movement. ie; up arrow and left arrow = move forward whil turning to the left, and so on. You get the picture.
I have a KeyTypedBehavior and MovementBehavior(both extend Behavior)
The KeyTypedBehavior WakesUpOn keypressed, and the Movement WakesUpOn frames elapsed(0).

Space bar fires a single projectile by capturing the current transform of the “cube/avatar”
and applying it to a new object(smaller cube) then move it forward for x number of seconds
then remove it frm the scene.

Ignoring some collisions issues with walls(which I am not concerned with right now), it runs exaclty
like I want it to.

At what point in that scenario should I send data from the client to the server?

Should I send x,y,z, and the matrix[16] of the player to the server or do you think keypresses = send(“turn left”), send(“turn right”)
would suffice?

considering you could be turning left and moving forward. Will this keep it accurate enough for shooting at
another player? An “arena” will have a max of 16 players. Right now only one arena will be active at
any one time.

And yes Quake-like movement is fine, I use keyboard only. Arrows for movement, possibly the shift to
boost speed, “tab” or “space” for fire and “alt” to activate shields.

I have done this in a 2D realm sending int’s for x and y and double angle to server using a thread that sends the data 3-4 times a second
and the server is on a 30 ms loop sending all data to all players(with a little, very primitive dead r).

http://www22.brinkster.com/mbowles/ for the 3D source code. Once unzipped, nav to folder and type java AWTFrame

You will notice a lot of the code is J3D tutorial(thanks Justin)

and many, many thaks to those of you here.

Where’s that from? What kind of overhead does it impose? I think the ByteBuffers are very slim and fast!

One thing you should not assume is that you will need to (or want to) send every single packet from your client to your server. Doing so will simply drown the server in packets as the number of clients goes up.

Unfortunately what you’re asking is a very application specific question. If its really necessary for you to send that level of detail and multicast it to the other clients, then you have to send it and will have to design around that. If its only necessary that other clients have the idea that ‘client X is turning left’ you can do that as well - but be careful! I can already see that you’re starting to write a fair amount of code without really designing/thinking about/specifying what you need. This will result in unnecessary hardship during your development cycle.

What I would suggest before we continue is that you write down what your requirements are. What information will be necessary for clients to relably draw the state of other clients? What assumptions can I make about the state of entities in my world so that I don’t have to transmit that information. For example if an object can only turn so fast, you may not need to transmit every discreet rotation to other clients. However if you find that you absolutely have to see every degree movement - put that into your design as a hard requirement.

Hopefully you see what I’m getting at. Before you can really talk about what you want to send - you need to really reconcile what you absolutely NEED to send. I’d be happy to go through that process with you in this thread if you desire.

Will do. I’ll put that together today, and thanks. Will post to this thread as soon as I put them together.

Its a very simple concept, so you are probably right, I am probably overdoing it.

More soon.

If you have seen the code running, you have the basic idea of what the client game screen should look like, minus a chat area at the bottom (this is where login and chat will take place.)

Desired functionality is as follows: Player will use the arrow keys for movement, tab or space to fire projectiles (these may varies in types). When pressing the s key, shields will come on based on how much shield energy you have. Up to 16 other players can be online at one time. As a player logs in, the server will assign him a team/side based on game balance. A match will have a time limit(or goal, capture the flag or something). When time is up, players will be scrambled to balance the teams again. Until there are sixteen players online, new players can join at anytime and will be entered into the appropriate team. When a player dies he will get a 10 second countdown and re-spawn on the same team, at the spawn/entry point for that team.

Code side: Since I am using cubes (Cube Wars is the planned name, and there is a story behind that), and a flat plane playing field, no terrain data is needed, nor will there be any zoning. When a client logs in(username and password check), he will need the universe data sent to him to synchronize his client app. That is location of all objects in the universe (projectiles and players). The new player is appear to all other players and to himself in the dedicated spawn location for his team. He can then start playing. The data that the client sends to the server and the data the server sends to the clients needs to be accurate enough for real-time shooting. Quake III Arena, Tribes 2, Sonys Infantry (most like this). After all objects have been synchronously sent to the new client, he should send his movement changes(turns, move forward, move backward, stop) and when he fires a projectile (the projectiles position and transform3D at launch should be sent to server, then sent to all players), it then becomes another universe object with only a straight line movement at a constant speed. I want server and client load to be the minimum needed to maintain shootable accuracy, attempting to elimnate the -hey your bullet was nowhere near me and I got hit!!- or - I shot you three times and you didnt go down-, etc. I know lag can cause this, but I dont want the code to be that off initially.

Have I given you what you were looking for?

That helps. Okay, here are a few things we can start to work on right away. There is no motion in the 3rd dimension so everything we need to do becomes a MUCH easier 2D problem. All we need to send is the x,y, and rotation of the object - 3 floats [notice how the requirements are getting down our data requirements]. We probably also want to send velocity so we can add that in as a 4th float… So now we can describe a player as some playerID and an ordered set of 4 floats.

Since our player can be in one of 3 states ( normal, shielded, firing ) we can encode that information in a char - where each int value represents one of these states so clients can remotely draw what’s going on. So really what we have is:

PlayerState
float x, y, rotation;
char state;

From what I was able to get from quickly reading through the requirements this is what you need to send for each player playing the game. More on what you’ll have to do as we progress to ensure a non exponential sending pattern as we proceed.

What I would suggest for now is having a data structure that contains all 16 player’s PlayerState structures transmitted at all times (this is NOT code you’ll be keeping for too long but enough to get us started).

Since your game takes place on the same plane (players cannot be above or below other players… this works for height field maps as well), you don’t necessarily have to transmit a transformation matrix for your projectiles either. If you assume that they always travel with the same velocity, you don’t have to transmit that information either since all the clients already know that information. It doesn’t sound that projectiles have any particular descriptive details that we need to send to other players so we won’t put that into the protocol right now.

ProjectileState
float x, y, rotation

You may be a little confused about how you will move the projectile with just the rotation. Since what we have is fundamentally a 2D problem we can assume that this rotation is an angle from some plane and that the projectile is moving in this direction. Pick the bottom of your map and determine your angle of motion from this information against this ‘world edge’ plane. If you have trouble conceptualizing this, lemme know.

So now in the simplest case your packet is

MessagePacket

  • source playerID
    -PlayerInfo (16 PlayerState structures)
    -# active projectiles
  • ProjectileInfo ( n ProjectileState structures )

This is pretty much the state of the world at any given time. Yes it may seem large, but really its not. Let’s not jump into ‘real’ optimizations yet in any event. This is a learning excercise so when you feel you’ve got this part down - lemme know and we can move onto the next step.

I tried to send you a message, but my son hit my power button!!! So i’ll re-comment here…

I may be confused a little. If I am navigating forward into z, would’t we need z also, and would this make y constant? I guess if you fire up my app at its currnet stage(link above), can you tell me if the green grid is x or z. I thought is was on the X plane, and that you would travel over it by increasing, decreasing z, but I could be (and probably am) wrong.

Other than that , I think I have your concept so far under control, and it makes more sense than what I was trying. I am under the impression you are talking UDP packet for multicasting?

If you are able to download my source, use aroows for nav and space to fire. The blue cubes can be hit by projectiles.

edit: I have always done client/server games with the “mud” concept on the server side, loop thru all players and at each player send the data by again looping thru all players with DataInputput and output streams sending ints. What would be the best data structure to use for the MessagePacket and the Player and Projectile states? i.e what should a PlayerState structure look like that you would pass to the messagepacket?

If you use y as up (and not all people do) then replace z with y. The thing to note is that you don’t have to keep track of height (moreso than x, y, or z) since you’re not concerned with players over other players or being over the map or anything.

For what its work protocol wise, you may want to start off with TCP. In the average case its not going to hurt you and is actually beneficial for our early work since UDP is likely to chop up our datastructure into smaller pieces that won’t all get to the destinations at the same time. We can get to UDP a little bit later, but adding that part in now will more than likely just serve to confuse you because it brings in other issues with respect to reliability and synchronization that we don’t necessarily want to tackle yet.

Sounds good…I think I understand you. Point is we dont have 3 dimensions to deal with since one of them is constant.

I have just completed a very basic set of classes in the server package:

Server
PlayerManager (keeps a vector of playerthreads)
PlayerThread (holds the socket connection for player)
Player extends GameObject (with char state)
GameObject (has floats x,y,rotation, and int objectID)

using TCP and it fires and waits for a connection. telnet causes a successful playerthread and player to get created! If you would like to check them out, let me know.

Get a stable build together for Friday and I’ll sign on and play a game with ya :slight_smile:

I have a few questions, but here s one of them…

DOn’t know if you have seen my client code, but I have a KeyTypedBehavior taht wiats for keystrokes. Those keystrokes set movement variables to true or false for different move directions. The Movement calss extends behaviors and waitsOnfFrame(0) then does the move based on the true false combinations. At what point in that process should I send the client data piece to the server? Should I not have a mevement behavior since movements are coming from the server?

and yes It seems I have having a little trouble grabbing the angle from the “world edge” Here is a screen shot. Player is green, projectiel is white, blue is generic obstacle(not in game). Movement is along green grid. Camera follows player.

at what point in the client shoudl I send data to server?

That is another ‘up to you’ type question. You want to send the data often enough to ensure your simulation resolution. Many people try to do this once per frame, and it may work for you right now - but later we will tune that down when we get into the fun of UDP, missing packets and dead reckoning.

sounds good, I’ll try by frame for now. oh, can you give me some hints on grabbing the rotation fo the player from the current tranform to send to the server?

thanks!

Okay here is how you do it. Take 2 pieces of paper. Lay one of them flat on the desk. This is the plane that your players are on. Next take the second page and put it perpendicular to that one. This is the plane that you want to take your angles from. Look down on the two pages. Take the bottom left corner and measure your angles from this corner. Objects are either heading towards or away from this plane.

Does that help any? If it doesn;t I’ll try and get some vector art together for ya (hard to draw with HTML).