using Pyro for network games

M

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

garabik-news-2005-05

Michael Rybak said:
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.


Do not use pyro, use simple UDP protocol.
I've written networked tetris in python, communicating via
UDP protocol, and used it successfully on very congested lines.
If all you need is to transfer pointer coordinates, UDP is perfect since
you do not need feedback.

use something like this for server:

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


and for client:

import socket

outsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
outsock.bind(('', 0))
outsock.sendto('message', ('server-hostname', server_port))



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

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

garabik-news-2005-05

Michael Rybak said:
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

http://melkor.dnp.fmph.uniba.sk/~garabik/pytris.html

contrary to what the page says, you do not need pyncurses, just plain
curses as included with modern pythons
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.

see the Net() class. I recommend you to use the same number for myport
and otherport (you can with UDP, and it makes traversing firewalls
easier)
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

just the socket.socket documentation, and generally for UDP protocol,
see e.g. http://www-net.cs.umass.edu/kurose/transport/UDP.html

Using it is very simple, on one computer, you send a (short) string,
and on the other computer you receive the string (or it might be lost on
the way). For your situation, I'd recommend to implement some sort of
time constrain - e.g. if user moves cursor very fast, ensure that the
coordinates are not transmitted with higher frequency that 50 Hz (or
something). And combine the coordinates into one packet - it always
helps to reduce the number of packets.
questions to your code, but don't want to flood here. OK, I will flood
here a bit: what's the print `` syntax?

the same as repr, i.e. textual representation of a variable - good for
debugging
P.S. I loved your virus alert ;)

and you got infected I see :)

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,197
Latest member
ScottChare

Latest Threads

Top