A 'standard' FPS?

BlitzPlus Forums/BlitzPlus Programming/A 'standard' FPS?

I'm working on two games right now, both have fairly low FPS rates.

The one is getting a steady 30 FPS, which is a standard according to Wikipedia, and although I would like it to go a bit faster (for particle effects and such) could I be happy with 30?

The other is coming in at 4-5 no my Win98 and 14-15 on my modern machine. The game runs great on both machines, so I'm thinking cap the FPS at 15, and anything slower will be fine as well (my Win98 computer is about the slowest it gets anyway), but this isn't even close to the standard 30-60.

Wikipedia also said that there have been games that ran on 6 FPS and were quality games.

I guess my question is, even if the game runs fine at 15 or fewer FPS should I strive for optimization?

I'm curious, can you send the wikipedia link where it says 30? I thought most games run at 60fps by now but it's not really something I have followed closely so I have no idea. Maybe it depends on the genre too... but lower than 30 fps? Is it a puzzle game or a text adventure? :)

I kind of worry about this kind of thing in the back of mind, in the sense that the rapid advancement of PC hardware outpaces our abilities to harness it and take advantage of it (and we get away with writing inefficient code in some basic ways?).

http://en.wikipedia.org/wiki/Frame_rate
(under the Video Games section)

Halo 3 runs at thirty, but Call of Duty 4 runs sixty.

GTA: San Andreas runs only 25.

And the game that runs six is an early FPS.

The most you can really get away with is 20 (and only with animations). Lower than that and the eye can start to see the glitches.

>Lower than that and the eye can start to see the glitches.

Are you talking about refresh rates or graphical oddities? I'm doing text based stuff, and 15 and 6 are both factors of 60, which is the refresh rate for most monitors if I'm not mistaken? Or does that even matter?

Movies (as in DVDs & theater films) run at 24 FPS. It's pretty much the lowest you can go for smooth-seeming animation. 30 FPS is generally alright, and will seem smooth. HOWEVER, if you watch a game running at 30 FPS for a while, then switch to 60 FPS, there will be a noticeable difference, and 30 FPS suddenly won't seem so smooth. I say go for 60 FPS, but if you stick to 30 FPS and don't go over at any time, then that should work fine.

Film only 'gets away' with 24 fps because it has so much motion blur filling in the movement for you. Computer games don't usually have this luxury. 60 is a good rate to aim for if you really want smoothness, but 30 or even lower can be fine depending on the [type of] game. Traditional cel animation used '2s' whereby you only changed the image every other frame so that it ran at 12 fps, but again you had the luxury of implying movement using lines and puffs of smoke etc.

Something to bear in mind is that the term 'frame rate' doesn't necessarily refer to the graphics frame rate. The term may be used to refer to the main game logic update rate, or to the update rate of a variety of sub-systems in your game.

Most good game timing regulation systems will allow the graphics frame rate to run as fast as the refresh rate of the monitor and the capabilities of the graphics card will allow. The frame rate of the game logic generally needs to be firmly regulated, however, so that changes occur at a predictable rate.

Here's a simple text tile world:

AppTitle "Text Tile World"
Graphics 800,600,32,2

;--------------------------------
; INITIALIZATION
;--------------------------------
Global px=115,py=0,hp=100
Global frametimer=CreateTimer(15)
Global starttime=MilliSecs(),elapsedtime,fpscounter,curfps

Global levelimg=CreateImage(600,400,1)

Dim map$(40,20)
Dim des$(5)

Type enemy
	Field startx,starty,x,y,u,d,l,r,dir
End Type

;--------------------------------
; MAIN LOOP
;--------------------------------

updatelevel()

While Not KeyHit(1)
	WaitTimer(frametimer)
	Text 620,20,FPS()
	Color 0,100,0
	displaylevel()
	updateplayer()
	Flip
	Cls
Wend 

;--------------------------------
; FUNCTIONS 
;--------------------------------

Function FPS()
	elapsedtime=MilliSecs()-starttime
	If elapsedtime>=1000
		curfps=fpscounter
		fpscounter=0
		starttime=MilliSecs()
	Else
		fpscounter=fpscounter+1
	EndIf
	Return curfps
End Function 
			
		
Function updateplayer()
	;displays player and updates movement/checks ground
	Text px,py,"O",True,True
	opx=px
	opy=py
	If KeyDown(205)
		If px+10<16*40
			px=px+10
		Else
			px=16*40
		EndIf 
	EndIf
	If KeyDown(203)
		If px-10>0
			px=px-10
		Else
			px=0
		EndIf
	EndIf
	If KeyDown(208)
		If py+10<16*20
			py=py+10
		Else
			py=16*20
		EndIf
	EndIf
	If KeyDown(200)
		If py-10>0
			py=py-10
		Else
			py=0
		EndIf
	EndIf
	
	mx=px Shr 4
	my=py Shr 4
	
	on$=map$(mx,my)
	If on$="#"
		px=opx
		py=opy
	EndIf
	If on$="_"
		hp=0
	EndIf
	If on$="^"
		hp=hp-1
	EndIf  
	
	Text 0,450,map$(mx,my)
	
End Function 


Function displaylevel()
	;displays the level and other crucial information
	DrawImage levelimg,0,0
	
	For x=0 To 4
		Text 0,420+x*20,des$(x)
	Next
	Text 610,0,"HP: "+hp
	updateenemy()
End Function


Function updatelevel()
	;on level change, updates/resets all aspects of level
	For m.enemy=Each enemy
		Delete m
	Next
	Restore leveldata
	For x=0 To 4
		Read d$
		des$(x)=d$
	Next
	For y=0 To 19
		For x=0 To 39
			Read num
			If num=1
				map$(x,y)="#" ;wall
			ElseIf num=0
				map$(x,y)=" " ;floor
			ElseIf num=2
				map$(x,y)="_" ;hole
			ElseIf num=3
				map$(x,y)="^" ;spikes
			EndIf  
		Next
	Next
	Read ennum
	For z=1 To ennum
		Read x
		Read y
		Read u
		Read d
		Read l
		Read r
		makenemy(x,y,u,d,l,r)
	Next
	
	SetBuffer ImageBuffer(levelimg) 
	Color 0,100,0
	For y=0 To 19
		For x=0 To 39
			Text x*16,y*16,map$(x,y)
		Next
	Next
	
	SetBuffer BackBuffer()
End Function


Function makenemy(x,y,u,d,l,r)
	;creates a new enemy instance from data strip
	m.enemy=New enemy
	m\startx=x
	m\starty=y
	m\x=x
	m\y=y
	m\u=u
	m\d=d
	m\l=l
	m\r=r
	m\dir=1
End Function


Function updateenemy()
	;controls enemy movement and display
	For m.enemy=Each enemy
		If m\dir>3
			m\dir=0
		EndIf 
		Select m\dir
			Case 1
				nextstep=m\x+10
				on$=map$(nextstep Shr 4,m\y Shr 4)
				If on$="#" Or nextstep>m\startx+m\r
					m\dir=m\dir+1
				Else
					m\x=nextstep
				EndIf
			Case 2
				nextstep=m\y+10
				on$=map$(m\x Shr 4,nextstep Shr 4)
				If on$="#" Or nextstep>m\starty+m\d
					m\dir=m\dir+1
				Else
					m\y=nextstep
				EndIf
			Case 3
				nextstep=m\x-10
				on$=map$(nextstep Shr 4,m\y Shr 4)
				If on$="#" Or nextstep<m\startx-m\l
					m\dir=m\dir+1
				Else
					m\x=nextstep
				EndIf 
			Case 0
				nextstep=m\y-10
				on$=map$(m\x Shr 4,nextstep Shr 4)
				If on$="#" Or nextstep<m\starty-m\u
					m\dir=m\dir+1
				Else
					m\y=nextstep
				EndIf
		End Select 
		
		Text m\x,m\y,"?"
	Next
	
End Function 
		
;-----------------------------------------------------
; DATA
;-----------------------------------------------------

.leveldata ;5 lines of text, 40x20 num block, enemy line
Data "YOU BEGIN YOUR JOURNEY IN THE DARK DUNGEON, THERE ARE TWO EXITS.  IT IS"
Data "QUIET AND DANK.  THERE IS A HOLE IN THE FLOOR, AND IT IS VERY DEEP..."
Data "f"
Data "e"
Data "g"
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,3,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 0,0,0,1,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,1,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,1,2,2,2,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Data 0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Data 0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0
Data 0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
Data 1 ;num enemys
Data 200,200,50,50,0,0 ; enemy attributes (x,y,u,d,l,r)


I only get 15 FPS. What optimization techniques should I use to improve it? I already used binary shifts instead of division, but it didn't help much.

After reading Bill Stanbrook's post again I've decided that since I'm not seeing flicker or graphical oddities, I'm most likely looking at the logic update. If the game plays fine on a decade old machine as well as modern computers, I'd say compatibility is just fine.

Now the other game running at 30 FPS I'd like to bump up to 60, but that's another day.

EDIT: Wow stupid me, just realized that I had capped the FPS to only 15 before I transferred it to my modern computer, that explains why its only running 15 FPS :) Regardless I'm still going to leave it at that, because I like how it runs at that speed.

Ok well I found the issue, solving both FPS problems for both my games on both machines as well (although I still have the tile game running at 15 by preference).

Windowed mode cuts the FPS in half on both my machines. I got my tile game running up to 30 on my ancient machine, and my other game at a solid 60 on my modern computer. Also, setting the bit depth to 32 may have been causing issues too.

Just in case anyone cared ;)