antoinelechacal
|
 |
«
Posted
2006-03-16 22:42:13 » |
|
Do you think synchonous or asynchonous network is the best for a MMORPG?
Can you develop your opinion, give the pros and cons of both methods...
|
My name is nobody
|
|
|
Riven
|
 |
«
Reply #1 - Posted
2006-03-17 00:11:17 » |
|
Generally you don't want blocking when having many connections. That would mean a lot of threads, which in this case is a waste of performance.
P.S. what is a MMORG anyway?
|
|
|
|
Jeff
|
 |
«
Reply #2 - Posted
2006-03-17 00:37:58 » |
|
Client can afford to block.
Server cannot.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
antoinelechacal
|
 |
«
Reply #3 - Posted
2006-03-17 08:25:58 » |
|
So you guys think it's better using asynchonous network? P.S. what is a MMORG anyway? MMORPG stands for Massive Multiplayer Online Role Playing Game. This means many clients, many messages etc. Let's say I have a game loop (60fps) on every client, how can I keep all the clients synchonized (so that all the clients see the same thing), avoiding lags? Thanks. See ya
|
My name is nobody
|
|
|
Riven
|
 |
«
Reply #4 - Posted
2006-03-17 09:14:52 » |
|
P.S. what is a MMORG anyway? MMORPG stands for... MMORG = massive multiplayer online role game ? You misspelled it in your title, i was just giving a subtle hint 
|
|
|
|
antoinelechacal
|
 |
«
Reply #5 - Posted
2006-03-17 12:15:54 » |
|
Sorry, I took me 2 posts to realize... lol
No idea of how to handle clients synchronizing?
|
My name is nobody
|
|
|
Kova
|
 |
«
Reply #6 - Posted
2006-03-17 13:19:53 » |
|
I'm far away from network programmer, but my first thought is client sending their data to server who sends everyone's data to clients, who then process it  Of course there would be a small lag from time spent to send the data. Idea couldn't be more simple, but it's up to ppl how to implement it.
|
|
|
|
|
antoinelechacal
|
 |
«
Reply #7 - Posted
2006-03-17 16:28:12 » |
|
Yeah basicaly this is what I have to do, but what I don't know is how to synchonize two clients.
Indeed, both clients won't run at the same speed, do I have to make all the clients run at the same speed as the slowest client? Or do I have to let each client run at its own speed and from to time teleport people?
|
My name is nobody
|
|
|
Riven
|
 |
«
Reply #8 - Posted
2006-03-17 16:35:47 » |
|
Every client should have a predictable ticker, independant of the framerate (say: 50Hz) in which the game-logic takes place.
Then all clients run at exactly the same speed.
|
|
|
|
antoinelechacal
|
 |
«
Reply #9 - Posted
2006-03-17 16:48:13 » |
|
What do you call a ticker?
Thanks?
|
My name is nobody
|
|
|
Games published by our own members! Check 'em out!
|
|
Riven
|
 |
«
Reply #10 - Posted
2006-03-17 19:32:39 » |
|
A thread that sleeps precisely enough milliseconds to wake up at a fixed interval. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| long nextTick = ...; long tickInterval = 20; while(true) { long now = ...; long timeToNextTick = nextTick - now; if(timeToNextTick > 0) sleep(timeToNextTick);
nextTick += tickInterval;
runLogic(); } |
|
|
|
|
antoinelechacal
|
 |
«
Reply #11 - Posted
2006-03-17 19:42:47 » |
|
New stupid question, what do you call "the game-logic"?
|
My name is nobody
|
|
|
Kova
|
 |
«
Reply #12 - Posted
2006-03-18 00:05:13 » |
|
it's how game works, in this case from programmer's point of view, like: first I draw something then I update something then I wait for user to click with mouse then I sleep... and so on... of course in precise form, this is extreamly simplified
|
|
|
|
|
DzzD
|
 |
«
Reply #13 - Posted
2006-03-18 01:26:34 » |
|
you may use a common timer to synchronize client and server:
- first found offset time between client and server : do many ping requesting server time and keep difference between client time and server time + average ping time * 0.5 (periodically update this offset)
- use your local client timer and add offset you found by ping to know server time, this way all client will use the same time (the server one)
- use interpolator for shared values (as player pos) to know aproximatively value at time t or to predict values, this is necessary because value keys can be late or too much spaced in time for low bandwith.
- use previous time based values (interpolated/extrapolated): for player pos and collision detection
- alternatively correct values when new keys arrive (and perform a server validation for movement and other to avoid cheating)
- this way each client is able to use a different framerate and bandwith.
ex prog: //Compute server offset time //need to be perform multiple time and averaged, also need to be updated periodically localTime=System.currentTimeMillis(); serverTime=networkServerTimeRequest(); pingTime=localTime-System.currentTimeMillis(); serverOffsetTime=serverTime-localTime-pingTime*0.5;
//Read all shared values key from server, ex all player pos while(serverPacketPlayer()) { player=getServerPacketPos() addTimeBasedPlayerPosKey(player.name,player.time,player.pos); }
//Rendering a frame
//For each player do playerPos=getTimeBasedPlayerPosAt(localTime+serverOffsetTime) drawPlayerAtLocation(playerPos)
//Computing colision, logic
//For each player do moveWithCollison(lastRealPlayerPos,playerPos) //lastRealPlayerPos mean last received server keys before current time
|
|
|
|
CommanderKeith
|
 |
«
Reply #14 - Posted
2006-03-18 03:49:33 » |
|
Hi, Unless you've got a turn based game i think that its best to run the clients asynchronously or the graphics will be choppy. Using a time-based approach has worked best for me. The gameWorld on the client has a time stamp of when it was last updated, and the gameWorld sent from the server does too. Use System.nanoTime() instead of System.currentTImeMillis() since the the latter is very imprecise on windows and makes the game look choppy.
This is how my client's game loop works:
int newGameWorldRelativeNanos = 0; long nanoTimeLastUpdated = System.nanoTime();
while(shouldRun){ long currentTime = System.nanoTime(); long timeSinceLastUpdate = (currentTime - nanoTimeLastUpdated); cumulativeNanosBetweenUpdates += timeSinceLastUpdate;
long timeElapsedNanos = timeSinceLastUpdate - newGameWorldRelativeNanos; // store the Player's events if (!(timeElapsedNanos < 0)){ gameWorld.update(timeElapsedNanos); } else{ // don't update the gameworld using a negative time, just replace it. java.awt.Toolkit.getDefaultToolkit().beep(); }
newGameWorldRelativeNanos = 0; nanoTimeLastUpdated = currentTime; view.reDisplay(); doMinSleep();
// update to the ServingController's new GameWorld if has been sent exists. networkPlayer.doClientAgentRecieve(); // this method calls setGameWorld(...) below if a new gameWorld was sent. }
public void setGameWorld(GameWorld gameWorld, long oldGameWorldTotalNanosElapsed){ newGameWorldRelativeNanos = (long)(gameWorld.getTotalNanosElapsed() - oldGameWorldTotalNanosElapsed); this.gameWorld = gameWorld; } Keith
|
|
|
|
CommanderKeith
|
 |
«
Reply #15 - Posted
2006-03-18 03:51:55 » |
|
Using this way you don't have to worry about pings and the only thing that can screw you up are the garbage collector pauses.
|
|
|
|
antoinelechacal
|
 |
«
Reply #16 - Posted
2006-03-18 12:19:13 » |
|
Thank you guys, I will consider your solutions, thanks for being that helpful!
|
My name is nobody
|
|
|
|