A complete technical guide to packaging HTML5 games for BentoTiles. Covers relative asset paths, Phaser, Godot 4 Web exports, mobile touch support, audio autoplay unlocking, and metadata optimization.
Shipping an HTML5 game to a global web portal should be an exhilarating milestone, not an exercise in debugging broken asset paths and rejected ZIP archives. Yet, over 65% of first-time web game submissions to portals fail initial automated quality assurance (QA) because of a handful of preventable technical oversights: absolute path references, missing root entry files, unhandled Web Audio autoplay policies, or unscaled mobile canvas viewports.
At BentoTiles, we host approved games inside isolated, high-performance Cloudflare R2 edge containers served over secure HTTPS. This architecture guarantees blazing-fast, sub-2-second loading and bulletproof sandboxing—but it also requires that your game archive adheres to clean, standardized web packaging practices.
Whether you built your game using Phaser 3, Godot 4, Construct 3, PixiJS, Three.js, or Vanilla JavaScript Canvas, this step-by-step technical guide covers everything you need to package, optimize, test, and upload your game for seamless approval on BentoTiles.
Every major game development framework supports HTML5/WebAssembly export, but default export templates often include desktop or development clutter. Here is how to configure your build for optimal browser delivery:
./):// vite.config.js
export default {
base: './', // Crucial for relative asset loading
build: {
outDir: 'dist',
assetsDir: 'assets',
}
}
cdnjs.cloudflare.com or unpkg.com tags. School campus filters and strict ad-blockers frequently block external third-party CDN scripts, causing your game to fail on student Chromebooks.Cross-Origin-Opener-Policy (COOP) and Cross-Origin-Embedder-Policy (COEP) headers. For maximum compatibility across web portals, export using the Single-Threaded build option if your game does not strictly require multi-threaded physics..pck package. - index.html (rename the export file to index.html)
- index.js
- index.wasm
- index.pck
Place all four files directly at the root of your ZIP archive.
my-game-zip/
├── index.html <-- Absolute root of the archive
├── style.css
├── js/
│ ├── main.js
│ └── game.js
└── assets/
├── sprites/
└── audio/
This is the single most common reason game submissions fail automated QA.
When your game is uploaded to BentoTiles, it is not hosted at the domain root (e.g. https://bentotiles.com/assets/player.png). Instead, it runs inside an isolated, sandboxed subfolder served from our global Cloudflare R2 edge storage:
https://games.bentotiles.com/games/[your-game-slug]/index.html
<img src="/assets/player.png">
<script src="/js/engine.js"></script>
In the browser, this tells the client to look at https://games.bentotiles.com/assets/player.png, which does not exist! Your sprites will fail to load with a 404 error, and your canvas will display a blank screen.
<img src="./assets/player.png">
<!-- Or simply: -->
<img src="assets/player.png">
This tells the browser to resolve the asset relative to the current index.html directory (https://games.bentotiles.com/games/[your-game-slug]/assets/player.png). Every texture, sprite sheet, audio file, JSON level data, and WebAssembly binary must use relative paths.
When compressing your files into a .zip archive, select the contents of your build directory—do not zip the parent folder itself.
MyGame.zip/MyGameFolder/index.htmlMyGame.zip/index.html (with assets directly beside it)Ensure all file names are lowercase and avoid spaces or special characters (e.g., use boss_level_1.png instead of Boss Level #1 (Final).png). Cloudflare R2 and Linux storage clusters are strictly case-sensitive.
Upload your ZIP archive (index.html at root) to our Cloudflare R2 edge sandbox and reach players on desktop and mobile with zero store fees.
To earn a top rating and reach maximum players on BentoTiles, your game should run smoothly on both desktop monitors and mobile touchscreens.
Ensure your index.html includes a responsive viewport meta tag inside the to prevent unwanted pinch-to-zoom gestures and mobile letterbox distortion:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
Add CSS to lock the canvas dimensions and disable elastic bounce scrolling:
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
touch-action: none; /* Prevents default browser swipe-to-refresh */
}
canvas {
display: block;
width: 100%;
height: 100%;
object-fit: contain; /* Preserves your aspect ratio with clean borders */
}
Don't limit your audience to desktop keyboards. If your game uses WASD or Arrow Keys for movement:
'ontouchstart' in window).e.code and e.key (e.g. KeyW and ArrowUp) for international keyboards.Modern browsers (Chrome, Safari, Firefox, and Edge) automatically block audio playback until the player interacts with the document via a click or tap gesture.
If your game attempts to play background music immediately upon initialization, the browser will throw an unhandled AudioContext was not allowed to start exception, occasionally muting all subsequent game audio.
// Resume AudioContext on first user interaction
function unlockAudio() {
if (myAudioContext && myAudioContext.state === 'suspended') {
myAudioContext.resume().then(() => {
console.log('AudioContext successfully unlocked');
});
}
window.removeEventListener('click', unlockAudio);
window.removeEventListener('touchstart', unlockAudio);
window.removeEventListener('keydown', unlockAudio);
}
window.addEventListener('click', unlockAudio);
window.addEventListener('touchstart', unlockAudio);
window.addEventListener('keydown', unlockAudio);
When players browse the BentoTiles bento grid, your metadata determines whether they click into your game or scroll past. Optimizing your submission metadata directly increases your initial play counts:
- Player 1: WASD to steer, Space to shoot
- Player 2: Arrow keys to steer, Enter to shoot
- Mobile: Left virtual joystick to steer, right tap button to fire
2-player, multiplayer, unblocked, arcade, action, puzzle, or io-games.In the coming weeks, BentoTiles is launching a built-in Prompt-Based Game Generation Engine. Registered developers on BentoTiles will get exclusive first access to early builds, the developer API, and our automated ad monetization tools. Turn natural language prompts into playable HTML5 code in minutes and start monetizing player sessions immediately.
Before uploading your ZIP archive to the BentoTiles Developer Portal, execute this 2-minute pre-flight checklist:
npx serve . or python3 -m http.server 8080) rather than opening file:///C:/index.html. Verify all textures, sounds, and fonts load with zero 404 errors.F12), switch to the Console tab, and play through two complete game loops. Confirm there are zero uncaught JavaScript errors or memory warnings.Once you hit submit on your developer dashboard:
index.html, checks for relative asset compliance, and scans for malware or external redirects.If any issue arises, you will receive clear, actionable feedback directly in your dashboard explaining what needs adjustment so you can resubmit immediately.
Ready to share your creation with millions of browser players? Submit your game to BentoTiles today or explore our Developer Documentation.
Inspect Live HTML5 Titles
Curious what formats players love? Explore live games across our top categories to test canvas responsiveness, frame rates, and control schemes before submitting your own title: