Skip to content
4 changes: 1 addition & 3 deletions config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ module.exports = [
});
}
}
],

devtool: 'source-map'
]
}
];
2 changes: 1 addition & 1 deletion src/core/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ var Config = new Class({
/**
* @const {number} Phaser.Core.Config#loaderMaxRetries - The number of times to retry a file load if it fails.
*/
this.loaderMaxRetries = GetValue(config, 'loader.maxRetries', 2);
this.loaderMaxRetries = GetValue(config, 'loader.maxRetries', 5);

/**
* @const {boolean} Phaser.Core.Config#loaderWithCredentials - Optional XHR withCredentials value.
Expand Down
2 changes: 1 addition & 1 deletion src/core/typedefs/LoaderConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
* @property {string[]} [localScheme] - An optional array of schemes that the Loader considers as being 'local' files. Defaults to: `[ 'file://', 'capacitor://' ]` if not specified.
* @property {boolean} [withCredentials=false] - Optional XHR withCredentials value.
* @property {string} [imageLoadType='XHR'] - Optional load type for image, `XHR` is default, or `HTMLImageElement` for a lightweight way.
* @property {number} [maxRetries=2] - The number of times to retry the file load if it fails.
* @property {number} [maxRetries=5] - The number of times to retry the file load if it fails.
*/
41 changes: 28 additions & 13 deletions src/loader/File.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,23 +243,33 @@ var File = new Class({
this.base64 = (typeof url === 'string') && (url.indexOf('data:') === 0);

/**
* The counter for the number of times to retry loading this file before it fails.
*
* The number of times to retry loading this file if it fails.
*
* You can set this property value in the FileConfig object. If not present,
* this property is read from the `LoaderPlugin.maxRetries` property when
* this File instance is created.
*
*
* You can set this value via the Game Config, or you can adjust the `LoaderPlugin` property
* at any point after the Loader has started. However, it will not apply to files
* that have already been added to the Loader, only those added after this value
* is changed.
*
* @name Phaser.Loader.File#retryAttempts
* @name Phaser.Loader.File#maxRetries
* @type {number}
* @default 5
* @since 3.88.0
*/
this.maxRetries = GetFastValue(this.xhrSettings, 'maxRetries', loader.maxRetries);

/**
* The counter for the number of times loading has failed and was retried.
*
* @name Phaser.Loader.File#retries
* @type {number}
* @default 2
* @since 3.85.0
* @default 0
* @since 3.88.0
*/
this.retryAttempts = GetFastValue(fileConfig, 'maxRetries', loader.maxRetries);
this.retries = 0;
},

/**
Expand Down Expand Up @@ -358,7 +368,7 @@ var File = new Class({

this.resetXHR();

this.loader.nextFile(this, success);
this.loader.nextFile(this, success, event);
},

/**
Expand Down Expand Up @@ -386,24 +396,29 @@ var File = new Class({
* Called if the file errors while loading, is sent a DOM ProgressEvent.
*
* @method Phaser.Loader.File#onError
* @fires Phaser.Loader.Events#FILE_LOAD_RETRY
* @since 3.0.0
*
* @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
* @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error.
*/
onError: function ()
onError: function (xhr, event)
{
this.resetXHR();

if (this.retryAttempts > 0)
if (this.retries < this.maxRetries)
{
this.retryAttempts--;
var retryDelay = Math.min(Math.pow(2, this.retries) * 100, 5000); // ms

this.retries++;

this.loader.emit(Events.FILE_LOAD_RETRY, this, event, this.retries);

this.load();
setTimeout(this.load.bind(this), retryDelay);
}
else
{
this.loader.nextFile(this, false);
this.loader.nextFile(this, false, event);
}
},

Expand Down
11 changes: 6 additions & 5 deletions src/loader/LoaderPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -349,18 +349,18 @@ var LoaderPlugin = new Class({

/**
* The number of times to retry loading a single file before it fails.
*
*
* This property is read by the `File` object when it is created and set to
* the internal property of the same name. It's not used by the Loader itself.
*
*
* You can set this value via the Game Config, or you can adjust this property
* at any point after the Loader has started. However, it will not apply to files
* that have already been added to the Loader, only those added after this value
* is changed.
*
* @name Phaser.Loader.LoaderPlugin#maxRetries
* @type {number}
* @default 2
* @default 5
* @since 3.85.0
*/
this.maxRetries = GetFastValue(sceneConfig, 'maxRetries', gameConfig.loaderMaxRetries);
Expand Down Expand Up @@ -1029,8 +1029,9 @@ var LoaderPlugin = new Class({
*
* @param {Phaser.Loader.File} file - The File that just finished loading, or errored during load.
* @param {boolean} success - `true` if the file loaded successfully, otherwise `false`.
* @param {Event | string} [event] - The Event that resulted from an error, if loading was not successful.
*/
nextFile: function (file, success)
nextFile: function (file, success, event)
{
// Has the game been destroyed during load? If so, bail out now.
if (!this.inflight)
Expand Down Expand Up @@ -1058,7 +1059,7 @@ var LoaderPlugin = new Class({

this._deleteQueue.set(file);

this.emit(Events.FILE_LOAD_ERROR, file);
this.emit(Events.FILE_LOAD_ERROR, file, event);

this.fileProcessComplete(file);
}
Expand Down
3 changes: 2 additions & 1 deletion src/loader/events/FILE_LOAD_ERROR_EVENT.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* The File Load Error Event.
*
* This event is dispatched by the Loader Plugin when a file fails to load.
* This event is dispatched by the Loader Plugin when a file fails to load without retry.
*
* Listen to it from a Scene using: `this.load.on('loaderror', listener)`.
*
Expand All @@ -16,5 +16,6 @@
* @since 3.0.0
*
* @param {Phaser.Loader.File} file - A reference to the File which errored during load.
* @param {Event | string} event - The Event that resulted from this error.
*/
module.exports = 'loaderror';
23 changes: 23 additions & 0 deletions src/loader/events/FILE_LOAD_RETRY_EVENT.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @author Richard Davey <[email protected]>
* @author Pavle Goloskokovic <[email protected]> (http://prunegames.com)
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/

/**
* The File Load Retry Event.
*
* This event is dispatched by the Loader Plugin when a file fails to load but will retry loading.
*
* Listen to it from a Scene using: `this.load.on('loadretry', listener)`.
*
* @event Phaser.Loader.Events#FILE_LOAD_RETRY
* @type {string}
* @since 3.88.0
*
* @param {Phaser.Loader.File} file - A reference to the File which errored during load, and is retrying.
* @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error.
* @param {number} retries - The number of times loading has failed and was retried.
*/
module.exports = 'loadretry';
2 changes: 1 addition & 1 deletion src/loader/events/FILE_PROGRESS_EVENT.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* @type {string}
* @since 3.0.0
*
* @param {Phaser.Loader.File} file - A reference to the File which errored during load.
* @param {Phaser.Loader.File} file - A reference to the File which is loading.
* @param {number} percentComplete - A value between 0 and 1 indicating how 'complete' this file is.
*/
module.exports = 'fileprogress';
1 change: 1 addition & 0 deletions src/loader/events/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = {
COMPLETE: require('./COMPLETE_EVENT'),
FILE_COMPLETE: require('./FILE_COMPLETE_EVENT'),
FILE_KEY_COMPLETE: require('./FILE_KEY_COMPLETE_EVENT'),
FILE_LOAD_RETRY: require('./FILE_LOAD_RETRY_EVENT'),
FILE_LOAD_ERROR: require('./FILE_LOAD_ERROR_EVENT'),
FILE_LOAD: require('./FILE_LOAD_EVENT'),
FILE_PROGRESS: require('./FILE_PROGRESS_EVENT'),
Expand Down
6 changes: 4 additions & 2 deletions src/loader/filetypes/HTML5AudioFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ var HTML5AudioFile = new Class({
*
* @method Phaser.Loader.FileTypes.HTML5AudioFile#onError
* @since 3.0.0
*
* @param {Event | string} event - The Event that resulted from this error.
*/
onError: function ()
onError: function (event)
{
for (var i = 0; i < this.data.length; i++)
{
Expand All @@ -98,7 +100,7 @@ var HTML5AudioFile = new Class({
audio.onerror = null;
}

this.loader.nextFile(this, false);
this.loader.nextFile(this, false, event);
},

/**
Expand Down
4 changes: 2 additions & 2 deletions src/loader/filetypes/ImageFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,9 @@ var ImageFile = new Class({
_this.loader.nextFile(_this, true);
};

this.data.onerror = function ()
this.data.onerror = function (event)
{
_this.loader.nextFile(_this, false);
_this.loader.nextFile(_this, false, event);
};

this.data.src = this.src;
Expand Down
1 change: 0 additions & 1 deletion src/loader/typedefs/FileConfig.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/loader/typedefs/XHRSettingsObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
* @property {(string|undefined)} [headerValue] - This value is used to populate the XHR `setRequestHeader` and is undefined by default.
* @property {(string|undefined)} [requestedWith] - This value is used to populate the XHR `setRequestHeader` and is undefined by default.
* @property {(string|undefined)} [overrideMimeType] - Provide a custom mime-type to use instead of the default.
* @property {boolean} [withCredentials=false] - The withCredentials property indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. Setting withCredentials has no effect on same-site requests.
* @property {boolean} [withCredentials=false] - The withCredentials property indicates whether cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. Setting withCredentials has no effect on same-site requests.
* @property {number} [maxRetries=5] - The number of times to retry the file load if it fails.
*/