The awkward playable failure is the one that feels impossible: the build is smooth in Chrome, the CTA works, and then the network preview shows a blank frame or the upload never reaches review.
Usually, nobody lied about the local test. It answered the wrong question. A browser proves that the mechanic can run in a friendly web environment. It does not prove that the final artifact matches a particular delivery route, waits for the host correctly, survives an in-app lifecycle, or makes a policy-safe promise.
This preflight is for that last mile. It separates official host requirements from vendor recommendations and from Hookin's own release controls, so a useful safety margin never gets repeated as a platform rule.
Local success proves less than it feels
A development server can quietly provide a missing image. A warm cache can hide a remote font request. An ordinary link can open a store in a desktop browser even though the ad container expects an exit bridge. Desktop graphics support can also rescue a scene that becomes a black rectangle in an older WebView.
Test four surfaces separately: the exported package, the host bridge, the lifecycle, and the visible experience. A pass on one surface is evidence, not a release decision.
Host mandate means the cited platform documentation requires it. Vendor recommendation means the platform advises it but does not present it as a universal acceptance condition. Hookin control means we use it to reduce risk; it is not an ad-network rule.
Six routes, six release contracts
Choose the exact product and delivery route before exporting. The matrix below was last checked on 2026-07-29. A product family name such as “Unity” is not specific enough to select a package or runtime.
| Route | Runtime and package | Requirement status and primary source | Validator or open question | Last verified |
|---|---|---|---|---|
| Google Ads App campaign playable | ZIP, up to 5 MB and 512 files; no required MRAID version is published for this upload route. | Host mandate: arbitrary remote references are restricted, but documented Google Fonts and named Google-hosted libraries are exceptions. Custom HTML can use ExitApi.exit(); Google also recognizes an MRAID-equivalent exit path. Upload specification and troubleshooting. |
The HTML5 validator remains officially linked, but its current end-to-end controls were not exercised. Open questions: official pages differ on 5 MB versus 5.2 MB, so Hookin uses the stricter 5 MB ceiling; Google preview intentionally blocks outbound CTA navigation, so that preview behavior alone is not a failed exit. | 2026-07-29 |
| AppLovin demand creative | One self-contained HTML file, maximum 5 MB, MRAID 2.0, both orientations. | Host mandate: no external calls; timer and audio wait for first interaction; no automatic or first-tap store redirect; CTA uses mraid.open(). Creative specs. |
Vendor recommendation: use the official web preview, then the iOS and Android Preview apps. Open question: the linked Runtime Analysis documentation currently has an ambiguous destination. | 2026-07-29 |
| Unity Ads user-acquisition playable | One file named index.html, all assets inline, under 5 MB, MRAID 3.0, both orientations. |
Host mandate: generally no network requests except a narrow lawful, non-personal analytics allowance; wait for MRAID and viewability; no automatic or first-touch redirect; use mraid.open(). Creative specifications and playable guidance. |
Vendor recommendation: use Unity's Ad Testing app flow. Open question: Unity's moderation checks conflict with the current specification on a 5 MB versus 6 MB ceiling; use the stricter under-5-MB rule. | 2026-07-29 |
| Unity Exchange programmatic playable | Programmatic MRAID 3.0 creative/tag environment; do not inherit the Unity Ads UA uploader contract. | Host mandate: follow the exchange's readiness model and supported-method subset. Unity Exchange playable documentation. | No standalone public creative validator was verified. Confirm transaction-specific package, network, and commercial limits with the buyer or account integration. | 2026-07-29 |
| ironSource Exchange MRAID tag | Raw HTML/JavaScript snippets rather than a full document; MRAID 2.0; maximum 4 MB across downloaded code and assets. | Host mandate: absolute HTTPS assets are allowed, autoplay is expected, mraid.open() handles the CTA, and the host supplies timer and close controls. Vendor recommendation: support both orientations. Exchange specification. |
No standalone public validator was verified. Confirm account or integration-specific tooling; do not submit the Unity Ads UA single-file package by analogy. | 2026-07-29 |
| Meta playable ad | Authenticated account verification required: package shape, limit, external-request policy, CTA bridge, MRAID version, audio, orientation, and lifecycle are unverified. | Status: unverified. The format page and technical help page were login-gated. No precise playable limit is asserted here. | Verify inside Ads Manager with an authorized account using the current create/test help route. Meta's general preview guidance and review guidance do not establish a playable-specific validator. | 2026-07-29 |
The sharpest contrast is worth repeating: Unity Ads UA wants one inlined file and no general network traffic; ironSource Exchange accepts absolute HTTPS assets and a tag-shaped artifact. They are not two names for one exporter.
Read symptoms as leads, not verdicts
A visible failure narrows the search; it rarely proves one cause. Treat each row as a hypothesis to investigate against the frozen artifact.
| Symptom | Investigate first | Evidence to capture |
|---|---|---|
| Rejected before preview | Package topology, bytes, filenames, metadata, or archive integrity | Validator message, artifact listing, and exact file hash |
| Blank or frozen preview | Readiness race, hidden start, missing asset, blocked request, WebGL failure, or console error | Lifecycle trace, console, request log, and fallback result |
| CTA works in Chrome only | Wrong route adapter, host not ready, ineligible gesture, duplicate event, or intentionally blocked preview navigation | Bridge call trace and a real-device destination test |
| Layout crops after rotation | Stale host dimensions, fixed-pixel layout, unsafe edges, or missed size event | Before/after viewport data and screenshots in both directions |
| State jumps after resume | Timers, audio, animation, or physics continued while hidden | Visibility timeline and state snapshot before and after resume |
“The CTA is broken” invites a rewrite. “The MRAID 2.0 adapter emitted two exit calls after pointer-up and click” gives an engineer something testable.
The twelve-point preflight
- Name the route. Record product, placement, OS, orientation, package profile, bridge, and destination. This is a Hookin control; “universal HTML” is not a release target.
- Test the final artifact. Run every check after inlining, minifying, packaging, and metadata injection. Never substitute the development project.
- Enforce the cited package contract. Measure the exact ZIP, HTML file, or downloaded tag total required by that route. A Hookin headroom threshold must be labeled as our safety margin, not the host's maximum.
- Inventory every request. Google has a documented allowlist; AppLovin prohibits external calls; Unity Ads UA has a narrow analytics exception; ironSource Exchange permits absolute HTTPS assets. Apply the selected row, not a universal “offline” rule.
- Complete DOM and host readiness. MRAID hosts can be loading or already ready when code subscribes. Test both arrival orders. This adapter pattern is a Hookin control informed by IAB best practices.
- Obey the route's start rule. Unity Ads UA waits for viewability; ironSource Exchange expects autoplay; AppLovin's timer waits for interaction. “MRAID compliant” does not resolve those differences.
- Exercise the actual exit. Test the selected Exit API or
mraid.open()path on iOS and Android, with a deliberate CTA gesture. As a Hookin control, keep the Meta adapter blocked until the current account-only contract is verified. - Prove audio lifecycle. Test first interaction, mute, hide, close, and resume against the route's rule rather than browser autoplay alone.
- Resize from host dimensions. Load portrait and landscape, rotate during instructions and gameplay, and preserve safe space for host chrome.
- Provide rendering failure behavior. Force unsupported WebGL or context loss and confirm a stable fallback, especially where AppLovin explicitly requires one.
- Review the promise. Compare gameplay, rewards, pricing, branding, and store destination with the actual product. Technical acceptance cannot make a misleading ad representative.
- Validate, hash, and freeze. Run official preview and device paths, record results, hash the artifact, and submit that unchanged file. Hashing and freezing are Hookin controls, not network mandates.
Run the paths nobody demos
The happy path should be the shortest part of QA. Run these negative paths on the exact release build and record an expected outcome before testing:
- Not viewable at launch: gameplay, timers, input, and audible media stay in the route-appropriate state.
- Background and resume: repeated hide/show transitions do not skip progress, duplicate listeners, or restart audio unexpectedly.
- Rapid double tap: pointer and click events produce at most one eligible CTA exit.
- Network loss: self-contained routes still load; routes allowed to fetch assets fail into a coherent state rather than a blank frame.
- Failed CTA: a rejected or unavailable bridge call does not trap the user or corrupt game state.
- Unsupported WebGL: the fallback remains readable and offers only behavior allowed by the route.
- Orientation change: instructions, controls, CTA, and host close area remain usable mid-session.
- Replay: a second run resets state without multiplying timers, audio, telemetry, or event handlers.
- Close state: animation, physics, media, and telemetry stop; the creative never obstructs or imitates host controls.
For MRAID behavior, the IAB compliance creatives are useful fixtures, not a substitute for each network's preview and device environment.
Inspect what leaves the playable
Open the request log and account for every hostname, script, image, font, pixel, and API call. Reject undeclared remote code. Search the built artifact for API keys, tokens, private URLs, environment names, source maps, debug panels, and verbose console output. Client-side secrets are exposed secrets.
Do not collect personal data inside the playable. Treat telemetry as its own reviewed surface: document fields, purpose, destination, retention, consent or lawful basis where relevant, and whether the selected host permits the call. “Anonymous” is a conclusion that needs evidence, not a comforting variable name.
Then inspect the creative as advertising. Confirm that the mechanic and rewards represent the product's actual experience; that trademarks, character likenesses, music, voices, fonts, stock assets, generated assets, and third-party code are rights-cleared; and that the destination is accurate. Policy, privacy, security, and IP review remain separate gates because a valid HTML package proves none of them.
Share the creative core, not the contract
One mechanic can still serve several routes. Keep game state, assets, and measurement-neutral events in a shared core, then build small route adapters for package shape, readiness, visibility, sizing, audio, and exit behavior.
That architecture is a Hookin control. It does not mean one binary is portable everywhere. AppLovin's MRAID 2.0 single HTML, Unity Ads UA's MRAID 3.0 index.html, Unity Exchange's supported-method environment, and ironSource Exchange's MRAID 2.0 tag still need separate exports and separate evidence.
Debounce the exit adapter, normalize duplicate visibility signals, and keep the route identifier inside the release record. When three profiles render correctly and one fails, that boundary gives the investigation a sensible starting point without pretending the adapter is certainly at fault.
Make the handoff reproducible
UA operations should receive more than final-v7-fixed.html. Attach the exact product route, source-document URLs and verification date, export-profile version, artifact hash, compressed and final byte counts, request inventory, orientations and devices tested, CTA destinations, validator results, negative-path evidence, known limitations, and open questions.
If the platform rejects the file, preserve both the artifact and exact message before rebuilding. A fresh export under the same filename destroys the evidence needed to distinguish a packaging defect from a host, account, or policy issue.
Pass two gates, not one
Submission-valid means the selected route accepts the artifact shape and the build survives its technical validation path. It covers bytes, files, runtime, bridge calls, lifecycle, device behavior, and host controls.
Campaign-safe goes further. The creative's promise is representative; measurement is declared; requests and telemetry are permitted; no secrets or personal data leak; assets and claims are rights-cleared; the destination matches; accessibility and player quality have been reviewed; and unresolved account-specific questions are visible to the owner.
These are Hookin release gates, not categories claimed by every host. A playable ships only when both pass. If a Meta technical field still says “account verification required,” or an exchange limit still depends on the buyer integration, that is an open release condition—not a blank to fill with a familiar number from another network.




