HTML5 game publishing
A Boot Sequence That Cannot Hang: Timeouts for Every Dependency
Using the roughly eight-second init() rejection as a design rule: a dependency table, a Promise.race timeout helper, honest loading screens and tests that break things on purpose.
Games break when they depend on something that is not there. A script that never loads, a save that never answers, an ad that never returns: each one can stall a loading screen for good. The SDK gives you one hard number to design around: init() rejects if it has not resolved after about eight seconds. This post uses that number to build a boot sequence in which nothing outside your game can stop it from starting.
The fact to design around
The reference says that init() returns a promise that resolves to a status object, and that if it has not resolved after about 8 seconds, it rejects. The advice that follows is to wrap it in try/catch and fall back to a fully offline boot, with no ads and a local-only save, rather than stalling your loading screen. Our post on the init boot sequence shows the basic version. This post extends the idea to every dependency.
List your dependencies
Before you write code, list what your start-up needs:
| Dependency | If it fails | Fallback |
|---|---|---|
| The SDK script | window.PlayKovoSDK is undefined | Run without it; skip ads and cloud save |
init() | Rejects after about 8 seconds | Continue offline |
| Cloud save | Result with ok: false | Local save, or a new game |
| Your own assets | 404 or decoding failure | Retry once, then show a clear error |
| Audio context | Blocked until the first click | Create it after the first interaction |
Only one line here is a real stop: your own assets. The rest can be skipped without ruining the game.
A boot that cannot hang
function withTimeout(promise, ms, fallbackValue) {
return Promise.race([
promise,
new Promise(resolve => setTimeout(() => resolve(fallbackValue), ms)),
]);
}
async function boot() {
let sdkReady = false;
try {
if (window.PlayKovoSDK) {
const status = await window.PlayKovoSDK.init();
sdkReady = !!status.ready;
}
} catch (e) {
// init rejected or failed: continue offline
}
let save = null;
if (sdkReady) {
const r = await withTimeout(window.PlayKovoSDK.cloudSave.get(), 3000, { ok: false });
if (r.ok && r.data) save = r.data;
}
if (!save) save = loadLocalSave();
await loadAssets();
startMainMenu(save, { ads: sdkReady });
}
boot();
Everything except the asset loading has a safe path. The cloud save gets its own shorter timeout, because the player should not wait eight seconds twice. The menu receives a flag saying whether ads are possible, so it can hide the rewarded button when they are not.
Keep the loading screen honest
If your game draws its own loading screen, tell the platform: call loadingStart() once it is visible and loadingFinished() once the game is interactive. The app then hides its own cover instead of showing two loaders. See loadingStart and loadingFinished. Call loadingFinished() in the fallback paths too. A game that fails over to offline mode but never reports finished leaves the cover up.
Retries: once, not forever
- Retry an asset once, since a brief network error is common.
- After the retry fails, show a message the player can read and a button to reload.
- Do not loop. An endless retry is a hidden freeze.
Show something quickly
A player who sees nothing for several seconds leaves. Draw a logo or progress bar as early as you can, before large assets load. A simple, honest bar is better than a fake animation. Keep the first download small; see the limits in what goes in a ZIP.
Test by breaking things
- Load the game with the SDK script blocked (many browsers let you block a URL in the developer tools).
- Throttle the network to a slow connection.
- Disable the network after the page loads.
- Delete a non-essential asset from a test build and check the error message.
- Check each of these on a phone.
A game that boots under all five is hard to break in the field. The pattern fits the rules in the SDK guidelines about unavailable features never blocking play; see also designing for unavailable ads.


