returing or printing current Frametime in realtime

Hey everyone! i am currently looking for a way to collect the current Frametime or FPS and assign it as a value to a string or float variable! does anyone know if this is possible and if so who i would go about getting something like that to work.

The reason i am asking is because my game is suffering from memory leaking or so i think, and im looking for a way to detect when my framerate drops below 30fps, and if so, id like to speed the movement of my characters up to by a factor of 2.

Im sure it probably best to just find the memory leak and fix it but im not sure if its with my scripts causing this slowdown or if its a low level C issue within BGE itself. However, if this works, it will prove to be a nice temporary solution to my game slowing down so drastically! Any help would be much appreciated!

Tony!!! :slight_smile:

oh ps im using blender 2.69 on a windows vista machine if this helps any! Thanks yall!!! :slight_smile:

getAverageFrameRate should be what you’re looking for.

Memory leaks usually eat memory rather than processing time. It can result in delays when the OS starts swapping memory which is by its nature slow.

I’m not sure if it is really a good idea to speed up the character by 2. It would be more sufficient to calculate the expected distance in conjunction to the estimated time (e.g. you estimate it is equal to the length of the previous frame). This is what the physics is doing and this is what the animation is doing. But they do not check the real duration they check the target duration (1s/60=20ms).

1/60 = 16.67 :stuck_out_tongue:


What you are looking for is called logic tics. These are essentially timers used so that no matter the frame buffer time, the logic will perform at, what looks like, the same speed. Blender doesn’t do this automatically: try disable “use framerate”, which is just a 60fps limit, and you will see the game run substantially quicker, not just smoother – you can test this with a timer. Time goes quicker at higher frame rates (it shouldn’t). To fix this, you can set the logic ticRate to the frame rate

logic.setLogicTicRate(logic.getAverageFrameRate())

Then you need to make it so that everything in the game works according to a timer delay, so that pulses aren’t triggered every frame, but rather after certain periods of time. It’s not a simple task. There might be a better solution

you are right, my brain calculator must be drunk :wink: (20ms would be 1s/50).

Oh, hey. I thought this wouldn’t work because the returned average frame rate would basically go from less than the target amount to exactly that amount, but it does work. I suppose this opens up a delta-time-based approach to timing in the BGE. Very nice!

EDIT: I got Blender to freeze doing this because on a fresh clean Blender start, getAverageFramerate() can return 0.0, which will literally stop the game and keep it from continuing.

logic.setLogicTicRate(max(1.0, logic.getAverageFrameRate())) should work.

Hey hey Thanks so much for all of your help yall! i was able to lower the framerate to 30fps and the game runs smoother! a lot smoother and doesn’t slowdown after a few minutes! i can still hear my computer fan rev up but the game moves close to the same initial speed! Thanks so much for yall’s help!!! :slight_smile:

Bumping this to say that setting the logic tic rate like this doesn’t work if the initial framerate of the game drops (i.e. if you use a for loop to set some values). You could try doing it only after it rises again or a certain amount of time, but that feels awkward, and it may not work if the framerate drops again for any reason. The search for a reliable method of unhinging the framerate continues…

I always write scripts in a way that they work off of a change in time (dt). A simple example could be character movment:


def move_character(cont):
    # Assume last_time is set and stored somewhere where it is not reset every frame
    dt = time.time() - last_time
    last_time = time.time()
    
    dir = calculateDirectionPlayerShouldGo() # A vector
    dir.normalized()
    movePlayerBy(dir * speed * dt)

This doesn’t help if you’re dependent on logic bricks (e.g., the motion actuator), but it works well enough for a mostly Python workflow, which is what I do. Also, make sure “Restrict Animation Updates” is checked, since this will decouple animation framerates from the render framerates.

Yeah you’re right. I tried making a hectic scene of a couple thousand physics objects with culling off to get the framerate to drop below 1. It stops working.

The problem with this is that inputs can still be received at a faster pulse than normal according to the framerate, and time goes faster according to the framerate too.

Also, the physics still runs way too quick.

^There’s a video of how much not controlling the amount of ticks can really affect a game mechanic.

Here’s my solution:
tic.py


from bge import logic
scene = logic.getCurrentScene()
cont = logic.getCurrentController()
own = cont.owner


tick = logic.getAverageFrameRate()
if tick < 1:
    tick = 1
    
logic.setLogicTicRate(tick)


if own["timer"] > 1/60:
    own["timer"] = 0
    logic.globalDict["tick"] = True
    
else:
    logic.globalDict["tick"] = False
    
logic.globalDict["timer"] = own["timer"]

Run this python controller preferably with it marked to run before other controllers.
EDIT: using min() with logic.getAverageFrameRate() doesn’t seem to work.

Example of usage to check for tick:
adder.py


from bge import logic, events
scene = logic.getCurrentScene()
cont = logic.getCurrentController()
own = cont.owner


key = logic.keyboard.events
space = key[events.SPACEKEY]


if space and logic.globalDict["tick"] == True:
    scene.addObject("Cube", own, 0)

.blend example: https://www.dropbox.com/s/m4euedsr7yd182d/tick.blend (I like to use dropbox so when I update it I don’t have to re-upload with my terrible internet)