Frame rate for the game? aka graphics rendering

Started by Karsten75, September 12, 2010, 11:52:03 AM

Previous topic - Next topic

Karsten75

In another thread someone mentions that the game runs at 30fps?  Is that correct?  In some of the graphics intensive games, frame rate achieved is dependent on the hardware, so I'm wondering how CW does this?

30fps sounds like a bit much for such a simple game. No offense intended, but I'm sure you understand what I mean.

Echo51

Im basing 30fps on what i read in the flash to exe post virgil put on the blog, he said one of them only got him 21-22fps while he aimed for 30fps.

30 fps also seems a typical for most games,
Join the chat! :D
- The only echo present here...

UpperKEES

My CW1 maps: downloads - overview
My CW2 maps: downloads - overview

knucracker

ChopRaider is set to run at 24 fps, CW1 at 36 fps, and CW2 at 30 fps.
Why these numbers?

Well, back in the flash 9 days "multiples of 12" were the sweet spots for getting the most consistent frame rate across different browsers.  So 24 is a good frame rate for a game set to run in browsers that only have flash 9.  This is also the default frame rate for flex based applications.

But, 24 is a little on the "choppy" side so 36 was what I used in CW1.  I planned on releasing a flash version of the game and I still wanted to support flash 9.

Now everybody has flash 10.x... and the multiple of 12 rule no longer applies.  If you set a trivial flash app to 30 fps, you will actually get 30 fps in both AIR and the browsers.   So CW2 is set to 30 fps.  This offers a fluid frame rate while reducing the computational load a bit (which I immediately put back to use for the games algorithms).



Echo51

Ah :P i had that multiples of 12 rule in my backhead, but assumed you would use 30fps as its the universal minimum framerate.

i stand corrected Karsten :P
Join the chat! :D
- The only echo present here...

UpperKEES

#5
Quote from: virgilw on September 12, 2010, 12:21:44 PM
CW2 is set to 30 fps.  This offers a fluid frame rate while reducing the computational load a bit (which I immediately put back to use for the games algorithms).

Quote from: virgilw on January 25, 2010, 05:53:14 PM
CW is a frame-locked game.  This is on purpose...  This means that the game loop does things like calculate creeper expansion, packet routing, and rendering.  Now not everything happens on every loop of the game.  But as the game slows down, _everything_ slows down.  This is a wise choice for a game like CW where performance can vary but you want fair treatment across different runs of the game.  Other game engine choices might be to measure the time delta between each game loop and adjust game physics based on that delta T.  This makes things run at the same wall time across fast and slow computers.  So for CW every game loop updates a counter.  Packets get produced after so many loops have passed (that's a simplification, but basically what goes on).

Quote from: virgilw on February 15, 2010, 03:10:01 PM
CW is a frame-locked game.  THis means that everything slows down if the computer it is running on can't keep up.  So everything just gets slower (the creeper moves slower, guns move slower, packets move slower, even the clock ticks slower).  It is done this way to keep scoring 'fair' across different platforms.

I've always wondered how this frame locking exactly works. A few questions:

1. Does the game measure whether the intended amount of FPS can be displayed with the current hardware?
2. Do you assign a duration of 27.8 ms (1/36 sec) to each frame to eliminate the use of the real time?
3. You say not everything gets calculated each loop of the game (= frame?), so during one frame more calculations may be done than during another frame. How do you compensate for that?
My CW1 maps: downloads - overview
My CW2 maps: downloads - overview

knucracker

In flash, you set a FPS that you want rendering to occur at.  You can also implement an "enterFrame" listener like this:
addEventListener(Event.ENTER_FRAME, onEnterFrame);

This means that the function "onEnterFrame" will get called for each 'frame' of the flash player.  Ideally, if you set the FPS to 30 this function will get called 30 times per second.  But of course it isn't that simple.

Inside that 'onEnterFrame' function you can do anything you want (the entire game logic for instance).  If you do a whole bunch then you will take more than 1/30th of a second.  The result is that the next call to onEnterFrame will come as quickly as possible, it just won't come 1/30th of a second later.... so your effective frame rate will drop.

Now this general way of doing things isn't really that tied to flash.  If you were doing an XNA game, you'd be working off a 60fps system (probably).  In any of these cases there at two general types of games you can write;  frame locked and time locked.

In a frame locked game, you do your logic per frame and assume a given frame rate.  So if you want a ball to take 10 seconds to move across the screen you assume 30fps and move the ball accordingly per frame.  In this kind of game, the ball will take longer than 10 seconds if the machine running the game can't maintain 30fps.  A time locked game, won't do this.  It instead will move the ball differing amounts depending on how much actual time has elapsed.  So if the game runs on a slow machine the ball will still move across the screen in 10 real seconds... it may just take a few bigger jumps to do it.

Which way you write a game depends on the goal of the game (and a little about the platform).  For CW, the game is frame locked.  This means that when the game runs on a really slow machine, everything slows down.  This is desirable for a game like CW.  It might not be desirable for a first person shooter.... and would certainly not be desirable for some multi player games.

Anyway, I digress...
Since CW is frame locked, I  do most of the game logic per frame.... just not every frame.  For instance, full creeper updates come only every 8 frames.  Some units check things only every 36 frames.  I literally have a frame counter and may do something like:
if (frameCount % 8 == 0) {
   updateCreeper();
}

Now in reality things are a even a bit more complex than this (in some cases).  Instead of one big creeper update once every 8 frames, I actually do 1/8th of the creeper update each frame.  In CW2, I split the load in half so that half of the creeper array gets updated every other frame.

Even with all of this, there will sometimes be frames that take too long to do their work.  When this happens there is a "jerk" in the game.  If it's just a little bit and happens every so often then no big deal.  A little hiccup that happens at a regular interval is more noticeable than one that happens at irregular intervals.  So, I sometimes mod the frameCount by a prime number (and use different prime numbers for different tasks) to help mix things up.

Lastly, flash takes a monster load of time to render the screen as well.  This can account for 75% of the total cpu load.  It all high depends on the number of transparent bitmaps, blah, blah, blah.  It also depends on if the user has scaled the game...
And it depends on how many cores a person has in their machine.  With more than one core the flash player has an opportunity to move the rendering to a different core(s) and free up event frame processing.  I believe this is why I see such a huge difference between single and dual core machines for flash performance. (And why I'm curious what people have:  http://knucklecracker.com/forums/index.php?topic=4696.0 )


Karsten75

This may explain little "freezes" I have noticed on the game on my laptop.

UpperKEES

#8
Thanks a lot! This really shows how much more interesting game development is compared to the development of many other systems, as you have to deal with so many more aspects.

So basically you increase the number of seconds by one to obtain the elapsed time when 36 frames have been processed? Is this also the reason you calculate the score from an integer time value and can't take the (non-existing) fractional part into account?

When a jerk/hiccup occurs, does the rendering of this frame gets skipped while the logic behind it is still executed?
My CW1 maps: downloads - overview
My CW2 maps: downloads - overview

knucracker

To calculate a framerate I see how long it takes for 36 frames to come.  Ideally, this would be 1 sec.  So when I'm dev'ing a game I'll have that little number on the screen all of the time.  In fact right this second I'm looking over on a second monitor where I have an AIR version of CW2 running.  It shows a little "30" right now (30 fps).  I'm running a test on a machine where I've turned off the second core and am toggling the intel speedstep in the bios (yes, it makes a difference to performance).  Basically, I take a moment every so often the check the performance on a slow machine.  Then I'll spend a few days optimizing algorithms (or removing /altering features).

Score wise, there is no frame reason for the way it is on CW1.  I basically just focused on "score" not time.  I had web site score integration in mind.  Time in CW2 (for scoring purposes) is calculated by the number of elapsed frames since mission start.  So it's a pretty accurate thing.  Scores reduce this accuracy by mashing a very accurate frame count into an exponentially decaying range of 10000 to 0.

As for hiccups and frame rendering.  The answer is sometimes a yes.  Flash won't always redraw the screen and can skip some renders.  I don't really have total control over this in flash (unlike some other environments).

Karsten75

Let me ask you a different question - suppose you have a really simple game, but you set the frame rate very low. So all processing happens in only a fraction of the time allocated to that frame. Does the game show some signs of "jerkiness" as it moves objects around?

UpperKEES

#11
The reason I asked this question about the completion time was because the scores always jump by 3 points (short game) or 2 points (medium game). Fractions of the completion time seem not to be taken into account (while this is possible with a framecounter not modulo 36). I notice this often lately when I play a quick Chronom map (< 2 minutes) and the time counter increases by one second just at the moment the rift opens (costing me 3 valuable points).

Regarding the skipped frames: so the logic is always executed and the OnEnterFrame is always called, even when the frame rendering is skipped? I think I don't understand this part completely:

Quote from: virgilw on September 12, 2010, 02:23:24 PM
A little hiccup that happens at a regular interval is more noticeable than one that happens at irregular intervals.  So, I sometimes mod the frameCount by a prime number (and use different prime numbers for different tasks) to help mix things up.
My CW1 maps: downloads - overview
My CW2 maps: downloads - overview

knucracker

Quote from: Karsten75 on September 12, 2010, 03:37:43 PM
Let me ask you a different question - suppose you have a really simple game, but you set the frame rate very low. So all processing happens in only a fraction of the time allocated to that frame. Does the game show some signs of "jerkiness" as it moves objects around?

If you set the frame rate to 1 fps, your enterFrame method will get called pretty much once per second.  You game logic will move you ball say 2 pixels.  The system will twiddle it's thumbs, then call your enterFrame method again after the next second is up.  Then you will move your ball again.

In this case the ball isn't jerky, it's just moving really slow.  To compensate for such a slow moving ball, you might decide to move the ball 20 pixels per update.  Now the ball makes it across the screen quicker, but it jumps 20 pixels at a time doing it.  In this scenario you might characterize the movement as "jerky", but it will always be pretty uniform at it. 

knucracker

Quote from: UpperKEES on September 12, 2010, 03:38:31 PM
The reason I asked this question about the completion time was because the scores always jump by 3 points (short game) or 2 points (medium game). Fractions of the completion time seem not to be taken into account (while this is possible with a framecounter not modulo 36). I notice this often lately when I play a quick Chronom map (< 2 minutes) and the time counter increases by one second just at the moment the rift opens (costing me 3 valuable points).

Regarding the skipped frames: so the logic is always executed and the OnEnterFrame is always called, even when the frame rendering is skipped? I think I don't understand this part completely:

Yes, the score is calculated off of "seconds" not frames.  So precision is lost there.  To get those extra points you have to shave off enough to keep the time from advancing once second more.

Rendering the display can be skipped from time to time and this is independent of when your enterFrame method is called.  For the most part, the rendering happens... but it can get skipped.  Think of it like another processor/thread.  The rendering isn't synchronously tied to the execution of you enterFrame calls.  So rendering could take a 100ms vacation while your enterFrame methods continued to get called.

Karsten75

Next question: Can I find the frame rate delivered on my system somewhere?