Re: [pygame] time progression independent of game ticks

2007-07-20 Thread Dave LeCompte (really)
Daniel Nixon [EMAIL PROTECTED] wrote:
 What advantage does calling pygame.time.wait() have over simply
 lowering the frame rate passed to .tick()?

I should really leave this one for folks who have been deeper into the SDL
C code, but my understanding is that (at least until recently) for small
frame times (frame rates above 30 fps? I don't recall), the
tick(framerate) call tries to be accurate - and it accomplishes this by
hogging the CPU.

The wait() approach, on the other hand, guarantees that your program
yields the CPU for a certain amount of time - you don't know when wait()
will return, but the clock.tick() function gives you the timing data that
you need, anyway. (And, don't worry - it's pretty close to the amount of
time you specified, but it might be a little off.)

The results of hogging all the CPU for your own process means that other
processes end up getting starved for CPU, which isn't a good idea on
multi-processing OSes (and who knows what the players are running in the
background).

All this ends up with a little bit of a counterintuitive practice: to get
smooth behavior, call wait(), even though it's unpredictable. It'll
average out and be more consistent than trying to manage time too
precisely.


-Dave LeCompte


Re: [pygame] time progression independent of game ticks

2007-07-20 Thread Simon Wittber

On 7/20/07, Daniel Nixon [EMAIL PROTECTED] wrote:

What is the best way to go about such a thing? Use MVC and run the
model in its own thread? If that is the case what is the best way to
keep track of the passage of actual time within the model?


This may or may not help:

http://entitycrisis.blogspot.com/2007/07/general-pygame-main-loop.html

--
   :: Simon Wittber
   :: http://www.linkedin.com/in/simonwittber
   :: phone: +61.4.0135.0685
   :: jabber/msn: [EMAIL PROTECTED]


Re: [pygame] time progression independent of game ticks

2007-07-20 Thread Laura Creighton
The first time I did something like that I made a fish class which
did things like get-hungry.  Each fish stored its time of creation
and time of last feeding, mating, egg-laying etc.  Then I kept doing:


 for every fish:
   check the time of day, and update the fishes' state
   based on the time elapsed

This worked fine for a few fish.  But it did not scale.  When I had
10s of thousands of fish, I couldn't get through the whole list of
fish before too much time had passsed.  My fish were carrying too
much state around with them as well.

So I changed the design to make my fish schedule 'at this time
something interesting will happen to me' events into a queue which
was sorted by time.  Then, for every bit of time, I only had to see
if it was later than or equal to the first item in the queue, and
pop things off the queue until the first item on it was 'later than
now'.

Just in case you run into the same problem that I had.

Laura


RE: [pygame] time progression independent of game ticks

2007-07-20 Thread Chris Ashurst
Have you considered using time deltas?

Each fish instance could be initialised a timestamp of its creation, and
each iteration of the main loop you could get a timestamp of *now* and pass
it to each fish (or get each fish to get its own *now* for comparison),
which could then use Python's builtin timedelta class to work out how much
real time has passed, rather than how much game time has passed in game
ticks.

So if an instance of fish was born on 4:15pm in-game then at 4:30pm, your
fish instance will roll out the birthday cake.

I realise this may seem like more overhead, since pygame already has a clock
class, but for me, I rely on the clock class to provide a nice and friendly
way of adjusting framerate, rather than a definitive timepiece for my game.

Of course, I could just be spouting bollocks.



~Chris

-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Behalf Of Daniel Nixon
Sent: Friday, July 20, 2007 00:20
To: pygame-users@seul.org
Subject: [pygame] time progression independent of game ticks


Hi list,

I'm working on a game in which the player looks after a fishtank full
of fish. Each fish ages, gestates while pregnant, grows hungrier, etc.
For arguments sake lets say 15 minutes = 1 fish year. I want this
passage of time to be independent of frame rate and iterations through
the main game loop (or do I?).

What is the best way to go about such a thing? Use MVC and run the
model in its own thread? If that is the case what is the best way to
keep track of the passage of actual time within the model?

Thanks for reading.

-- 
Regards
Daniel Nixon




CONFIDENTIAL NOTICE: This email including any attachments, contains 
confidential information belonging to the sender. It may also be 
privileged or otherwise protected by work product immunity or other 
legal rules. This information is intended only for the use of the 
individual or entity named above.  If you are not the intended 
recipient, you are hereby notified that any disclosure, copying, 
distribution or the taking of any action in reliance on the contents 
of this emailed information is strictly prohibited.  If you have 
received this email in error, please immediately notify us by 
reply email of the error and then delete this email immediately.


Re: [pygame] time progression independent of game ticks

2007-07-20 Thread Dave LeCompte (really)
Simon Wittber [EMAIL PROTECTED]
 On 7/20/07, Daniel Nixon [EMAIL PROTECTED] wrote:
 What is the best way to go about such a thing? Use MVC and run the
 model in its own thread? If that is the case what is the best way to
 keep track of the passage of actual time within the model?

 This may or may not help:

 http://entitycrisis.blogspot.com/2007/07/general-pygame-main-loop.html

In that post you say the benefits of a fixed sim tick step are not
immediately apparent, and yet the benefits to network game synchronization
is obvious.

Could you go into more detail? I don't see why fixed sim ticks are any
better than variable sim ticks for networked games.


-Dave LeCompte


Re: [pygame] time progression independent of game ticks

2007-07-20 Thread Patrick Mullen

Yeah, a time queue is the way to go, don't bother with threads.  On each
update, you can get the current time (pygame.time, or pygame.clock), and
pass that into your time queue.  The time queue, will look something like
this:

[(5.0,eat,fish1),(6.5,eat,fish2)]

At each iteration, you continue to pop() the list, calling each function
(eat) with the argument (fish1, fish2), until the item on the list has a
time that is greater than the current time.  If you spread out your
scheduling, so there aren't too many fish doing the same thing at the exact
same time, this will scale really well and be a good way to handle timed
events.

As for tracking time, I use pygame.time as well.  I've found pygame.clock to
be inaccurate in some cases, and of course it's not usable in situations
where you don't want to use pygame (server).

I store lasttime = pygame.time.time() at the start of the simulation, then
on each iteration I calculate dt = pygame.time.time()-lasttime;.  Then if I
have some sort of game timer (like your 15 minutes = 1 year) I add the
dt(real time difference) times a modifier (to get game time difference) to
the game time variable.


Re: [pygame] time progression independent of game ticks

2007-07-20 Thread Greg Ewing

Michael George wrote:
Having recently taught a data structures course I'm forced to point out 
that for some number of fish, inserting into the queue will become a 
bottleneck,


Actually, it's not the number of fish that determines when this
will become a bottleneck, but the typical number of events in
the queue at any given moment. This is not necessarily proportional
to the number of active entities in the simulation.

Another thing is that the event-queue approach might not help
so much for an *animated* simulation. If the fish are all swimming
around on the screen, you're going to have to process them all
every frame anyway to update their positions.

But if only a small proportion of the fish are visible at a time,
and you can avoid having to simulate the motion of off-screen
fish in a detailed way, it will probably help, as long as you have
a way of quickly finding all the visible fish.

--
Greg


[pygame] time progression independent of game ticks

2007-07-19 Thread Daniel Nixon

Hi list,

I'm working on a game in which the player looks after a fishtank full
of fish. Each fish ages, gestates while pregnant, grows hungrier, etc.
For arguments sake lets say 15 minutes = 1 fish year. I want this
passage of time to be independent of frame rate and iterations through
the main game loop (or do I?).

What is the best way to go about such a thing? Use MVC and run the
model in its own thread? If that is the case what is the best way to
keep track of the passage of actual time within the model?

Thanks for reading.

--
Regards
Daniel Nixon


Re: [pygame] time progression independent of game ticks

2007-07-19 Thread Ian Mallett

You could try: http://www.pygame.org/docs/ref/time.html#pygame.time.Clock;
with Clock.tick(framerate) which would normalize the speed of the program on
any computer.  Then you wouldn't have to deal with any of the annoying
stuff.  Of course this means that cutting edge computers would have no
faster a fps rate than their slower counterparts.
Ian

On 7/19/07, Daniel Nixon [EMAIL PROTECTED] wrote:


Hi list,

I'm working on a game in which the player looks after a fishtank full
of fish. Each fish ages, gestates while pregnant, grows hungrier, etc.
For arguments sake lets say 15 minutes = 1 fish year. I want this
passage of time to be independent of frame rate and iterations through
the main game loop (or do I?).

What is the best way to go about such a thing? Use MVC and run the
model in its own thread? If that is the case what is the best way to
keep track of the passage of actual time within the model?

Thanks for reading.

--
Regards
Daniel Nixon



Re: [pygame] time progression independent of game ticks

2007-07-19 Thread Dave LeCompte (really)
Ian Mallett [EMAIL PROTECTED] wrote:
 You could try:
 http://www.pygame.org/docs/ref/time.html#pygame.time.Clock;
 with Clock.tick(framerate) which would normalize the speed of the program
 on any computer.

I wouldn't go about it that way - tick(framerate) tries to achieve the
framerate, but if you're running on a slow machine and can only run at
10Hz, calling Clock.tick(20) won't make it catch up.

That's even what the documentation says:

By calling Clock.tick(40) once per frame, the program will never run at
more than 40 frames per second.

Also, read on:

Note that this function uses SDL_Delay function which is not accurate on
every platform

A few milliseconds every frame, over 15 minutes, who knows how far out of
sync you'll end up?


 On 7/19/07, Daniel Nixon [EMAIL PROTECTED] wrote:

 Hi list,

 I'm working on a game in which the player looks after a fishtank full
 of fish. Each fish ages, gestates while pregnant, grows hungrier, etc.
 For arguments sake lets say 15 minutes = 1 fish year. I want this
 passage of time to be independent of frame rate and iterations through
 the main game loop (or do I?).

That plan sounds fine to me.

The way I do this sort of thing is to create a clock (as suggested by Ian)
and read the amount of time each time through the loop takes, and pass
that duration down into your simulation code:

theClock=pygame.time.Clock()

while (gameIsPlaying):
  frameTime=theClock.tick()

  processInput()
  doSim(frameTime)
  renderFrame()


Inside your doSim function, update the game logic based on frameTime going
by.

It might look a little like this:

FISH_DAYS_PER_MILLISECOND=0.0004
fishDays=0

def doSim(milliseconds):
  fishDays += milliseconds*FISH_DAYS_PER_MILLISECOND


And, you should find that after about 15 minutes of the player's time, the
fishDays value has climbed up to about 365 days.

I also usually have ways to suspend the sim, so that if the user leaves
the window, or brings up a pause menu, or whatever, I no longer call the
doSim function, which means the game clock isn't counting up.


If you want to combine this with Ian's suggestion, and add a frame rate
hint to the tick() call, you can, but even if you don't, you should be
able to get some good results.


-Dave LeCompte



Re: [pygame] time progression independent of game ticks

2007-07-19 Thread Ian Mallett

OK, I agree, it is probably not the most accurate way to do it, I'm assuming
that the problem is that the game won't run basically the same speed and
cumulative errors aren't relevant (ex: the speed the fish swims won't be
exactly the same but close enough).
Ian


Re: [pygame] time progression independent of game ticks

2007-07-19 Thread Dave LeCompte (really)
Daniel Nixon [EMAIL PROTECTED] wrote:
 Thanks Ian, Dave. Passing down the milliseconds sounds like the way to
 go. Thanks for the great advice. :)

Actually, let me refine my suggestion.

Back a month or more ago, I kicked off the whole a CPU is not a saw
thread with a discussion very similar to this, and what I would suggest
based on the opinions voiced at that time would be to make sure that you
leave a few cycles each frame for the OS.

If you're reasonably confident that you can pick a frame rate that the
slowest machines can keep up with, and then some, all you'd have to do is
pass in the argument to the tick() call:

TARGET_FRAME_RATE=25.0

while(gamePlaying):
  #[see earlier post]
  myClock.tick(TARGET_FRAME_RATE)


If you want to be extra sure to give up a few cycles to the OS, you can
add in an explicit delay:

TARGET_FRAME_RATE=25.0
WAIT_TIME=5 # number of milliseconds per frame to yield to other processes

while(gamePlaying):
  #[see earlier post]
  myClock.tick(TARGET_FRAME_RATE)
  pygame.time.wait(WAIT_TIME)


tune these numbers to where you feel comfortable with them.

I feel bad plugging my game over and over again, but if you look at the
0.9 version of the code, it wasn't yielding any time to the OS, and
sometimes things felt a little uneven. 0.91 and 0.92 are more aggressive
about using more CPU-efficient approaches, and I decided to use a 60fps
target. The result was much smoother performance.

0.9:  http://www.pygame.org/projects/23/415/?release_id=698
0.92: http://www.pygame.org/projects/23/415/?release_id=767

-Dave LeCompte


Re: [pygame] time progression independent of game ticks

2007-07-19 Thread Daniel Nixon

I've been using something like myClock.tick(60), but that's for no
other reason than 60 seems to be popular in most of the examples I've
read. I doubt my game will require such a high frame rate.

Aiming for 60fps seems to cause the game to take an entire core for
itself, but using your wait time brought that down to about 10% of one
core.

What advantage does calling pygame.time.wait() have over simply
lowering the frame rate passed to .tick()?


On 7/20/07, Dave LeCompte (really) [EMAIL PROTECTED] wrote:

Daniel Nixon [EMAIL PROTECTED] wrote:
 Thanks Ian, Dave. Passing down the milliseconds sounds like the way to
 go. Thanks for the great advice. :)

Actually, let me refine my suggestion.

Back a month or more ago, I kicked off the whole a CPU is not a saw
thread with a discussion very similar to this, and what I would suggest
based on the opinions voiced at that time would be to make sure that you
leave a few cycles each frame for the OS.

If you're reasonably confident that you can pick a frame rate that the
slowest machines can keep up with, and then some, all you'd have to do is
pass in the argument to the tick() call:

TARGET_FRAME_RATE=25.0

while(gamePlaying):
  #[see earlier post]
  myClock.tick(TARGET_FRAME_RATE)


If you want to be extra sure to give up a few cycles to the OS, you can
add in an explicit delay:

TARGET_FRAME_RATE=25.0
WAIT_TIME=5 # number of milliseconds per frame to yield to other processes

while(gamePlaying):
  #[see earlier post]
  myClock.tick(TARGET_FRAME_RATE)
  pygame.time.wait(WAIT_TIME)


tune these numbers to where you feel comfortable with them.

I feel bad plugging my game over and over again, but if you look at the
0.9 version of the code, it wasn't yielding any time to the OS, and
sometimes things felt a little uneven. 0.91 and 0.92 are more aggressive
about using more CPU-efficient approaches, and I decided to use a 60fps
target. The result was much smoother performance.

0.9:  http://www.pygame.org/projects/23/415/?release_id=698
0.92: http://www.pygame.org/projects/23/415/?release_id=767

-Dave LeCompte




--
Regards
Daniel Nixon

ABN: 62 535 877 916
phone: 04 0109 8560
email: [EMAIL PROTECTED]