playcanvas / playcanvas/engine

There's an app.start(), but not an app.stop()

Open
#5,709 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
JavaScript
Stars
16.8k
Forks
2k
Avg merge
4h 32m
Merged PRs (30d)
222

Description

Feature request: For manual engine users, we create and start the application:

const app = new pc.Application(canvas, {...});
app.start()

There is no equivalent .stop() nor .pause() method though.

Use cases:

  1. When the Playcanvas canvas / scene is no longer in the user's viewport or DOM. In my specific case, there are UI tabs that let you switch between the scene and a configuration pane. When switching tabs, the scene should no longer have an animationFrame loop.
  2. When using React + hot reloading in local development, like in Next.js, every time a hot reload happens, React hook "cleanup" functions run, basically mimicking what happens in use case 1, aka unmounting (and then immediately re-mounting) the scene. I store the app in memory in a parent component so the app/context is preserved, but there's no way to pause the app and then resume it in this case.

I tried calling app.destroy() in the cleanup hook, but that does not leave the app in a restartable state.

I tried hacking a pause method on top of app, it's not easy because the frameRequest variable is private. Meaning, in my code, if I do app.tick = null, the next window.requestAnimationFrame(application.tick) in the current tick fails.

I was able to cancel all animation frames with a no bueno hack. Here's the current cleanup and resume hook I have for reference:

function cancelAllAnimationFrames() {
  let id = window.requestAnimationFrame(() => {});
  while (id--) {
    window.cancelAnimationFrame(id);
  }
}

// ...

useEffect(() => {
  app.on('update', animate);
  if (!app.tick) {
    // @ts-ignore
    app.tick = app._lastTick;
    app.tick();
  }

  return () => {
      app.off('update');
      cancelAllAnimationFrames();
      // @ts-ignore
      app._lastTick = app.tick;
      // @ts-ignore
      app.tick = null;
    }
  };
}, [app, animate]);

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/framework/app-base.js, especially the private frameRequest handling around the application tick loop. Trace how app.start() and app.destroy() manage animation frames, then define restartable stop and pause behavior for the manual engine use cases. Done should allow an application to stop or pause without destroying it and resume without leaving an active animation loop.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
game-dev
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.