Speed

Game development specific discussions.
ITomi
Posts: 154
Joined: Jul 31, 2015 11:23
Location: Hungary

Speed

Post by ITomi »

Hello!

I would like make a safety solution that control the speed of my games, in order to run the game same speed both on slow and fast computers.
I invented this code for this, what clocks the fps:

Code: Select all

dim as integer fps,frame
dim as double starttime

fps=0
frame=0
starttime=timer
do
    cls
    if timer-starttime>1 then
        fps=frame
        starttime=timer
        frame=0
    else
        frame+=1
    end if
    print "ESC: exit, FPS: "& str(fps)
loop until inkey=Chr$(27)
It seems to be good for me, but what is your opinion, as a skilled FB programmer?
I think if I can get the fps, then e.g. I can move the game objects by pixel amount, in inverse ratio to fps, so for example bigger fps would result in smaller move on a fast computer and less fps would result in larger move on a slow computer. Or I can give the suitable value to Sleep command.
I don't know, are these good conceptions?
Pitto
Posts: 122
Joined: Nov 19, 2012 19:58

Re: Speed

Post by Pitto »

Hi ITomi,

see this useful article:
III. A digression in Framerate Independence aka "Delta-Time"
http://games.freebasic.net/BASICGaming/ ... #tutorial1
ITomi
Posts: 154
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: Speed

Post by ITomi »

Thanks, Pitto! That article and the demos there are truly helpful. I would like also be a real pro programmer like that guys, who publish their demos there.
Now I'm working on an FPS and a Millipede remake game. I hope, these will be faultless in every respect, included speed too.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Speed

Post by deltarho[1859] »

I am not into game development but was attracted to the thread's title.

The opening post's code is knocking seven bells out of my Intel i7 at 11%/12%.

I don't know if you, ITomi, can make any use of the following but the CPU 'hit' is down to 0%/1% by adding that 'Sleep 1'. I am using 'timeBeginPeriod' to ensure that Sleep operates at the milli-second level as opposed to the default of 15.625ms (64 Hz). The Declare is by dodicat. We don't need timeBeginPeriod's counterpart - the system restores on the application's closing.

Code: Select all

Declare Function settimer  Lib "winmm" Alias "timeBeginPeriod"(As Ulong=1) As Long

Dim As Integer fps,frame
Dim As Double starttime

SetTimer

fps=0
frame=0
starttime=Timer
Do
    Sleep 1
    If Timer-starttime>1 Then
        fps=frame
        frame=0
        starttime=Timer
    Else
        frame+=1
    End If
    Locate 1,1, 0
    Print "ESC: Exit, FPS: "& Str(fps)
Loop Until Inkey=Chr(27)
ITomi
Posts: 154
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: Speed

Post by ITomi »

Thank you, Deltarho[1859], for your attention and addition. That is an interesting phenomenon from Intel i7 CPU (I have an AMD A4-4000 CPU in my PC).
I tried your code and if it is really safe for all CPU types then I will use it. I didn't know that using of Sleep is so important in the codes.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Speed

Post by deltarho[1859] »

I should have mentioned that timeBeginPeriod is Windows only.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Speed

Post by badidea »

deltarho[1859] wrote:I should have mentioned that timeBeginPeriod is Windows only.
Sleep already seems to have ms accuracy on my linux laptop.

Code: Select all

var t1 = timer
sleep 1,1
print timer-t1
t1=timer
sleep 1,1
print timer-t1
Gives here:

Code: Select all

0.001074075698852539
0.001089096069335938
The 64 Hz disappeared with WinXp, Win7 uses 100Hz I think. (not 100% sure)

Edit: I was duckduckgoing this timer resolution thing, it is more complex than I thought.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Speed

Post by deltarho[1859] »

badidea wrote:Sleep already seems to have ms accuracy on my linux laptop.
Ah, well done Linux. Not enough to get me 'outa' Windows though. <laugh>
The 64 Hz disappeared with WinXp
Edit: I was duckduckgoing this timer resolution thing, it is more complex than I thought.
Just ask the host what it is using. I'm on Win10 64 bit Pro.

Code: Select all

Declare Function GetTimeValues Lib "Kernel32" Alias "GetSystemTimeAdjustment"(Byref As Long, Byref As Long, Byref As Long) As Long
Dim As Long lpTimeAdjustment, lpTimeIncrement, lpTimeAdjustmentDisabled
GetTimeValues( lpTimeAdjustment, lpTimeIncrement, lpTimeAdjustmentDisabled )
Print lpTimeAdjustment
Print lpTimeIncrement
Print lpTimeAdjustmentDisabled
Sleep
which gives me

Code: Select all

 156250
 156250
 1
So, 64 Hz.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Speed

Post by badidea »

deltarho[1859] wrote:
badidea wrote:Sleep already seems to have ms accuracy on my linux laptop.
Ah, well done Linux. Not enough to get me 'outa' Windows though. <laugh>
No, there are much better reasons to run away from Windows :-)
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Speed

Post by deltarho[1859] »

badidea wrote:No, there are much better reasons to run away from Windows :-)
Too late. My local funeral directors had a gravestone sale, including cutting, last summer so I jumped at the chance. Mine reads: "Here lies a Windows die hard"
ITomi
Posts: 154
Joined: Jul 31, 2015 11:23
Location: Hungary

Re: Speed

Post by ITomi »

deltarho[1859] wrote:I should have mentioned that timeBeginPeriod is Windows only.
Because of "Lib "winmm""? And what happening if I omit the SetTimer function and use only Sleep command?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Speed

Post by jj2007 »

deltarho[1859] wrote:So, 64 Hz.
I vaguely remember that some applications, notably Firefox, have the bad habit to set 1 ms resolution when playing videos on YouTube etc, and that's a system-wide setting, but I can't reproduce it now. Bad luck.
There is an excellent article by Arno Lentfer, Microsecond Resolution Time Services for Windows, in case you want to dig deeper.
deltarho[1859]
Posts: 4305
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Speed

Post by deltarho[1859] »

ITomi wrote:Because of "Lib "winmm""?
Yes: timeBeginPeriod function
And what happening if I omit the SetTimer function and use only Sleep command?
'Sleep n' only has a resolution of 15.625ms so Sleep n, where n<16, has no effect; 15.625ms is as good as it gets. The SetTimer function increases the resolution to 1ms by using a multimedia timer as opposed to the system clock.

Sleeping for 1ms stretches the 'bottleneck' caused by a tight loop.

On Windows 10 we can get a resolution of 0.5ms but not via timeBeginPeriod - that is another story.

Anyway, experiment.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Speed

Post by dodicat »

You should test your framerate offline.
Google chrome is another to make sleep 1 = 1 ms
Some computers are limited to about 60 fps offline (This one included)
This code gives me the requested 300 fps online, but about 60 fps offline.

Code: Select all

 

Function Regulate(Byval MyFps As long,Byref fps As long) As long
    Static As Double timervalue,_lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:fps=frames:frames=0
    Var sleeptime=_lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    _lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function


screen 18
dim as long fps,x=10,y=10,dx=1,dy=1
do
    x+=dx
    y+=dy
    if x<10 or x>630 then dx=-dx
    if y<10 or y>470 then dy=-dy
    screenlock
    cls
    draw string(100,100),"Framerate  " &fps
    circle(x,y),10
    screenunlock
    sleep regulate(300,fps)
    loop until len(inkey)
     
The moral is if you write a game make sure cheapskate computer owners can run it.
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Speed

Post by badidea »

deltarho[1859] wrote:Too late. My local funeral directors had a gravestone sale, including cutting, last summer so I jumped at the chance. Mine reads: "Here lies a Windows die hard"
In blue, with 'fatal error' and a sad smiley?
dodicat wrote:I vaguely remember that some applications, notably Firefox, have the bad habit to set 1 ms resolution when playing videos on YouTube etc, and that's a system-wide setting, but I can't reproduce it now. Bad luck.
I think the flash player does (or used to do) that.

Alternatively use screensync without sleep, this also seems nice on cpu?

Code: Select all

Function Regulate(Byval MyFps As long,Byref fps As long) As long
    Static As Double timervalue,_lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:fps=frames:frames=0
    Var sleeptime=_lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    _lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function


screen 18
dim as long fps,x=10,y=10,dx=1,dy=1
do
    x+=dx
    y+=dy
    if x<10 or x>630 then dx=-dx
    if y<10 or y>470 then dy=-dy
    screenlock
    cls
    draw string(100,100),"Framerate  " &fps
    circle(x,y),10
    screenunlock
    screensync 'NOTE: SCREENSYNC ADDED
    regulate(300,fps) 'NOTE: SLEEP REMOVED
    loop until len(inkey)     
More info in coderJeff's topic: What is good cross platform gameloop?
Post Reply