Jump to content

Keep RequestAnimationFrame running in the background?


WombatTurkey
 Share

Recommended Posts

Hey guys,

Kind of stuck here. 

I've read numerous topics about this and it seems like.. it just isn't available. Phaser has this property: http://phaser.io/docs/2.4.6/Phaser.Stage.html#disableVisibilityChange which works, but even if you do minimize the game or switch tabs (let's say you're using electron or nw/js) the game will pause because it's not active and RAF calls will not work.

There has to be away around this. Since my game is getting fairly large creeping up to triple digit's in lines of code and half of that for the gameserver.. when a client minimizes their window I cannot have the game essentially 'pause' if you will. Especially since my game is multiplayer and other player's can move around / mobs agro / etc / etc. It all needs to be updated while in the background.  (If a player alt-tabs or minimizes the window).

I made a topic in the Electron forums: https://discuss.atom.io/t/keep-the-browser-window-running-while-not-active/27242 to see if maybe their is a setting in electron to enable this. I honestly don't think there is though, I think the problem is something to do Chromium and how it manages the RequestAnimationFrame internally. Which I would need to edit that and re-compile from source.  If so, where do I start? There is no way I am switching game engines at this point.

Edit: There is a way around this and it's using Web Workers, but I don't think using Web Workers within a Physics engine is a good idea :P

Link to comment
Share on other sites

Yeah, its not possible, browsers can not consume that much potential power when effectively 'idle'.

From your end though, you don't need to be running anything when the browser isn't visible either (I know it could be visible but unfocussed, but I'm just ignoring that for now), you just need to know where stuff is and what its doing when the user comes back.

It would depend on your architecture but, for example, if you had an authoritative server that sent entire state packets then it'd be fairly trivial as you'd be rendering the scene from the state each 'tick' anyway.

If the logic is all on the server then handling client 'pauses' shouldnt be too problematic but if you have a more chaotic solution or peer-to-peer style thing going on then I'd imagine things are going to get fairly complex.

Link to comment
Share on other sites

9 minutes ago, mattstyles said:

Yeah, its not possible, browsers can not consume that much potential power when effectively 'idle'.

From your end though, you don't need to be running anything when the browser isn't visible either (I know it could be visible but unfocussed, but I'm just ignoring that for now), you just need to know where stuff is and what its doing when the user comes back.

It would depend on your architecture but, for example, if you had an authoritative server that sent entire state packets then it'd be fairly trivial as you'd be rendering the scene from the state each 'tick' anyway.

If the logic is all on the server then handling client 'pauses' shouldnt be too problematic but if you have a more chaotic solution or peer-to-peer style thing going on then I'd imagine things are going to get fairly complex.

Hey, thank for the reply. I was thinking of something after I read this

Since setInterval seems like it's working when the browser is minimized / not active, maybe I can change Phaser to update it's logic using that instead of RAF? (http://phaser.io/docs/2.4.4/Phaser.RequestAnimationFrame.html#forceSetTimeOut). Since I can detect if tab (or should I say window since I'm using Electron) is minimized / not active.  

 

Link to comment
Share on other sites

I dont think the setInterval is consistent when unfocussed, although that might be largely a cross-browser issue, which you'll avoid with Electron.

Yeah, just found something that suggests it'll be inaccurate http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs

I'm pretty sure your only sure-fire solution is server-side timing. Is most/all of your application logic running on the server anyway?

Link to comment
Share on other sites

2 hours ago, mattstyles said:

I dont think the setInterval is consistent when unfocussed, although that might be largely a cross-browser issue, which you'll avoid with Electron.

Yeah, just found something that suggests it'll be inaccurate http://stackoverflow.com/questions/6032429/chrome-timeouts-interval-suspended-in-background-tabs

I'm pretty sure your only sure-fire solution is server-side timing. Is most/all of your application logic running on the server anyway?

Yep, the problem is even if it's serverside the player can be alt-tabbed if let's say someone is shooting a fireball at them :)

 

I found a solution and it's through the win.setMinimizable(minimizable) option with electron. https://github.com/atom/electron/pull/4156

It disables the user to minimize the window (see how it removes it here)

ee33a98f4b0b96a5a68534021e3c8a09.png

 

But, you can still minimize the window by using WindowsKey+D. But! RAF still runs! Thankfully! Haha. But I am not sure if that's intended or a bug! Because I don't want electron to later down the road make it so RAF stops when the client is minimized by WindowsKey+D if win.setMinimizable(minimizable) is set to false.

So I guess that is a fix for now..... something just doesn't feel right here though.

 

Link to comment
Share on other sites

Wow, nuking the minimise button is a big step, but, I guess I'm slightly tarnished by the web where usability and inclusion is paramount, most games I play can't be minimised either so it's probably fine.

The setMinimizable( false ) thing, that doesn't solve unfocussed windows though right? you tab away and it pauses? Oh, mind you, that isn't Chrome behaviour anyway right? It only pauses when the tab changes, which won't happen with Electron, so the window losing focus isnt a problem.

Link to comment
Share on other sites

My understanding is that setInterval will be delayed for inactive tabs, similar to requestAnimationFrame. The exact behavior will likely vary between browsers and browser versions. setInterval is inferior to RAF for animation purposes, so I wouldn't use it in any case. If setInterval does run more often for inactive tabs than RAF then I suppose you could use RAF when the tab is active and fall back to setInterval when inactive, but that's an ugly hack and you didn't hear it from me.  :-)

You're likely to receive complaints from some users if your game has window chrome, but the minimize button is missing. It would be much better to change the game so a player can gracefully drop out of the action when minimized and drop back in when restored. Keeping the game running when the tab or browser is not active will unnecessarily run down the battery for mobile devices, which is not nice.

Link to comment
Share on other sites

5 hours ago, mattstyles said:

Wow, nuking the minimise button is a big step, but, I guess I'm slightly tarnished by the web where usability and inclusion is paramount, most games I play can't be minimised either so it's probably fine.

The setMinimizable( false ) thing, that doesn't solve unfocussed windows though right? you tab away and it pauses? Oh, mind you, that isn't Chrome behaviour anyway right? It only pauses when the tab changes, which won't happen with Electron, so the window losing focus isnt a problem.

Yep your right, the disibility `game.stage.disableVisibilityChange = true;` in Phaser fixes that and thank heaven for it! :)

I found the core issue here guys if anyone is wondering:

There is actually a command line argument inside Chromium that let' you continue rendering even when the page is minimized (or ran as a background):

It's called: 

disable-renderer-backgrounding

Which can be used inside an electron app. The problem is, it doesn't continue to render RAF, only other processes inside Chromium see this: https://github.com/atom/electron/issues/4317#issuecomment-194279148

Quote

I tried to patch a few places related to throttling but none of them works for animations, so filing an issue would probably be the only choice.

So it looks like 'disable-renderer-backgrounding' does work, but not for RAF. They have created a github issue about it 3 days ago, so hopefully they find a away to hack it in there.

Quote

The --disable-renderer-backgrounding command line switch only disables throttling for timers, there is currently no way to disable throttling of requestAnimationFrame.

Kudo's to the electron team. I wonder if there is anything besides chromium to create packaged apps? I really just need something like Ejecta but for Windows.. I'm really getting fed up with this Chromium, RAF stuff to be honest. I just want my game to run in the background. It shouldn't be that hard. Obviously, I can do Web Workers and have it update the physics... but I feel like that will cause more issues, especially for a multiplayer game.

Link to comment
Share on other sites

1 hour ago, BobF said:

My understanding is that setInterval will be delayed for inactive tabs, similar to requestAnimationFrame. The exact behavior will likely vary between browsers and browser versions. setInterval is inferior to RAF for animation purposes, so I wouldn't use it in any case. If setInterval does run more often for inactive tabs than RAF then I suppose you could use RAF when the tab is active and fall back to setInterval when inactive, but that's an ugly hack and you didn't hear it from me.  :-)

You're likely to receive complaints from some users if your game has window chrome, but the minimize button is missing. It would be much better to change the game so a player can gracefully drop out of the action when minimized and drop back in when restored. Keeping the game running when the tab or browser is not active will unnecessarily run down the battery for mobile devices, which is not nice.

Ha, my game get's like 2fps on mobile anyway :P But yeah, the mainWindow.setMinimizable(false); does do the trick for now, and the window will always be active which I agree will annoy people. Plus, it only works for Window user's as well.  I want to ship my game to linux too. So, I guess just waiting on the fabulous electron team to find a away to fix that issue. Although, it's more of a hacked feature within Chromium, not complaining though haha.

Link to comment
Share on other sites

It sounds like --disable-renderer-backgrounding does what you want, you just need to switch from RAF to setInterval while you're in the background, and back to RAF when you're active again. For example, you could run both RAF and setInterval together. Have RAF set a timestamp on each iteration that can be checked by setInterval. As long as setInterval sees it has been, say, less than 1 second since the RAF timestamp was last set then it would do nothing. But if more than 1 sec has passed since the RAF timestamp was last set then setInterval does the same work RAF would have done. SetInterval's timing won't be as accurate as RAF, but that shouldn't matter since the user has put the game in the background anyway.

Link to comment
Share on other sites

Okay big news:

Anyone that see's this thread, should now know that NW.js has just patched in a new chromium argument:

https://github.com/nwjs/nw.js/issues/4664#issuecomment-204321581

By using  --disable-raf-throttling

https://github.com/rogerwang Is a boss. An absolute boss for helping me with this issue. This is actually yuuuge news. Multiplayer games can now be minimized without being paused / stopped and their physics can run sequentially with RAF! Especially when mixed with game.stage.disableVisibilityChange = true;

 You could not use that argument as well obviously if you want your game to NOT run in the background... which is fine to save CPU / GPU usage, but for multiplayer games that depend on Physics tied with RAF.. This is a freaking huge step forwards in game development I think. Especially with packaged app's.. I am so freaking excited, this was stressing me out for days!

 

You are welcome!  But RogerWang deserves all the credit :wub:

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...