How to Run the Game while the Tab is Inactive?

How to Run the Game while the Tab is Inactive?

hi, the browser won’t like you to do that, so it controls the invocation of requestAnimationFrame and setTimeout, they are normally stopped when your tab is inactive. See MDN:

requestAnimationFrame() calls are paused in most browsers when running in background tabs or hidden <iframe>s in order to improve performance and battery life.

And chrome doc:

Chrome does not call requestAnimationFrame() when a page is in the background. This behavior has been in place since 2011.

In some circumstances, setTimeout may be able to run in a very low frequency. But all in all, you shouldn’t be relying on timer in background tab.

I know some games like idle games wants to use background timer to keep updating things, or keep connection with the network. I suggest you to run batched tasks while the page returning in normal state. The engine really doesn’t have much things to do here.

1 Like

Tried the solution here, there’s a problem, but it is what I’m looking for

I have the same problem where the Game is being pause… I tried the solution you suggested

game.on(Game.EVENT_HIDE, () => {
game.resume();
});

It’s not working anymore. resume is being called first. then Pause after.

Can you show me a new way of doing this?

Can I get help please.

image
image

@kazchew903
the engine source clearly calls out that this is un-reliable in the browser.
(cocos/core/game.ts:171)

    /**
     * @en Event triggered when game hide to background.<br>
     * Please note that this event is not 100% guaranteed to be fired on Web platform,<br>
     * on native platforms, it corresponds to enter background event, os status bar or notification center may not trigger this event.
     * @zh 游戏进入后台时触发的事件。<br>
     * 请注意,在 WEB 平台,这个事件不一定会 100% 触发,这完全取决于浏览器的回调行为。<br>
     * 在原生平台,它对应的是应用被切换到后台事件,下拉菜单和上拉状态栏等不一定会触发这个事件,这取决于系统行为。
     * @example
     * ```ts
     * import { game, audioEngine } from 'cc';
     * game.on(Game.EVENT_HIDE, function () {
     *     audioEngine.pauseMusic();
     *     audioEngine.pauseAllEffects();
     * });
     * ```
     */
    public static EVENT_HIDE = 'game_on_hide';

I would recommend you try directly hooking into the browser callbacks, if this works well we can ask the engine devs to merge this fix instead of the one they have currently.
Please refer to the following documentation:

I believe you should be able to solve your problem with this. (at least you will know when to pause and when to resume)

Not sure what happening and why you can’t resume the game, but there are two ways to ensure that

  1. Refer to game.resume implementation, game._runMainLoop() is what matters, but that will still be using requestAnimationFrame which won’t be invoked, so you should set the frame rate to other pace.
game.on(Game.EVENT_HIDE, () => {
    game.setFrameRate(20); // Don't use 60 or 30
});
  1. You can also have your own setTimeout callback to drive the main loop manually
game.on(Game.EVENT_HIDE, () => {
    const step = () => {
        game.step();
        setTimeout(step, 30);
    }
    setTimeout(step, 30);
});
1 Like

You can use web worker to run game mainLoop when hide tab