I was a bit unhappy to read this, because what you describe here is just what I've tried yesterday in my test-game with 2 balls, so if I've pointed that out, you wouldn't have to say I DLB> don't understand threading either, it appears. :'(
Thank you very much for putting so much effort in making things clear to me, *this* email of your made everything clear as never. Still I have problems, and hope you still don't mind me asking. Some comments: >> while 1: >> render() >> inp = get_player_input() >> thread.start_new(send_inp, (inp,)) >> thread.start_new(accept_opponents_inp, ()) DLB> You don't understand threading either, it appears. Here you are DLB> starting a new thread for each input you want... and >> while still_no_opponents_input_from_previous_iteration() >> time.sleep(0.05) DLB> You're still focused on a turn based system, it looks like... Now, that's *not* how I'm tending to do it; that's what I was thinking of while trying the turn-based approach, and describing here; Christopher Subich asked how it was done initially, so I brought my hanging system out of shame again, and added something I was thinking about to improve it, while I already realize that's not the way to go - from your previous comprehensive posts. DLB> There should just be AN input thread, started at the very beginning, DLB> and it should just wait for input, then update the global state so DLB> the "update step" can do whatever. As stated above, that's how I'm trying it right now. Still, if doing it turn-base, I would have to create a new thread every time. I have some other questions though - please see below. DLB> Also, recommend you use threading, not thread as the module. Surely will, why? DLB> SERVER DLB> An input thread would look something like: DLB> while True: DLB> data = socket.read() #assumes both clients write to same socket DLB> #otherwise use a select(client_socket_list) DLB> #followed by socket.read for the flagged socket(s) DLB> parse data DLB> lock global DLB> save in global state variables DLB> unlock global Now, few questions. Do I need to time.sleep(0.xxx) in any of these while True: loops, not to overwhelm CPU? I can measure the time at beginning and end of each iteration to make things happen fixed number of times per second, but should I? And another: do I get it right that instead of "lock global" you mean: while global.locked: time.sleep(0.001) lock global And I also wonder how do I make sure that 2 threads don't pass this "while" loop simultaneously and both try locking global. There is a probability, not? Now, for update thread: DLB> That is all DLB> Update thread DLB> while True: DLB> lock global DLB> copy state variables to local DLB> unlock global DLB> compute new world state (check for collisions -- "bullet" hits) DLB> for c in client_list DLB> send world state to c In my yesterday experiment, I have a separate thread for each of 2 clients, and what I do there is: def thr_send_status(player_sock): while 1: t, sub_addr = player_sock.recvfrom(128) #player ready to accept player_sock.sendto(encode_status(g.get_status()), sub_addr) I'm reading 1 byte from client every time before sending new update to him. OK, Ok, I know that's not good, ok. Now, I like your idea much more, where you say we first measure the processing speed of each client, and send data to every client as often as he can process it: DLB> Slow client receives the first at T0, but the last (packet 100) comes in DLB> at T0+60. Fast client receives all packets in T0+10... DLB> It took 60 seconds to receive 10 seconds of data. Client sends DLB> back to server a rate of 6. Other client sends back rate of 1. DLB> Server now uses a modulo function on packet sends... DLB> for c in client DLB> if t mod c.rate = 0 DLB> send current world packet to client Yes, this I great, but what if speed changes? Should I retest this around every 10 seconds? I mean, server sending too much data to a client is ok for server, but very bad for a client, since it starts hanging and loses synchronization, unless I use a timestamp to throw away late states (I think I need to re-read all your previous posts, you've explained about synchronizing already). While thinking about this, I've decided to go the wrong way, and to wait for confirmation from client before sending next pack. Still, it shouldn't slow anything a lot, because client does this: def thr_get_status(self, g, player_sock, player_id): while 1: player_sock.sendto("!", addr) #ready self.local_status = decode_status(player_sock.recvfrom(128)[0]) g.set_status(self.local_status) So they simply exchange data all the time in separate threads, even through separate sockets (not to dispatch the confirmations from different players into corresponding threads via global flags), which makes the "ready" thing ok from speed point of view, but I prefer your way, quoted above, so my question is still valid - do I remeasure speed? I'm also almost sure it's wrong to have separate sockets and threads for each player, you say I should select()/dispatch instead, but I'm afraid of that some *thing* being wrong with select() for Windows. Somehow, I'm doing a lot of thins the wrong way :( Before describing another problem I've encountered, I thought I'd remind you of what my test game is: each player controls it's ball by moving mouse pointer, towards which his ball starts moving; that's it. When I first tried this with threads, 1 client ran nearly perfect. But when running 2 clients via localhost, they eat cpu away, and bad things happen. Now, you see, sending user motions to server appears to be faster (or at least not slower) than getting new status, so, as a result, I have the following picture: I place my pointer somewhere, and the ball runs to it, and then runs a bit beyond it, because by the moment server knows the ball is already at my pointer, client still thinks it's not. Several seconds later, thins "a bit beyond" becomes "a lot beyond", and finally both balls run away from game field, being helpless; seems like I/O thread being much more productive than send_status one? I thought that the reason is my stupid "ready" check before every status update, and removed it. As a result, even single client via local host was very slow, but no artifacts. This all was when I had *no* time.sleeps in the while 1: loops. So I added time.sleep(0.005) to server's send_status loop and to client's send_user_action loop. Things became better, but still balls are spinning around the mouse pointer instead of running under it. Every time client tries moving towards the mouse, it's ball is already at another place at server, and it runs in wrong direction. Obviously, if I have these problems in such a primitive test at localhost, I shouldn't even try running it online with the Snakes :( Thanks again for being this helpful, Dennis, and thank you for your patience! -- Best Regards, Michael Rybak mailto:[EMAIL PROTECTED] Antivirus alert: file .signature infected by signature virus. Hi! I'm a signature virus! Copy me into your signature file to help me spread! -- http://mail.python.org/mailman/listinfo/python-list