Recreation reloads or crashes on iPhone when loading belongings from a number of Distant Bundles (Cocos Creator v3.8.1)
Howdy everybody,
I’m growing a recreation utilizing Cocos Creator v3.8.1, focusing on each native and HTML5 platforms.
The sport is cut up into 29 distant bundles, every representing a mini recreation. The sizes of the bundles vary from 128.6 KB to twenty MB.
Throughout gameplay:
- I load all belongings from a bundle when a mini recreation is opened, and after that, load belongings from the subsequent bundle to modify to a unique mini recreation.
- This course of continues with load – swap – load.
The difficulty:
- On cellular browsers (Safari/Chrome) and native app (iPhone 8 Plus), the sport both reloads or crashes after loading belongings from about 10 bundles. Nonetheless, the precise variety of bundles is unsure, and the possibilities of the crash/reload occurring will increase with the extra belongings loaded.
- Check machine used: iPhone 8 Plus (older iOS).
- Checks on Android (Be aware 9) have no points.
The code liable for loading belongings:
loadAny(...args: any[]): Promise {
return new Promise(async (resolve, reject) => {
attempt {
let [assets, options, onProgress, onComplete] = args;
choices = choices ?? {}; // If choices just isn't offered, initialize as an empty object
const loadPromises = belongings.map((assetsInfo) => {
return new Promise((res, rej) => {
const { bundle } = assetsInfo;
ResourceMap.log(`[ResourceMap] loadAny assetsInfo`, assetsInfo);
if (bundle && bundle.size > 0 && cc[`settings`].querySettings("belongings", "projectBundles").consists of(bundle)) {
this.loadBundle(bundle).then(() => {
res(assetsInfo);
}).catch((err) => {
ResourceMap.error(`[ResourceMap] loadAny err`, err);
res(null);
});
} else {
res(assetsInfo);
}
});
});
// Await all guarantees to finish
let outcomes = await Promise.all(loadPromises);
// Filter out any null outcomes
belongings = outcomes.filter(consequence => consequence !== null) as AssetManager.Bundle[];
// After preloading completes, transfer to the loading part
await this.loadAssetsInParallel(belongings, choices, (loaded, complete) => {
if (onProgress) {
onProgress(loaded, complete); // Ahead progress throughout preload part
}
}, (err, outcomes) => {
if (err) {
if (onComplete) {
onComplete(err); // Full callback after loading
}
resolve(outcomes); // Resolve with the info after each preloading and loading
} else {
if (onComplete) {
onComplete(null, outcomes); // Full callback after loading
}
resolve(outcomes); // Resolve with the info after each preloading and loading
}
});
} catch (error) {
reject(error); // Reject the promise in case of any error
}
});
}
loadAssetsInParallel(belongings, choices, onProgress, onComplete) {
let complete = belongings.size;
let loaded = 0;
const assetLoadingPromises = belongings.map((asset) => {
return new Promise((resolve, reject) => {
if (this.uuidMap.has(asset.uuid)) {
loaded++;
if (onProgress) {
onProgress(loaded, complete); // Ahead progress throughout preload part
}
resolve({ asset: this.uuidMap.get(asset.uuid), data: asset }); // Resolve the promise as soon as the asset is loaded
} else {
assetManager.loadAny(asset, choices, (loaded, complete, merchandise) => {
ResourceMap.log(`[ResourceMap] loadAny uuid: ${merchandise.uuid}, path: ${merchandise.url}, bundle: ${merchandise['config'].identify}, kind: ${js.getClassName(merchandise?.data?.['ctor'])}`);
}, (err, information) => {
loaded++;
if (onProgress) {
onProgress(loaded, complete); // Ahead progress throughout preload part
}
if (err) {
ResourceMap.error(`[ResourceMap] loadAny err`, err);
resolve(null); // Resolve with null in case of an error
return;
}
resolve({ asset: information, data: asset }); // Resolve the promise as soon as the asset is loaded
});
}
});
});
attempt {
let information = await Promise.all(assetLoadingPromises);
information = information.filter(consequence => consequence !== null);
let outcomes = [];
information.forEach((v) => {
let a = v.asset;
if (Array.isArray(a)) {
a.forEach((_v) => {
outcomes.push(_v);
this.updateUUIDMap(_v);
});
} else {
outcomes.push(a);
this.updateUUIDMap(a);
}
});
if (onComplete) {
onComplete(null, outcomes); // Full callback after loading
}
return outcomes;
} catch (err) {
ResourceMap.error(`[ResourceMap] loadAny An error occurred throughout parallel asset loading:`, err);
if (onComplete) {
onComplete(err, null);
}
}
}
Questions:
-
Has anybody skilled comparable points when loading belongings from many distant bundles on iOS?
-
May this be resulting from iOS reminiscence limitations (low RAM or webview/browser constraints)?
-
Are there any optimizations for loading/unloading belongings to keep away from reloads/crashes?
-
How ought to I rethink dividing bundles for a venture with many mini video games?
Any suggestions, ideas, or simply pointing me in the best path would imply so much. Thanks prematurely!