Some questions.

Started by Disastorm, February 07, 2010, 05:17:30 AM

Previous topic - Next topic

Disastorm

Hi, I have some questions.  Whats the best way to sync two objects together over a network.  Right now I send transformation and rotation matrix clones every 50 ms over an ObjectOutputStream or something like that and also have the keypresses sending so that it can continue to translate the objects in between those 50ms. its pretty good but doesn't seem to be perfect when i have 2 clients open it has a slight delay before one can see the movement.  I was just wondering if theres a better way or perhaps this delay is due to my logic in constructing a pojo to send across the stream and then checking all the objects on the client side to find the one that is referenced by the pojo, etc.

Also how can I make something collidable with everything? I only see that theres a setting that check collision self and check collision other.  Is there no way to make it collidable with everything for example if I have 3 objects that can collide with each other?

Also if I use a .obj how do I get material to work?  If I use a .3ds exported from 3ds max with texture coords and then import the jpegs itto jpct, it will automatically put them on my model.  But I tried with a .obj exported from 3ds max and i set the .mtl file also and then i noticed that jpct imported all the correct jpegs after it read the .mtl file but it didnt seem to show up in the actual world.

Also why does it seem like sometimes parts of my 3ds file will be in the wrong position when i load it into jpct instead of the position it was in when i open it in 3ds max.  If i use a .obj file though this position problem doesn't happen but i'm not sure how to use textures.  So far I believe this 3ds problem only happened if I cloned a copy of an object, but im not sure.

Thanks,
Disastorm

Wojtek

Hello,

For my game I am sending a rotation angles of object and its coorinates (x,y,z) - 3 angles sent as float or double are smaller than matrixes.
However I am not saying it is best way to synchronize objects. I have heard that for games such as Quake, instead of sending coords and rotation parameters the action messages are sent (like: object started moving in that way, or object started rotating) and all clients (including server) symulates those moves/rotations by them own. In that case you do not have to send such a much amount of messages, but there is a still problem to synchronize clients timings etc. which may be more difficult ;-)

For the second question I cannot help you yet - in my game, server does not know JPCT models and currently I do not have collision implemented. However, I was thinking of solving it in one of two ways:
* the game client checks collision and when it occurs, it sends info to server - server will have to validate that message somehow and process collision
* server have a very simple models of objects (low polys, no textures etc) and it uses them for collision testing, however I am little afraid if this will work, because server processes much more objects than client and this may kill the server performance or use too much memory (I have many worlds/play arenas where client 'sees' only one at time while server processes all of them....)

I am only using 3ds files so I cannot help you with objs :(
For loading 3ds files I am using following method (that I have found in some post on forum):
static public Object3D loadObject(String path, String name, int scale)
{
Object3D[] model = Loader.load3DS(path + name + ".3ds", scale);
if (model.length == 0)
return null;
Object3D o3d = new Object3D(0);
Object3D temp = null;
for (int i = 0; i < model.length; i++)
{
temp = model[i];
temp.setCenter(SimpleVector.ORIGIN);
temp.rotateZ((float) (-.5 * Math.PI));
temp.rotateMesh();
temp.setRotationMatrix(new Matrix());
o3d = Object3D.mergeObjects(o3d, temp);
o3d.build();
}
return o3d;
}


I hope my post is helpful,
Thanks,
Wojtek

raft

Quote from: Disastorm on February 07, 2010, 05:17:30 AM
Whats the best way to sync two objects together over a network.

i dont think this question has a simple answer. there are many factors. i guess you must first specify your target network, local area or wide area.

* local area: UDP is the preferred transfer method here. you can send positions and directions of objects very frequently (as you do know). if send period is 50ms, assuming network transfer and object serialization-deserialization happens in no time, you will have an average lag of 25ms. this practically means instant, no lag at all.

* wide area: UDP is not reliable over wide area. you will possibly need to stick to TCP which is slower and due to its nature (it guarantees message order) may cause significant lags. even a few seconds on some cases. indeed i personally believe fast paced multiplayer action games are not appropriate for wide area.

i had read an article about Quake3 network system. besides positions and directions server also sends movement information, like speed, acceleration and direction of movement. so if client cant get any message from server, it can calculate positions of objects. this sounds quite a good approach to me. this is discussed in some thread but couldnt find it now.

in karga i've done something different: as karga is not a fast paced action game, i accepted the lag from the beginning and used lag to optimize bandwith usage. i send data with 2 seconds period (and only if there is any movement), accepting 1s lag on the average. this gives me the ability to remove redundant data and use very less bandwith. for example, i send only end points of a straight line segment as seen in the image (the crossses mark the points of sent path):


hope this helps,
r a f t

Disastorm

#3
Thanks for the responses everyone.  btw wojtek i wasn't wondering about how to do collision via server/client but rather how to make something collidable with everything.  Since you havn't done collision yet, maybe you have not seen it , but it seems you can set an object as to COLLISION_CHECK_SELF or COLLISION_CHECK_OTHERS and those 2 different types can collide with each other, but for example a CHECK_SELF and another CHECK_SELF cannot collide with each other.  So the question is how can you make 3 objects all able to collide with each other?

oh yea raft I remember looking at your website for karga awhile back, that game looks really cool.  I'm trying to make an mmo game with jpct.  Is there some way to test the bandwidth required for your program?  If I am running my program on 2 computers in a local network is there some way I can check how much bandwidth is going through?

It looks like if you "attach" stuff together you don't get the weird positioning problem with .3ds files.

raft

Quote from: Disastorm on February 08, 2010, 09:16:37 AM
oh yea raft I remember looking at your website for karga awhile back, that game looks really cool.  I'm trying to make an mmo game with jpct.  Is there some way to test the bandwidth required for your program?  If I am running my program on 2 computers in a local network is there some way I can check how much bandwidth is going through?

thanks ;D i dont know any specific programs. altough there are programs (like tcpdump for linux) to monitor network traffic. you can also write your input/output streams to count the bytes going in and out..

paulscode

In the game I'm currently working on, for collision between enemy ships for example, what I did was to iterate through the list of ships setting check_others and check_self to test them one at a time.  The time required is similar to sorting a list I think, so I don't know how well this would work for a huge list of objects.  It works well in my case, anyway.  I'd be interested to see if there is another way to do this, too.

.jayderyu

Quote from: Disastorm on February 07, 2010, 05:17:30 AM
Hi, I have some questions.  Whats the best way to sync two objects together over a network.  Right now I send transformation and rotation matrix clones every 50 ms over an ObjectOutputStream or something like that and also have the keypresses sending so that it can continue to translate the objects in between those 50ms. its pretty good but doesn't seem to be perfect when i have 2 clients open it has a slight delay before one can see the movement.  I was just wondering if theres a better way or perhaps this delay is due to my logic in constructing a pojo to send across the stream and then checking all the objects on the client side to find the one that is referenced by the pojo, etc.
I agree with Wojtek. It's also the standard way to do network game communications. Messages are given as instructional commands not current positions. TURN, MOVEFORWARD.... these commands are then flagged in your update loop so that if say float TURN is <> 0 then your character turns by said amount. that value does not change until a new TURN command has been sent with a new value. More turn or 0 or even the other way. Everycommand you send is also packed with current situation data. so you do send position/angle with every message. Finally you also send this data every so often. You will want to personally test how often you will want to send though. Also you want to keep track of game time. ie time since the game started. So that every message will also send said game time. Finally upon receiving you calculate the difference between gametime of sent message and game time of receiving the message and the figure the difference based on rate of current movement. Finally theres dead reckoning. I would suggest reading up on that.

My early games avoided dead reckoning due to the simplicty of them, but if your going to have combat then deadreckoning is essential.

I don't know the api you are using, but I would really suggest either Java Gaming Network. You can create a binding for  JPCT. Objects through the system it will handle Object syncing. It also uses UDP over the internet. Handles things like packet loss and so on. Theres also project DarkStar(which I use). It doesn't handle object synching, but it's built on a solid scalable server core.


Quote from: Disastorm on February 07, 2010, 05:17:30 AM
Also why does it seem like sometimes parts of my 3ds file will be in the wrong position when i load it into jpct instead of the position it was in when i open it in 3ds max.  If i use a .obj file though this position problem doesn't happen but i'm not sure how to use textures.  So far I believe this 3ds problem only happened if I cloned a copy of an object, but im not sure.

Thanks,
Disastorm

I've heard of people having this problem. There a sticky on 3ds models in this category. Maybe the solution is in there.

Disastorm

Thanks for the replies.  I don't use an engine I am just sending stuff through object input stream and object output stream attached to a socket lol.  Is it alot better for me to use an engine instead?

Disastorm

Another question.  I'm using the code posted in the forum a few times to select an object by doing the 2d3d ray thing but for some reason it doesn't seem to work perfectly.  depending on the angle of my camera i can select the object at certain points and sometimes i can select it above the actual object or below the object and other times i can click parts of the object and it doesn't select.

paulscode

Could you post the code that you are using?  I have some experience with this.

Disastorm

just the select part or my whole program?  the select part is exactly the same as the code snippet in all the other "how to select objects with mouse" threads.

paulscode

#11
Just the select part.  For reference, here is the code that I use -- see if it is the same as what you are using:

    public void mousePressed( MouseEvent e )
    {
        // Get the mouse's coordinates on the applet window:
        int x = e.getX();
        int y = e.getY();
       
        // Get the 3D coordinates in Camera space:
        SimpleVector position = new SimpleVector( Interact2D.reproject2D3D(
                                                       camera, buffer, x, y ) );
        // Convert the coordinates to World space:
        position.matMul( camera.getBack().invert3x3() );
        position.add( camera.getPosition() );
       
        // Determine the direction from the camera position to the click point:
        SimpleVector direction = position.calcSub( camera.getPosition() ).normalize();
       
        // Calculate the distance to whatever was clicked on:
        float distance = world.calcMinDistance( position, direction, 10000 );

...


At this point, a collision event should be sent if something was clicked, allowing you to determine which object it was.

If I were to just blindly guess what the problem is, I would say that maybe you used a direction ray from the click point in the camera direction rather than using a ray from the camera position toward the click point, but that is just a wild guess until I see the code.

Disastorm

#12
thanks ill try out your code: this is what i had
public static void pickingObject(int mouseX, int mouseY){
       SimpleVector ray=Interact2D.reproject2D3D(Main.world.getCamera(), Main.getBuffer(), mouseX, mouseY);
       int[] res=Interact2D.pickPolygon(Main.world.getVisibilityList(), ray, Interact2D.EXCLUDE_NOT_SELECTABLE);
if (res!=null) {
           Object3D selection = Main.world.getObject(Interact2D.getObjectID(res));
           System.err.println(selection);  
           if(selection.getClass().equals(NPCObject3D.class)){
               System.err.println("OPEN_CHAT_WINDOW WITH " + ((NPCObject3D)selection).getNpcName());
           }
}
   }


I got your code working but it still seems to have the same effect as the code I used.  Is it possible it has something to do with how i created my object3ds?

paulscode

Yes, that seems like the next place to look.  Any chance you could put together a simple test case and post the source?

EgonOlsen

And always remember that Interact2D.pickPolygon() doesn't work correctly on compiled objects. This doesn't seem to be the problem here, but i just wanted to mention it again.