The scenario
You built the playable once, in Unity, and Playworks/Luna exported it as a ZIP — typically dropped somewhere like ProjectRoot\LunaTemp\stage4\create-hub. It runs fine in a browser. Now the media buy calls for it to run on Google Ads, Meta, AppLovin, and maybe Mintegral or TikTok too, in the same campaign window. The export you have doesn't natively satisfy any one of those networks' submission rules — it satisfies none of them, because none of them agree with each other on what a compliant creative even looks like.
Why hand-rebuilding it per network is genuinely painful
This isn't busywork you can shortcut by copy-pasting — the specs conflict at a structural level, so the rework is real:
- Different click APIs. Google expects
ExitApi.exit()via its hosted script; AppLovin and Unity Ads expect MRAID'smraid.open(url); Mintegral expectswindow.install()with an MRAID fallback; TikTok expectswindow.openAppStore()from its own Playable SDK; Meta expectsFbPlayableAd.onCTAClick(); Vungle expectswindow.parent.postMessage('download','*'). Wire the wrong one into the wrong network and the CTA silently does nothing — a common cause of a creative getting rejected on review. - ZIP vs. single file. Google, Mintegral, and TikTok expect a ZIP archive. AppLovin, Meta, Unity Ads, and Vungle require the opposite: one self-contained HTML file with every image, sound, and font inlined as data — no external requests, no separate assets, period. The same export can't be both at once; it has to be rebuilt two different ways.
- Different size caps in practice. Every network puts a hard ceiling at 5 MB, but Meta and Unity Ads specifically recommend staying near 2 MB, and Google additionally caps a ZIP at 512 files. A build sized fine for one target can blow past another's limit once its assets are properly embedded rather than loaded on demand.
- Naming and folder rules. Mintegral wants the archive name, top-level folder, and HTML filename to all match. TikTok wants a first-level
index.htmlplus aconfig.jsondeclaring orientation. AppLovin, Meta, Unity, and Vungle each expect their own fixed entry filename.
Doing that correctly once is tedious. Doing it correctly for five networks, then again for the next creative iteration, is where the manual approach stops scaling — and where a small packaging mistake turns into a rejected submission you only find out about after review.
The practical workflow with PlayableKit
PlayableKit doesn't touch how you build the playable — Playworks/Luna still does that part. It picks up at the export step:
- 1
Upload the Luna/Playworks export once. The same ZIP you'd otherwise be hand-editing per network goes in as a single source file for the whole job.
- 2
Select your target networks. Pick from PlayableKit's supported networks — limited to whichever ones your plan actually includes (more on that below).
- 3
Run the conversion. PlayableKit extracts the source once and produces a separately packaged output per selected network — correct click-through wiring, correct asset encoding, correct package shape and naming — from that same extracted build.
- 4
Review the report, then submit. Each job returns pass/fail status, output size, and entry-file details per network, so you know before submission whether a package is actually compliant.
A note on plan-based network access
Which networks you can actually select in step 2 depends on your plan, not just on what the campaign needs. The Starter plan covers four networks — Google Ads, Meta, AppLovin, and Unity Ads. Mintegral, TikTok, and Vungle require Studio, Scale, or Enterprise, which unlock all seven. A build request for a network outside your plan is rejected before conversion even runs, so it's worth checking your target list against your plan before you upload, not after. Full plan-by-network detail is on the multi-network export overview and the pricing page.