What Playworks/Luna actually does — and doesn't

Playworks/Luna builds a working playable from your Unity scene and exports it as a ZIP (on a typical setup, that's ProjectRoot\LunaTemp\stage4\create-hub). That export runs correctly in a browser. What it doesn't do on its own is satisfy every ad network's specific packaging rules at once — Major ad networks each have their own entry-file conventions, size caps, click-through APIs, and (in several cases) a hard requirement that every asset be embedded as base64/base122 data with zero external requests.

That gap is where the actual manual work lives, and it's the same work regardless of which engine or export tool produced the original build.

What adapting a single export for multiple networks actually involves

  • Click-through wiring — Google expects a clickTag variable plus its own ExitApi script; AppLovin and Unity Ads expect an MRAID mraid.open() call; Vungle's primary CTA is window.parent.postMessage('download','*') with MRAID open as a fallback; Mintegral expects window.install(); TikTok expects openAppStore() from its own Playable SDK; Meta expects FbPlayableAd.onCTAClick(). None of these are interchangeable — shipping the wrong one is a common cause of a creative being rejected outright.
  • Asset encoding — AppLovin and Meta require a single self-contained HTML file with zero external requests, which means every image, audio clip, and font has to be inlined as a data URI or an encoded blob decoded at runtime, not referenced by a relative path.
  • Size limits — most networks cap creatives at 5 MB, and a handful specifically recommend staying near 2 MB. A build that's fine for one network can be well over the limit for another once its assets are properly embedded rather than loaded on demand.
  • Package shape — Mintegral specifically wants the archive name, top-level folder, and HTML filename to all match; TikTok wants a first-level index.html plus a config.json declaring orientation; Google wants an orientation meta tag and a flat ZIP under 512 files.

Doing this by hand for one network is tedious but manageable. Doing it correctly for five or six networks from the same source build, every time you ship a new creative, is where teams either build internal tooling or start looking for something else.

Where PlayableKit fits

PlayableKit doesn't replace Playworks/Luna — you still build in Unity exactly as you do today. It picks up right where Playworks/Luna leaves off: upload the same Luna/Playworks export ZIP once, and PlayableKit produces a separately packaged, network-compliant creative for each network you select — clickTag/MRAID/SDK wiring, asset encoding, and package shape all handled per network's actual rules, from that one source build.

StepManual processWith PlayableKit
Click-through API per networkHand-write clickTag / MRAID / SDK calls for each targetApplied automatically per network
Asset embedding (AppLovin, Meta)Manually inline every asset as a data URIAutomatic base64/base122 encoding
Package shape (Mintegral, TikTok)Manually rename files/folders, hand-write config.jsonGenerated to spec automatically
Size/compliance checkUpload and wait for network review to find outFree validator plus a pass/fail report per network before you submit
Worth knowing: if you just want to check whether your current Playworks/Luna export has an obvious structural problem — a missing entry file, a broken inline script, missing engine assets — before doing anything else, PlayableKit's Playable Ad Validator checks that for free with no signup.

Is switching worth the effort?

If you're only ever shipping to one network, probably not — the manual work is a one-time cost per creative. It starts paying off the moment you're maintaining the same creative across three or more networks, or shipping new variants often enough that re-doing the per-network adaptation by hand becomes the actual bottleneck in your release cycle.