phaserjs / phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
https://phaser.io
MIT License
37.16k stars 7.1k forks source link

The Loader retries loading errored files #6872

Closed pavle-goloskokovic closed 3 months ago

pavle-goloskokovic commented 3 months ago

To avoid connectivity issues, usually with poor mobile networks, from breaking games โ€“ the Loader could make multiple attempts to reload errored files with exponential delay increase.

Currently if a file errors, depending on file type, it will either cause a breaking error or undesired behavior.

Here are code examples that demonstrate how playcanvas handles described behavior:

Enabling retry on loader level: https://github.com/playcanvas/engine/blob/v1.73.0/src/framework/handlers/loader.js#L325-L338

On file type handler level: https://github.com/playcanvas/engine/blob/v1.73.0/src/framework/handlers/handler.js#L39-L55

And on request level: https://github.com/playcanvas/engine/blob/v1.73.0/src/platform/net/http.js#L504-L525

Ideally, maxRetries setting could be added to the LoaderConfig to be set when creating a game and used globally for loading all files, but also be changed per file type, and even set per file by adding maxRetries option to the xhrSettings.

greptile-apps[bot] commented 3 months ago

For internal use only

To implement retry logic for loading errored files with exponential delay increase, follow these steps:

  1. Add maxRetries to LoaderConfig:

    • Modify /src/loader/typedefs/FileConfig.js to include maxRetries property.
      
      /**
    • @property {number} [maxRetries=0] - The maximum number of retry attempts for loading this file. */
  2. Update XHRLoader.js to handle retries:

    • Modify /src/loader/XHRLoader.js to include retry logic.

      function XHRLoader(file, xhrSettings) {
      let retries = 0;
      const maxRetries = file.maxRetries || 0;
      const retryDelay = 1000; // Initial delay in ms
      
      function load() {
         const xhr = new XMLHttpRequest();
         // ... existing XHR setup code ...
      
         xhr.onloadend = function () {
             if (xhr.status !== 200 && retries < maxRetries) {
                 retries++;
                 setTimeout(load, retryDelay * Math.pow(2, retries));
             } else {
                 // ... existing onloadend logic ...
             }
         };
      
         xhr.send();
      }
      
      load();
      }
  3. Update File.js to include maxRetries in file configuration:

    • Modify /src/loader/File.js to accept maxRetries from FileConfig.
      class File {
      constructor(loader, fileConfig) {
         // ... existing constructor code ...
         this.maxRetries = fileConfig.maxRetries || 0;
      }
      }

References

/src/loader/typedefs/FileConfig.js /changelog/3.7.1/CHANGELOG-v3.7.1.md /src/loader/index.js /.github/ISSUE_TEMPLATE /src/loader /types/phaser.d.ts /.github /src/loader/filetypes/typedefs/TilemapJSONFileConfig.js /src/loader/events/ADD_EVENT.js /src/loader/filetypes/typedefs/JSONFileConfig.js /src/loader/filetypes/typedefs/AsepriteFileConfig.js /src/loader/events/FILE_KEY_COMPLETE_EVENT.js /changelog/3.60/Loader.md /src/loader/typedefs /src/loader/filetypes/typedefs /src/loader/filetypes/typedefs/TextFileConfig.js /src/loader/filetypes/typedefs/TilemapImpactFileConfig.js /src/loader/const.js /changelog/3.5.1/CHANGELOG-v3.5.1.md /src/loader/filetypes/typedefs/SceneFileConfig.js /changelog/3.17/CHANGELOG-v3.17.md /src/loader/events/FILE_LOAD_ERROR_EVENT.js /changelog/3.7.1 /src/loader/filetypes/index.js /.github/CONTRIBUTING.md

#### About Greptile This response provides a starting point for your research, not a precise solution. Help us improve! Please leave a ๐Ÿ‘ if this is helpful and ๐Ÿ‘Ž if it is irrelevant. [Ask Greptile](https://app.greptile.com/chat/github/phaserjs/phaser/master) ยท [Edit Issue Bot Settings](https://app.greptile.com/apps/github)
photonstorm commented 3 months ago

Thank you for submitting this feature request. We have implemented this and the feature has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.