Monday, April 21, 2025
spot_img

Recreation reloads or crashes on iPhone when loading belongings from a number of Distant Bundles (Cocos Creator v3.8.1) – Cocos Creator


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:

  1. Has anybody skilled comparable points when loading belongings from many distant bundles on iOS?

  2. May this be resulting from iOS reminiscence limitations (low RAM or webview/browser constraints)?

  3. Are there any optimizations for loading/unloading belongings to keep away from reloads/crashes?

  4. 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!

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisement -spot_img

Latest Articles