Haxe inactive browser tab stops completly

230 views Asked by At

I'm developing a browser based game with haxe. As long as I have the browser tab as my active tab, everything works just as intended and smoothly, but as soon as i switch the tab (regardless if i'm using chrome or firefox) it stops working completly and doesn't send any heartbeat at all to my server.

I'm aware, that inactive tabs are slowed down in perfomance and i'm also aware, that inactive tabs are not allowed to load ressources. (My game does not do that).

I want my game to continue while it is inactive and more importantly, I want it to send a heartbeat to the server.

Is there any way I can enforce this?

I'm using Kha and Haxe, i tried the haxe native scheduler for the heartbeat and the kha scheduler, both of them don't work while beeing inactive.

2

There are 2 answers

0
Rafael Kress On BEST ANSWER

Okay, I found the solution. The SystemImpl from kha is requesting the requestAnimationFrame and checks if it is null every timestamp.

var window: Dynamic = Browser.window;    
if (requestAnimationFrame == null) window.setTimeout(animate, 1000.0 / 60.0);
else requestAnimationFrame(animate);

During inactive tab, the requestAnimationFrame isn't null, but doesn't call the animate function. I've added a static bool value isFocused, which is changed everytime the browser closes or opens this window.

To fix this i temporarely modified this small snippet into:

var window = Browser.window;
window.onfocus = function(){isFocused = true;}
window.onblur = function()
{
    window.setTimeout(animate, 1000.0 / 60.0); 
    isFocused = false; 
}           
if (requestAnimationFrame == null || !isFocused) window.setTimeout(animate, 1000.0 / 60.0);
else requestAnimationFrame(animate);

This way I'm checking if the current window is the active window and use the much smoother requestAnimationFrame and if not I'm using setTimeout. The callback methods are setting the is focused value. The Blur Callback value also makes sure, that the animate function is always called while blurred.

I'm going to present this solution in the upcoming 1 or 2 weeks to rob, maybe he considers the implementation

3
Mark Knol On

You already found it, but I think window.Top should be window.top.

Such thing would give an error if you would not have used :Dynamic. Window is a typed object and you get nice errors, which is a one of the good things of a a strict typed language. requestAnimationFrame is a global function on window, so this snippet works without a dynamic annotation.

var window = Browser.window;
if (window.requestAnimationFrame == null || window.top != window.self) window.setTimeout(animate, 1000.0 / 60.0);
else window.requestAnimationFrame(animate);

You also mention that checking window.top != window.self checks if the window is active. This is not true, it checks if the window runs in a (i)frame. Also, you only use this check once (and only when requestAnimationFrame isnt supported, so if it isn't true the first time, you will never get updates.

You could use the !Browser.document.hidden property, which is supported very well https://caniuse.com/#search=hidden

var window = Browser.window;
if (window.requestAnimationFrame == null) window.setTimeout(animate, 1000.0 / 60.0);
else window.requestAnimationFrame(animate);

I would suggest to use this snippet. And use if (Browser.document.hidden) return in the animate function