2-player game, client and server at localhost

2005-07-30 Thread Michael Rybak
hi, everyone.

I'm writing a 2-players game that should support network mode. I'm now
testing  it  on 1 PC since I don't have 2. I directly use sockets, and
both  client  and  server do computations, the only data transfered is
user mouse/kbd input.

It  works  synchronously,  but  somehow, when I play in client window,
both  client  and  server  have  17  fps, while when playing in server
window,  server  has  44  fps  while  client  has 5, and due to forced
synchronization,  they  both run very slowly (I wonder how come server
says  it  has  44fps?).

Does  anybody have an idea how can this be? Not that users will test 2
game  intances communicating via localhost, but I need to make it work
properly.

-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[2]: 2-player game, client and server at localhost

2005-07-31 Thread Michael Rybak
DLB> This logic will suck up as much CPU time as the OS will give the
DLB> program... While if the client looks like

DLB> loop
DLB> send data to server
DLB> read reply (blocking)
DLB> do nasty computation
DLB> end loop

DLB> then it not only has to compete for CPU time, it does nothing while
DLB> waiting for the server to handle the section inside the IF block.

DLB> But what would happen if you put something like os.sleep(0.025)
DLB> inside the loops? Assuming the loop takes 0.025sec to process, the total
DLB> comes to 0.05 seconds (20fps) AND releases the CPU for the other process
DLB> to compute.

DLB> -- 
DLB>  > == <
DLB>  >   [EMAIL PROTECTED]  | Wulfraed  Dennis Lee Bieber  KD6MOG <
DLB>  >  [EMAIL PROTECTED] |   Bestiaria Support Staff   <
DLB>  > == <
DLB>  >   Home Page: <http://www.dm.net/~wulfraed/><
DLB>  >Overflow Page: <http://wlfraed.home.netcom.com/><



-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


using Pyro for network games

2005-08-01 Thread Michael Rybak
Hi, everyone.
In topic "2-player game, client and server at localhost", I've asked
about subj, and Peter Hansen suggested to switch to Twisted, Pyro or
the like.

I've tried using Pyro.

I've written a very very simple test-game, in which you have 2 balls
controlled by 2 players. Each player moves his mouse somewhere at
his window, and his ball starts moving towards the pointer. No
objectives, just to test how it works. The code is very small, so I
can put it all here, skipping obvious stuff.

I've tried playing this test-game via local-host - all is ok.
Then I've tested via Internet connection with my friend. I have a
33.6 Kbps modem, he has a 2 MBps dedicated line (if this is the term),
and we ran a server at his pc and both connected to it. His ball ran as
a child, smoothly and quickly, while I had about 5 fps :(, and for him
it looked like my ball is simply very slow. I realise that client at
my pc *has* to work slower than the client at server's pc, but hey,
I've played Quake2 and WarCraft 2 via 33.6 modem, and those should have
much more stuff to transfer per second :(

Please help me in any way you can think of. I'd welcome links to
Python games written with Pyro, tips on what I am doing wrong, on not
Pythonically enough - anything.

server.py#
#
[..imports..]
class game__(game_, Pyro.core.ObjBase):
def __init__(self):
#storage for balls' coordinates
game_.__init__(self)
Pyro.core.ObjBase.__init__(self)

[..server initialization..]

daemon.requestLoop()
END#server.py#

client.py#
[..imports..]

[..preparations to create proxy..]
proxy=Pyro.core.getAttrProxyForURI(URI)

[..imports..]

def process_user_input(game, id):#id is client's id - 0 or 1
nx, ny = pygame.mouse.get_pos()
x, y = game.ball[id].get_pos()
dx, dy = nx - x, ny - y
leng = sqrt(dx*dx + dy*dy)
k = 20 / leng
dx *= k
dy *= k
game.move(id, dx, dy) #remote call: move ball


id = proxy.get_n_clients() #which ball to control
if id < 2:
proxy.new_client()

pygame.init()
scr = pygame.display.set_mode((640, 480))

g = game(proxy.get_status(), scr)
#get_status provides 2 pairs of balls's current coordinates
#g, "game" instance, is a local storage, able to render itself

while 1:
g.set_status(proxy.get_status())
g.render()
process_user_input(proxy, id)

time.sleep(0.03)

[..quit = (ESCAPE is pressed)..]
if quit: break

END#####client.py#

-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[4]: 2-player game, client and server at localhost

2005-08-01 Thread Michael Rybak
Again, thank you very much for your help.

DLB> The server should basically handle the multiple client
DLB> connection logic, and determination of interactions between movable
DLB> objects -- collision detection, for example (and I don't mean in the
DLB> terms of graphics rendering but in terms of object one at current
DLB> movement intersecting object two moving at some other vector).

My problem is: there are about 30 movable objects, so transferring
all their coordinates is much more traffic consuming (about 150 bytes
per transfer) rather than sending only user's motions (10 bytes per
transfer). But on the other hand, sending user's motions between two
non-server-neither-clients means that I needed stricted
synchronization, which means the turn-based approach, as you've said.


DLB> I'm also NOT a game programmer, so I'm not sure how well most of
DLB> them separate screen updates from I/O, but I'd turn the above loop into
DLB> something like:


DLB> create screen thread
DLB> create I/O thread

DLB> {screen thread}
DLB> loop:
DLB> compute/display screen using snapshot of "local status"

DLB> {I/O thread}
DLB> loop
DLB> if keyboard has activity
DLB> read data
DLB> send data to server
DLB> if server has activity
DLB> read data
DLB> update local status

DLB> Note that the keyboard, in this simple example, never affects
DLB> the local (client) display -- only the status sent back by the server is
DLB> used. Okay, you may need to process things like "quit" locally .

Well, this look really elegant, but will need me some time to rewrite
my networking that way. Thank's a lot, I'll let you know when it
works.

[..snip..]

]DLB> The server looks like:

DLB> loop
DLB> if new client connect
DLB> add client to list of clients
DLB> send client current status
DLB> if data from client
DLB> update world state (collision detects, damage, etc.)
DLB> for c in client list
DLB> send current status
DLB> if client disconnect
DLB> remove client from list

consider this part:
DLB> if data from client
DLB> update world state (collision detects, damage, etc.)
DLB> for c in client list
DLB> send current status
the problem is - I should do this not "if data from client", but every
50 milliseconds or so, because objects are still moving when not
affected by users. To give you a better idea of what my game is:

Each player controls a snake, which is 2 to 12 balls connected to each
other with ropes; by mouse motions you move the snake's head, and the
rest of the body moves adhering normal physics. The objective/gameplay
is unimportant here, but if you're curios - all the balls of your
snake are bullets, and right-clicking releases current tail. So, you
have to spin around, and release the tail in appropriate moment so it
reaches your opponent, causing as much damage as much impulse it had.
There are health-pots and other stuff on game field of course.

So, you see - server will have to send current status as much time per
second, as much fps I want, and that's quite a lot of data.

I'd also like to mention (if I haven't already) that I have a 33.6
modem, while the friend I'm testing with has a 2 Mbit dedicated line,
if this is the right term.


I also was advised (by Peter Hansen) to try using Twisted, Pyro os
something like that. I've looked at Pyro, and tried using it, without
a lot of success compared to what I have now. I'm starting a new topic
here, describing my experiment.


DLB> Recall my warning -- I'm not a game programmer; this is just how
DLB> /I'd/ consider implementing something like this.
You're being very helpful anyway :)


DLB> -- 
DLB>  > == <
DLB>  >   [EMAIL PROTECTED]  | Wulfraed  Dennis Lee Bieber  KD6MOG <
DLB>  >  [EMAIL PROTECTED] |   Bestiaria Support Staff   <
DLB>  > == <
DLB>  >   Home Page: <http://www.dm.net/~wulfraed/><
DLB>  >Overflow Page: <http://wlfraed.home.netcom.com/><



-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[2]: need for speed

2005-08-01 Thread Michael Rybak
SDA> On Mon, 01 Aug 2005 02:28:36 -0700, [EMAIL PROTECTED] wrote:

>> hi everyone
>> can someone suggest me where find a lot programming tricks for
>> achieving the top speed in python?

SDA> There is only one programming trick you need to know about making code run
SDA> fast.

SDA> Never even waste one second on optimising code before it is working,
SDA> or before you have tested it and profiled it and know (1) that it IS slow;
SDA> and (2) WHERE it is slow.

SDA> Why would you waste your valuable time making bugs run faster? Why waste
SDA> time and effort to speed up something that is already fast enough?

SDA> In other words: Make your code work. Make it work right. Then, and only
SDA> then, make it run fast -- and only if it isn't already fast.

SDA> Now that you have written your code, and you have made it work right,
SDA> please tell us what the code is, and the results of profiling the code,
SDA> and we will help you speed it up.


Is there a way of profiling other than manual (debug output with
measurements and all)? Some tools? And is there some kind of plugin
for native Python's IDLE to trace scripts? I'm a bit tired of getting
all info from debug output and exceptions

SDA> -- 
SDA> Steven



-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[4]: need for speed

2005-08-02 Thread Michael Rybak
sorry for emailing privately, pressed the wrong "reply" button

DLB> On Mon, 1 Aug 2005 20:14:51 +0300, Michael Rybak <[EMAIL PROTECTED]>
DLB> declaimed the following in comp.lang.python:


>> 
>> Is there a way of profiling other than manual (debug output with

DLB> Chapter 10 of the Python Library Reference... You have looked at
DLB> that document, haven't you?
Already am, yes!

>> measurements and all)? Some tools? And is there some kind of plugin
>> for native Python's IDLE to trace scripts? I'm a bit tired of getting

DLB> Have you read Chapter 9?
ok, I'm looking through. A bit tough for me I think, I can live with
debug outputs :) Well I'm too much used to M$ V$ / Borland Delphi
interfaces to switch to almost-asm-like debugging.

DLB> BTW: if you are working on M$ Windows,
 only on that
DLB> you might want to consider installing the ActiveState release
I tried, and the installer gives me that stupid Internal Error 2229:
Control, SELECT 'Control', 'Type', 'X', 'Y', [..snip..], 'Dialog' = ?
And I forgot the OK button.

DLB> -- PythonWin might be nicer than IDLE (and has the referenced
DLB> manuals formatted as Windows help files).
I am using a *.chm file containing all online documentation available
from python.org



DLB> -- 
DLB>  > == <
DLB>  >   [EMAIL PROTECTED]  | Wulfraed  Dennis Lee Bieber  KD6MOG <
DLB>  >  [EMAIL PROTECTED] |   Bestiaria Support Staff   <
DLB>  > ====== <
DLB>  >   Home Page: <http://www.dm.net/~wulfraed/><
DLB>  >Overflow Page: <http://wlfraed.home.netcom.com/><



-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[6]: 2-player game, client and server at localhost

2005-08-02 Thread Michael Rybak
 those 30 frames, because input from other player comes
instantly, about 10 times per second, and server tries sending this to
all clients. So my slow client simply can't know current true status,
thus has nothing to draw, because it can't handle 10 transfers per
second. And if server doesn't send user motions equal number of times
to all clients, while they compute the world's status, they will
happen to have different pictures :(



-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[2]: need for speed

2005-08-02 Thread Michael Rybak
sorry for emailing privately, pressed the wrong "reply" button

BD> Michael Rybak a écrit :
BD> (snip)
>> 
>> Is there a way of profiling other than manual (debug output with
>> measurements and all)? Some tools?

BD> http://docs.python.org/lib/profile.html

BD> HTH

Oh, wow! Manuals rule, I should have at least skimmed through.
Thanks a lot, already profiling :)

-- 
Best Regards,
 Michael Rybak   mailto:[EMAIL PROTECTED]

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[2]: using Pyro for network games

2005-08-02 Thread Michael Rybak
gn20kjss> Do not use pyro, use simple UDP protocol.
gn20kjss> I've written networked tetris in python, communicating via
gn20kjss> UDP protocol, and used it successfully on very congested lines.

Would you please be so kind to share that with me? That would be
greatly helpful, because 1) I'd run it together with my friend to see
what speed I can get from UDP 2) I'd grasp the networking part of your
code and reuse it.

gn20kjss> If all you need is to transfer pointer coordinates, UDP is perfect 
since
gn20kjss> you do not need feedback.

gn20kjss> use something like this for server:

gn20kjss> import socket
gn20kjss> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
gn20kjss> s.bind(('', port))
gn20kjss> while 1:
gn20kjss> data, addr = s.recvfrom(1024)
gn20kjss> print `data`


gn20kjss> and for client:

gn20kjss> import socket

gn20kjss> outsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
gn20kjss> outsock.bind(('', 0))
gn20kjss> outsock.sendto('message', ('server-hostname', server_port))
Would you recommend some reading on this? I have some immediate
questions to your code, but don't want to flood here. OK, I will flood
here a bit: what's the print `` syntax?

P.S. I loved your virus alert ;)


gn20kjss> -- 
gn20kjss>  ---
gn20kjss> | Radovan Garabik http://kassiopeia.juls.savba.sk/~garabik/ |
gn20kjss> | __..--^^^--..__garabik @ kassiopeia.juls.savba.sk |
gn20kjss>  ---
gn20kjss> Antivirus alert: file .signature infected by signature virus.
gn20kjss> Hi! I'm a signature virus! Copy me into your signature file to help 
me spread!



-- 
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


Re[2]: 2-player game, client and server at localhost

2005-08-02 Thread Michael Rybak
CS> Michael Rybak wrote:
>>  That's the problem - "or a player input comes in". As I've explained,
>> this happens a dozen of times per second :(. I've even tried not
>> checking for player's input after every frame, but do it 3 times more
>> rare (if framecount % 3 == 0 : process_players_input()). Well, I've
>> already got it that I shouldn't tie this around framerate, but
>> nevertheless...

CS> There's the key.  How are you processing network input, specifically 
CS> retrieving it from the socket?

A "sock" class has a socket with 0.1 timeout, and every time I
want anything, I call it's read_command() method until it returns
anything. read_command() and send_command() transfer user's actions in
special format so that it takes 10 bytes per transfer.


I believe this should be rewritten to be done in a separate thread, and
that *current* user input should be processed as *next* one:
 while 1:
 render()
 inp = get_player_input()
 thread.start_new(send_inp, (inp,))
 thread.start_new(accept_opponents_inp, ())
 while still_no_opponents_input_from_previous_iteration()
   time.sleep(0.05)
 process_previous_player_input()
 physics.make_step
 
I will try writing it that way, but I doubt it shall make things much
better... You see, I've tried the normal 1-server-2-clients approach
with Pyro (and today with simulating RMI proxy via UDP), and resulted
with nothing comforting. Please read the "using Pyro for network
games" topic here for details.

-- 
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!




P.S. here's the sock class. My server_sock and client_sock are derived
from it, with additional accept_connection and establish_connection
methods respectively.

#sock.py
import socket
import com_network
import constants as c_


class sock:
def __init__(self, host):
self.host = host
self.port = c_._PORT

self.sockobj = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sockobj.settimeout(0.1)

self.curcon = None #connection will be created and saved here
self.connected = False

def read_command(self):
"""format:
command_id - 1 byte
command_size - CMD_LEN_BIT_SIZE bytes
command_text - command_size bytes

returns a triple (int id, int size, str text)"""

if not self.connected:
return (None, None)
cmd = com_network.read_fixed(self.curcon, 1)
if len(cmd) < 1: #no cmd
return (None, None)
sz = com_network.read_fixed(self.curcon, CMD_LEN_BIT_SIZE)
cmd, sz = str_to_cmd(cmd + sz)
text = com_network.read_fixed(self.curcon, sz)
return (cmd, text)

def send_command(self, cmd, obj):
send_text(self.curcon, com_network.cmd_to_str(cmd, str(obj)))

 
def close(self):
if self.connected:
self.connected = False
self.curcon.close
self.curcon = None
self.sockobj.close()

-- 
http://mail.python.org/mailman/listinfo/python-list


Re[4]: 2-player game, client and server at localhost

2005-08-03 Thread Michael Rybak
 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