home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / programming / basic / udpchat / lag problems in net games next >
Encoding:
Text File  |  1999-05-14  |  21.7 KB  |  457 lines

  1. On 11-Apr-98, Paul Burkey wrote:
  2. >Hi Dave,
  3.  
  4. >> Now that's all fine, I can do most of the TCP/IP stuff pretty
  5. >> easily, but I have some other problems. Does anyone know of the best
  6. >way
  7. >> to do 8 seperate players playing on the same game over the internet.
  8. >Like
  9. >> how would you linkup 8 players...all to one player, or all in a
  10. chain.
  11.  
  12. >With more than 4 players I'd avoid the chain idea. That is unless you
  13. >can deal with large amounts of lag and you don't need to be fully
  14. >synchronised. The 1 server many clients idea is the safest and easiest
  15. >system to deal with but ALWAYS the best way.
  16.  
  17.    First check out Paul's netpage:
  18.   <http://www.sneech.demon.co.uk/netlink.html>  
  19.  
  20.    It's got some links to pages with the problems you're likely to come
  21. up against. I've been researching this for the last 6 or so months (with
  22. some help from Paul), because I want to put multiplayer internet support
  23. into a similar type of game as yours- a fast reaction arcade game. The
  24. big problem as far as I can see is the lag you get from when one
  25. computer sends a move, and the other machine receives it. This is worse
  26. on a 2D game because you'll see if something's a few pixels out- on a 3D
  27. game you'll never really notice anything is out, unless the lag is
  28. terrible. You have to do everything to cut down the lag time
  29.  
  30. >> it depends on how much data I'm gonna have to send to every player.
  31. >> And that's the second problem, do I just send co-ordinates of
  32. >> every player, and say ever players bullets, and any objects
  33. >> they pick up, or do I send just the players action, and work out the
  34. >> outcome of that action and then reply with a message to say that it
  35. >worked
  36. >> okay.
  37.  
  38. >As always it's not easy to give any firm directions with this kind of
  39. >stuff. You may have good reasons why you need to keep things
  40. >synchronised
  41. >or you may have a design that can cope with large amounts of lag. It
  42. >depends on the gameplay really. I'd probably suggest using the I/O
  43. >method where instead of sending coordinates or players, bullets
  44. >and whatever else. You just send the players inputs. So if player 1
  45. >moves forwards you send this. If he doesn't move anywhere then you
  46. >don't send anything.
  47.  
  48.    Yes, I think this is the only way you could have it work for lots of
  49. players- otherwise you'd physically run out of bandwidth (you wouldn't
  50. be able to get enough information through the modem in a given time).
  51. Instead of sending out each new pixel position of an object, you just
  52. send out differences in speed, acceleration and direction with a
  53. time-stamp. As all machines are time-synced at the start you can then
  54. adjust the Avatar (copy of your player etc on another machine) to the
  55. exact position the original is on-screen (using simple physics), because
  56. you know what speed and direction it was traveling at a certain point in
  57. time. Your characters actually are in sync more than the position method
  58. which would always be behind by whatever the lag was. This is how
  59. Quake/XWing etc do it. 
  60.   So if a monsta is traveling down a corridor, you can ignore it until
  61. it goes down a different angled corridor, then you send this info out to
  62. the other machines. You just have to have one machine only, responsible
  63. for each object onscreen- so I was thinking of using the Server to say
  64. which machine is responsible for which monsta etc (even though I'm using
  65. peer-to-peer, I've got a Server to log in to), and other objects like
  66. bombs, doors, etc could be controlled this way as well. This solves your
  67. problem about having two players in one space, as only one machine makes
  68. the decisions for each object. You might get visual glitches like
  69. shooting a player and it misses them when it should have hit, because
  70. the actual player was really a few pixels off, but if the lag times can
  71. be kept down this shouldn't be much of a problem.
  72.  
  73.    A point raised on one of the web pages, was the problem that could be
  74. caused by lag. Say for example, a monsta has AI that makes it chase a
  75. player on line-of-sight. If a player changes direction just before an
  76. intersection say, and a monsta is in line-of-sight of that intersection
  77. eg:
  78.  
  79. -------------+-+--------------
  80.             P->                           P- player
  81. -------------+ +--------------
  82.              | |
  83.              | |
  84. -------------+ +--------------
  85.               M->                         M- monsta
  86. -------------+-+--------------
  87.  
  88.  
  89.   If the lag to one machine is greater than another, you could get the
  90. situation of the monsta going in two different directions on the two
  91. machines. On the machine with the faster connection the Avatar has
  92. turned back (as the human player has), so the monsta carries on along
  93. the way it was going; on the machine with the slightly slower connection
  94. the Avatar goes a few pixels into the corridor before turning back, and
  95. the monsta sees it and changes direction and chases it down the
  96. corridor. Once the monsta changes course on one machine, the courses of
  97. the two monstas will continue to diverge :-/  (sort of like that old (I
  98. think it was H.G Wells') sci-fi story about the guy who goes back in
  99. time and accidentally kills a butterfly :)
  100.   If you have the one machine only making decisions for an object, it
  101. solves this problem. 
  102.  
  103. >> Like if 4 players each tried to enter the same square, and only 1
  104. >> could...which one would it be, and how would I tell all the others
  105. >which
  106. >> one it was. I hope that hasn't confused everyone...cos it's confused
  107. >me.
  108.  
  109. >This is where the 'one server many clients' idea can make life very
  110. >easy. The following is just a rough plan, I'm making most of it up
  111. >as I go along so feel free to pick the ideas appart until we can
  112. >agree on a solution. Also lets understand that this idea would work
  113. >for some gams and not for others...
  114.  
  115. >Lets imagine you have 20 players. Each player would have a unique
  116. >number eg 1,2,3..20. Now imagine that each player has to send
  117. >commands to the server and wait for the command to arive back before
  118. >the command can be executed. A command may be something like 'shoot',
  119. >'move forwards', 'move backwards' or whatever. Any commands player
  120. >1 sends to the server will be mirrored to all other players as well
  121. >as himself. Now lets imagine that the server is setup so that it
  122. >will take incomming commands for 1/10 of a second and then send
  123. >them all out. If no commands are taken then the server will send a
  124. >'no commands' message to everyone. The game would be setup to
  125. >gather these commands and sort them into order. So all player 1
  126. >commands would be executed first, then player 2 and so on. A better
  127. >solution would be for the server to attach a timestamp to each
  128. >command as it arives. Then a batch of commands are sent out and
  129. >these can then be sorted into the same order as thy arived on
  130. >the server.
  131.  
  132. >Some extra error checking should be used in this example but theres
  133. >no need to go into too much detail here.
  134.  
  135. >To get back to your question.. Each player would move towards
  136. >this same square at the same time. So the 'move to square'
  137. >command is sent to the server and then the server sends these
  138. >commands to the players. All players will attempt to execute
  139. >the commands in the same order so player 1 will be first and
  140. >then player 2. Player 2 can't move into the square because
  141. >player 1 beat him to it.
  142.  
  143.    This is ok as long as it runs fast enough for your game- for an
  144. arcade type game I think it might run too slow (as you have to send the
  145. message to the Server and then back to the Client (which could double
  146. lag times). I'm using Peer-to-Peer (every machine sends its messages to
  147. all machines), which by-passes the Server. 
  148.    In Quake, I think they have a max of 8 players peer-to-peer, and up
  149. to 16 going through a dedicated Server (as in Paul's way, but only to
  150. pass messages on, not to do any logic). But these Servers are rather
  151. powerful with a fast direct net connections.
  152.  
  153.    This is all theory at the moment as I haven't had time to put the
  154. code into a small test game to see what works :-/
  155.  
  156.    Also am using UDP instead of TCP which is much faster but has no
  157. error checking. I've done a little chat program using UDP which checks
  158. wether packets have arrived at their target or not, and has a basic
  159. log-in Server- but all messages are still sent direct to all machines,
  160. that are logged on.
  161.     I'll put it on Aminet, but I need to tidy up the docs first- I can
  162. send it to you if you want.
  163.  
  164.  
  165. On 14-Apr-98, Dave Newton wrote:
  166.  
  167. >>>With more than 4 players I'd avoid the chain idea. That is unless you
  168. >>>can deal with large amounts of lag and you don't need to be fully
  169. >>>synchronised. The 1 server many clients idea is the safest and
  170. easiest
  171. >>>system to deal with but ALWAYS the best way.
  172.  
  173. >> I've been researching this for the last 6 or so months (with
  174. >>some help from Paul), because I want to put multiplayer internet
  175. >support
  176. >>into a similar type of game as yours- a fast reaction arcade game. The
  177. >>big problem as far as I can see is the lag you get from when one
  178. >>computer sends a move, and the other machine receives it. This is
  179. worse
  180. >>on a 2D game because you'll see if something's a few pixels out- on a
  181. >3D
  182. >>game you'll never really notice anything is out, unless the lag is
  183. >>terrible. You have to do everything to cut down the lag time
  184.  
  185. > Well, I had almost made my mind up on server->clients way of doing it.
  186. >Let
  187. >me explain more about the game, so you know why I thought this would
  188. >work
  189. >for me. Basically, it's a blockbased game, you move from one square to
  190. >another, and it takes so many frames to get to the new block. All I
  191. >really
  192. >need (or atleast all I think I need) is someway of keeping track of all
  193. >the players. I need to make sure they don't walk into eachothers
  194. >squares,
  195. >and make sure that I know who's picked up what object, and whether they
  196. >have fired there gun. Now, I'm thinking for the monsters, that if I
  197. keep
  198. >all the players in sync, then each machine will be able to use the same
  199. >monster routine to keep all the monsters in the correct place, without
  200. >sending any messages about them. Because I keep track of the players,
  201. >then
  202. >say monster1 will always attack the closest player, and if they need to
  203. >do
  204. >any random stuff, I'm going to generate a seed, and send it to all
  205. >players
  206. >before the game starts, so when you do rnd(10) on everyones machine,
  207. >everyone gets the same number back :).
  208.  
  209.   The problem is with this, is that if the delays (lags) from the Server
  210. to the  players are different, the commands will end up being executed
  211. at different times and that means that the monstas could react
  212. differently on different machines, as in the diagram in my last post.
  213. One way around this could be to put on a delay for when the move is to
  214. be executed- if this delay is less than the max allowed lag, say one or
  215. two seconds, then everything will run as above. It sounds like your game
  216. might be able to handle a delay like that- only playtesting would tell
  217. you. 
  218.  
  219. > I think the limit for this game is 8 players, and all I need to do is
  220. >send
  221. >a single byte for each player to the server from each client, then wait
  222. >for a 8 byte answer, which includes my next move, and all the other 7
  223. >players next move. Now because it's square based (ie, there not roaming
  224. >free on the game), I don't need to send stuff every frame, as say it
  225. >takes
  226. >8 frames to get from one square to another, then I'd have about 8
  227. frames
  228. >to
  229. >use for the wait (lag - both ways).....correct?? Though this may seem a
  230. >lil
  231. >slow to the player, as he may have to wait 8 frames before his
  232. character
  233. >moves on the screen.
  234.  
  235.   This might make the game horrible to play- you'd have to do some
  236. testing to see.
  237.  
  238. > Now, assumming that works...I have some other queries. If I'm on a pal
  239. >screen, and my opponent is on a ntsc screen, I'll have to do some fancy
  240. >sync
  241. >keeping/checking, so that my oppenent isn't ahead of me, as if it takes
  242. >8 frames for my character to move, he'll see me at the square I'm
  243. moving
  244. >too before I get there. I was thinking, If I wait for the server to
  245. >reply
  246. >everytime, before doing anything else, then I supposed the sync could
  247. >be the server return, as then everyone would move about, and then send
  248. >their
  249. >next move, and wait for the server to send the new moves. This would
  250. >mean
  251. >that ntsc users wait longer than pal users....but I don't mind that :).
  252.  
  253.    You could just drop frames in your NTSC game (10 every second), or
  254. have a timer and drop frames, and sync everthing from that timer- I was
  255. going to do that for my game, as I haven't got any CIA timings working.
  256. I worked out you drop your counter (50 per second), one number every 6
  257. frames= 10 frames dropped every second, and then your PAL just runs one
  258. count per frame- I was going to use the vertical blank interupt, instead
  259. of just a counter in the main loop in case the game slowed down (say by
  260. another program multi-tasking), so every game always was synced.
  261. Although if some-one changed from NTSC to PAl in the middle of the game
  262. it would stuff up though- so a CIA timer would be preferable.   
  263.  
  264. > Now what's the best way of getting people to find other players??? I
  265. >assume you would need a server that registers people who have this game
  266. >and are currently online, and you can request a list, to see who's on,
  267. >then ask them if they want a game. Now to register, you would have to
  268. >run a special program that puts your hostname into a database, and
  269. >then when you disconnect from the net, you'd have to send a offline
  270. >message
  271. >to this database. The server would need to be on 24hrs so I was
  272. >wondering
  273. >if you could say write a cgi script, then use a specially written
  274. >program
  275. >to act like a web browser and pass your information on to the cgi kept
  276. >database...or would you have to beg someone with a permanent connection
  277. >to
  278. >run a script or daemon for you.
  279.  
  280.   There's a program on Aminet called AmiComSysMUI.lha, which does just
  281. that- it has a permanent Server, and when you go online it logs into the
  282. Server- you can put whatever message you like on the Server- ie: hosting
  283. such-and-such game. You can start programs from AmiComSys and send them
  284. arguments like the IP address of the person acting as game Server, so to
  285. join a game you just click on a button in AmiComSys. You could do it by
  286. sending the IP address to your game through Arexx as well if you wanted.
  287. Also you can chat to others online with an external program that comes
  288. with it.
  289.    Another similar program is QamiTrax which does a similar thing, but
  290. can't launch programs yet. Also look out for the port of ICQ (some
  291. people are attempting to do it- but having a bit of problem with the
  292. original authors). It is a very sophisticated program currently on the
  293. PC/MAC. 
  294.  
  295. > Now the other thing is that would be
  296. >fine
  297. >for just two player games, but not for 8 player games, as how would you
  298. >know when to start, how long would you wait for players to join?? Well,
  299. >you could fix a time limit, and when you connect to the data base, it
  300. >just
  301. >time stamps it, and when someone access the list, it'll tell you how
  302. >long
  303. >before the next game starts (unless you've missed it). In this way,
  304. it'd
  305. >mean that you don't go need to register when you log onto the net, you
  306. >only need to register once, when your ready to play the game in 10
  307. >minutes,
  308. >and the database will delete entries that have already started. After
  309. >that you could have a daemon on your computer that when someone has
  310. >found
  311. >you from the server database, it asks you if you want them to join in,
  312. >and
  313. >adds the host and alias to the game connect list, and then when the
  314. >timer
  315. >has run out, the game starts and connects to all the people on the
  316. list.
  317. >Good idea????
  318.  
  319.   Yes indeed :-) If you want ideas, check out the way Quake on the
  320. PC/MAC does things, and also the game-launcher/chat program Kali (also
  321. on PC/MAC). They do some of your ideas above. A simple way to start off
  322. is what I've done, is just have one machine as log-in Server, and each
  323. player logs into that. The level, environment etc is set by the Server
  324. (ie: the person hosting the game). A group of people chat together on
  325. IRC, or AmiComSys and agree to join together in a game, then they log
  326. into the Server and the Server auto-starts the game when they all have
  327. logged in, or maybe the person running the game starts it manually if
  328. someone doesn't log in. 
  329.   Another way is like Descent, and the game is started by the Server,
  330. and people can join in at any time- but your game has to be set up to
  331. allow this.
  332.    The Server needs to put it's IP address out for people to
  333. log into as it usually changes every time you log in- I've written a
  334. little procedure to get this on your own machine.
  335.  
  336. > I don't suppose theres some way of 'broadcasting' to all clients just
  337. >using
  338. >a single port...I assume the server has to have a port to each client,
  339. >and
  340. >then send the same 8 bytes to all the ports....(correct???). And how
  341. >much
  342. >better is UDP???
  343.  
  344.   Well, you can with UDP, as each UDP packet you send out has it's own
  345. address, so you only need one port (you can send out, and receive
  346. everthing from this one port). With TCP you have one port for every
  347. player, you can do this with UDP if you wanted. 
  348.    There is `IP MultiCasting' for large numbers of players, but I don't
  349. know a lot about it- some of those pages mention it.
  350.   UDP is better for speed (much smaller lag times)- Quake etc use it.
  351. But TCP is much easier to use- I'd try it first and see if it works for
  352. your game.
  353.  
  354. > I have already started writing a test for my square based tcp/ip game,
  355. >and I may have a go at a non square based tcp/ip game just to see if
  356. >it's
  357. >possible. If I do, I'll upload the test source for that somewhere, and
  358. >let
  359. >everyone know :).
  360.  
  361.   I've got a small game I wrote, that uses Paul's TCP Client-Server
  362. routines, if you want an example.
  363.   
  364.  
  365. On 16-Apr-98, Paul Burkey scribbled:
  366.  
  367. >>   If your game can handle a slight lag, you could put out a timestamp
  368. >> with your commands, and all the commands are delayed a couple of
  369. >> seconds, to make sure that they all get executed at exactly the same
  370. >> frame on each machine- then you could have the AI being executed on
  371. >each
  372. >> machine. But with a fast action game this wouldn't be practical.
  373.  
  374. >okay, heres the "closer to original" idea... The server would gather up
  375. >the commands for 10th of a second or whatever delay you wanted to use.
  376. >The server may have 10 commands from different players. It would post
  377. >these commands to all of the players and the players would read them
  378. in,
  379. >sort them and excecute them. The players would also get an extra packet
  380. >telling them how many commands they should expect. In this case 10. So
  381. >they stay in a loop until all 10 commands have arived. This would force
  382. >some kind of "time sync" every 10th second where all players will
  383. accept
  384. >incomming commands and execute them. This means the environment is
  385. >kept in perfect sync so even the cpu AI will be using the same data
  386. >on each machine. This verion has the drawback of forcing a delay until
  387. >the packets have arived but with carefull choice of 'delay time' the
  388. >lag could be beaten.  While I recomended the server would be running
  389. >with some kind of time delay (10th of a second or whatever) the games
  390. >would be running in "frames" so if a game is running at 20fps it
  391. >would read incomming commands every 2 frames. Carefull thought would
  392. >be needed to avoid the case where the server and the games are running
  393. >at the wrong speeds :)
  394.  
  395.    Hmm, yes that would work. The only problem I see here is with your
  396. monstas running around- if the delays from the server are different they
  397. might change direction at different times on different machines, as the
  398. frame might get executed at different times on the different machines.
  399. The internal AI is executed the same, as all the commands are executed
  400. in same frame in each machine. As long as it doesn't really matter to
  401. the gameplay, and they're just a visual clue, it should work ok,
  402. - especially as you have many peasants wandering around, there normally
  403. should be enough to get the idea across. 
  404.   Also, more importantly, I assume all their movements are
  405. pre-calculated (ie: go to point x,y) in each frame so they'd all wander
  406. around identically.
  407.   Your system is then synced by frame, rather than by all running the
  408. same synced time. As your system has some time between frames, it would
  409. allow your computer to `catch up' so to speak with the other machines,
  410. if your machine got behind because of a slow lag time time, or being
  411. slowed by multi-tasking (assuming that the multi-tasking wasn't taking
  412. too much CPU time for too long :-/ 
  413.    The 1/10th of a second delay of the Server (100ms) would be too much
  414. of an overhead for a speed game I would think, but wouldn't 
  415. be noticed in your game :-)
  416.  
  417.  On 18-Apr-98, Paul Burkey wrote:
  418.  
  419. >> - especially as you have many peasants wandering around, there
  420. >normally
  421. >> should be enough to get the idea across. 
  422. >>   Also, more importantly, I assume all their movements are
  423. >> pre-calculated (ie: go to point x,y) in each frame so they'd all
  424. >wander
  425. >> around identically.
  426.  
  427. >No, the people calculate their routes as they walk. This avoids the
  428. >case where a building is placed in the middle of a pre-calculated path
  429. >causing him to walk through it. It also allows him to escape or
  430. >attack any enemy characters who could also cross his path. Then maybe
  431. >he is following another character who is moving about. These are
  432. >just a few simple reasons why the routes should be caulculated in
  433. >real-time. This doesn't affect the TCP commands system because of the
  434. >way it is synced up on a 'frame by frame' basis.
  435.  
  436.    Yes, all commands are started at the same frame on each machine, so
  437. any characters would start off on a journey (say) on the same frame, and
  438. would wander around the same way, as the AI is being executed
  439. identically on each machine.
  440.  
  441. >>    The 1/10th of a second delay of the Server (100ms) would be too
  442. >much
  443. >> of an overhead for a speed game I would think, but wouldn't be
  444. noticed
  445. >> in your game :-)
  446.  
  447. >The time lag only affects the "control" of the game. So the time when
  448. >you'd notice a large amount of lag would be when you issue a command
  449. >and it doesn't actually take effect for a second or two.
  450.  
  451.    Yeah, that's what I meant, not actual CPU time :)
  452.  
  453. ---------
  454.  
  455.         Anton Reinauer <anton@ww.co.nz>
  456.  
  457.