An Empty Unity Web Build Already Misses Poki's Size Budget: Engine Choice Is a Distribution Decision
The engine a licensed HTML5 game was built in decides which portals will accept it. Size limits, threading headers, and blocked CDN calls are engine decisions. Nobody asks about them during licence negotiation, and then a perfectly good game gets rejected by a distribution partner for reasons that have nothing to do with whether it is fun.
Buyers evaluate web games the way they evaluate any other content: they play it, they check the art, they ask about the licence scope. What they rarely do is open the build folder. That is where the commercially relevant information lives, because the major web platforms publish hard technical thresholds, and an engine's default export blows through several of them before a single asset is added.
This is not the device-performance argument โ that a cheap Android phone will chug. It is a narrower and more annoying problem: the game runs fine, and the platform still will not take it.
๐ The Acceptance Thresholds Are Published, and They Are Not Negotiable
Two of the largest web game platforms document what they require. These numbers function as the de facto spec for the whole channel, because a build that clears them will clear most smaller portals too.
Poki's requirements ask developers to target an initial download size under 8 MB. Games must work on desktop, mobile and tablet, at 16:9, with tablets automatically taking mobile control schemes.
CrazyGames' technical requirements are more generous on paper and stricter in the details. Total build up to 250 MB, but the initial download must be 50 MB or less โ and 20 MB or less to be eligible for the mobile homepage. On top of that: a maximum of 1,500 files, time to gameplay of 20 seconds or less for externally hosted files, and the game must run smoothly on a Chromebook with 4 GB of RAM.
Note where the two disagree. Poki's 8 MB and CrazyGames' 50 MB are not the same requirement measured differently; they reflect different bets about how much patience a player has. If you are licensing a catalogue to place across multiple portals, you are underwriting the tighter number, not the average of the two.
The file-count limit is the one that catches people. A framework that ships hundreds of individually loaded sprites, or an export that does not bundle its assets, can pass every size check and still fail on file count.
๐งฑ An Empty Unity Build Spends Most of the Budget Before You Add a Game
In October 2024, Aras Pranckeviฤius โ a long-time Unity graphics engineer โ published measurements of empty Unity 6 web builds. A default 3D URP project with nothing in it came out at 10.7 MB (6.9 MB of that code, 3.7 MB data). A 2D built-in-pipeline project landed at 7.7 MB. Getting it down took work: removing packages, disabling exceptions, high code stripping got him to 4.8 MB, and only after removing the Input System and Unity UI entirely, plus link-time optimisation, did an empty project reach 2.0 MB.
Read that against Poki's 8 MB initial-download target. A default Unity 6 3D project containing no game at all does not clear it. You can get under the line, but only by stripping the engine down to something that no longer resembles a default project โ which is a decision made during development, by the developer, not something a licensee can retrofit after the fact.
None of this makes Unity the wrong engine. It makes Unity a wrong-by-default engine for the web channel, which is a different claim. A studio that builds for the web deliberately ships small Unity builds. A studio that ported an existing mobile title generally does not.
The vendor's compatibility claim and the platform's behaviour are different documents
Unity's own manual lists Web platform support for iOS Safari 15 and up and Chrome 58 and up on Android, with no experimental caveat. CrazyGames, running the actual traffic, states that Unity games are disabled on iOS by default pending a performance evaluation.
Both statements are true. One describes whether the runtime executes; the other describes whether a commercial platform is willing to serve it to players. During due diligence, only the second one predicts revenue.
There is a related detail in Unity's manual worth flagging because it breaks a feature rather than a build: Safari on iOS does not support IndexedDB inside iframes. Portals embed games in iframes. If the game stores progress, high scores or settings in IndexedDB, that persistence silently fails for a large share of mobile players on a portal, while working perfectly on the developer's own test page.
๐งต The Threading Header Is Where Engine Choice Collides With Ad Revenue
This is the one that actually costs money, and it is almost never raised in a licensing conversation.
Multi-threaded WebAssembly needs SharedArrayBuffer. Since the Spectre-era mitigations, browsers only expose that API to pages that are cross-origin isolated, which means serving both Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers.
Cross-origin isolation is not a switch you flip on one file. As Google's web.dev guidance sets out, every subresource has to explicitly opt in via CORS or a Cross-Origin-Resource-Policy header, and the entire chain of documents โ parent frames and child frames included โ must be isolated too. Resources you do not control have to cooperate, or you must ask their owners to add headers.
Ad tags, mediation scripts and analytics beacons are precisely the resources you do not control. Chrome's credentialless embedder policy exists to relax this, but web.dev notes it shipped in Chrome 96 and Edge and is not supported by other browsers.
The Godot team stated the business consequence plainly in their 4.3 web export report: the required isolation headers "disable external API calls," which they describe as problematic for monetization and third-party integrations. Godot 4.0 leaned hard on SharedArrayBuffer; 4.3 reintroduced single-threaded builds specifically so exports could be deployed without cross-origin isolation. They also reported an unplanned benefit โ long-standing failures on macOS and iOS disappeared in single-threaded exports.
So the practical position for a portal operator:
- A threaded web build may require you to serve isolation headers on the page hosting it.
- Those headers can break the ad stack that pays for the page.
- Single-threaded exports avoid the problem and cost frame-rate headroom in CPU-heavy scenes.
- Which of those you got is decided at export time, by someone else, before you ever saw the game.
"Does this build require SharedArrayBuffer?" is a one-line question with a yes/no answer, and it belongs in the same email as the licence terms.
๐ "No External Requests" Breaks Default Engine Templates
Poki blocks all external requests from games by default. Their documentation names the usual offenders: Google Fonts, external assets, external CDN libraries. Multiplayer servers and some analytics providers are reviewed case by case; Google Analytics is always blocked.
This is a bigger deal than it sounds, because pulling a font or a physics library from a CDN is the default behaviour of half the HTML5 templates in circulation. The game works everywhere the developer tested it. It fails on a platform that enforces self-containment โ and it fails in a way that looks like a rendering bug rather than a policy violation.
For catalogue buyers, the same principle applies to your own deployments. A game that phones home to an origin you do not own is a game whose behaviour can change without notice, and whose availability depends on someone else's hosting bill. Self-contained builds are worth paying for.
โ๏ธ What Wasm 3.0 Changes, and What It Doesn't
WebAssembly 3.0 was declared the live standard on 17 September 2025, per the WebAssembly working group. It is the largest change since the original MVP: Memory64 lifts the addressable ceiling above the old 4 GB limit, plus garbage collection, multiple memories per module, typed references, tail calls, exception handling and relaxed SIMD.
Memory64 and GC matter for the top end โ large 3D titles, and languages like Java, Kotlin and Dart that can now target the web with a host GC. Neither of them makes a download smaller. The constraint that governs the web games channel is bytes-before-first-play and platform acceptance criteria, and Wasm 3.0 does nothing about either.
Treat it as a ceiling being raised, not a floor being lowered. It also arrives on engine timelines, not spec timelines: a feature being standardised in September 2025 says nothing about when your licensor's engine version emits it.
๐ Six Questions to Add to Web Game Due Diligence
None of these require an engineer to answer. All of them are cheap to ask before signing.
- What is the initial download, in bytes, to first playable frame? Not total build size. Not the zip. The bytes before the player can act.
- Does the build require cross-origin isolation? If yes, you need to know what that does to your ad stack before, not after.
- How many files does the build contain? Against a 1,500-file ceiling this is a pass/fail number.
- Does it make any request to an origin you do not control? Fonts, CDNs, analytics, leaderboards. Ask for the network log, not an assurance.
- Where does it store player state, and has it been tested inside an iframe on iOS Safari? This is where the IndexedDB gap surfaces.
- Which platform SDKs are already integrated, and who owns re-integrating them? Portal SDKs are a recurring maintenance obligation, not a one-off task.
If a licensor cannot answer these, that is itself the answer. Everything in the list is knowable from a build folder in under an hour.
๐ซ Five Ways Buyers Get the Engine Question Wrong
- Treating the engine name as a quality signal. "Built in Unity" tells you nothing about web viability. A well-built Construct or Phaser title will out-deliver a lazily ported Unity build on every metric that matters for a portal.
- Testing on the developer's demo page. That page has no ad stack, no iframe, no consent banner and no isolation headers. Your page has all four. Test in your own embed.
- Buying volume without opening a single build. A thousand titles where a third exceed your load budget is not a thousand-title catalogue.
- Assuming the licensor will fix builds later. Size reductions in an engine build are development work. Unless the contract says who does it and by when, nobody does it.
- Ignoring the maintenance side of portal SDKs. Platform SDKs get versioned. Someone re-integrates and re-uploads. If your licence is content-only, that someone is you.
๐ฎ Where a Licensed Catalogue Fits
Forestry Games has licensed HTML5 games and Android titles since 2017, and develops HTML5 games in-house โ which means the export settings, file counts and threading decisions above are made with distribution in mind rather than discovered afterwards. For operators running their own white-label portal, that is the difference between a catalogue you can place and a catalogue you have to rework. Where a buyer needs to modify builds themselves, source-code licensing is the route that actually permits it โ a content licence generally does not.
๐งญ What to Do Before the Next Catalogue Purchase
Pick five titles from any catalogue you are considering, at random rather than from the licensor's shortlist. Load each one inside an iframe on a staging page that carries your real ad tags and consent banner. Record the bytes to first playable frame, the file count, whether the console reports a SharedArrayBuffer failure, and whether any request leaves for an origin you do not own. Then repeat the whole thing on an iOS device and check whether saved progress survives a reload.
That test takes an afternoon. It will tell you more about whether a catalogue can be distributed than a month of playing the games will, and it converts a vague technical worry into five numbers you can put in front of a licensor before the contract is signed. Games get rejected by platforms for reasons that were fixed at export time โ the only leverage you have is to find out which ones before you pay.


