CrazyGames Submission Checklist: What I Learned Before Submitting
CrazyGames Submission Checklist: What I Learned Before Submitting
Honesty note: I haven’t submitted to CrazyGames yet — my game (Merge Fish 2048) is still in development, but I integrated their SDK early and built against their documented requirements. This checklist is what I verified against official docs and my own integration so the submission is a formality, not a gamble.
TL;DR
- The technical gates come first: your game must run in an iframe with no external network calls beyond CrazyGames’ own SDK, load fast (small initial payload), and work without their SDK present.
- The SDK’s lifecycle signals matter for placement:
gameLoadingStart/Stop(load time) andhappytime()(satisfaction moments) feed the metrics that decide whether you get featured or buried. - Every rewarded ad needs a non-ad alternative. Reviewers reject games where the only path forward is watching an ad — design the alternative into your game economy.
- Isolate the SDK behind one manager with a simulated fallback so the game is testable pre-approval, demo-able on itch.io, and review-safe. (Full pattern in the SDK comparison.)
The checklist
Technical gates
- Runs in an iframe with zero external calls — no analytics, no raw
fetch, no CDN assets at runtime. Everything must load from the game’s own build. This is the #1 rejection reason (see the marketing guide). - Small initial payload — portals favor fast loads; keeping the build ~1-2 MB gzipped makes you compatible everywhere (see the size guide).
- Works without the SDK — if
window.CrazyGames.SDKis absent, the game must still run (rewards grant after a delay). Reviewers and your own tests run without it. - No file compression tricks — serve standard gzip/brotli-compressed builds with correct headers, not exotic packaging.
- Responsive to different aspect ratios — the portal iframe may be any size; scale your scene, don’t letterbox-crash.
SDK integration (all in one manager)
-
gameLoadingStart()called as early as possible,gameLoadingStop()when the main scene is interactive — this measures your load time. -
happytime()on genuinely satisfying moments (big merges, level-ups) — feeds engagement metrics. - Rewarded ads requested through
requestAd('rewarded', ...)with a busy guard so requests can’t stack (spam detection). - Every SDK call wrapped in try/catch — SDK failure must degrade, not crash.
- Ad requests only after the SDK is ready; never before lifecycle signals.
Game design requirements
- Non-ad alternative for every reward — e.g., a rewarded continue exists, but the game also lets you restart for free; rewarded coins exist, but coins also drop from play. Reviewers check this.
- Muted by default — audio must not autoplay; add an explicit toggle (also a COPPA/privacy consideration, see the privacy template).
- Clear reward feedback — the player must understand what the ad bought them.
- Save data that respects browser storage limits — portal iframes share browser storage; use a namespaced save key and handle quota errors (see the save tutorial).
Business/policy
- Privacy policy URL — CrazyGames requires a hosted privacy policy (use the template).
- Understand the revenue terms — €100 minimum payout (Tipalti monthly), developer share per current official terms (see the monetization guide and realistic earnings).
- No external ad mediation — ads must go through CrazyGames’ SDK, not a third-party ad network.
- No prohibited content — check the portal’s content policy for violence/gambling/adult rules before submitting.
What reviewers actually test (from docs + developer reports)
- The game loads and plays without the SDK present — your simulated mode is what they see first.
- The game doesn’t make network calls beyond the SDK — DevTools network tab.
- Rewarded ads can be declined and the game still progresses (the non-ad alternative).
- Load time — the gameLoading signals and actual boot speed.
- The game restarts cleanly — no state bleed between sessions (another reason to namespace saves).
My integration (what this looks like in code)
The RewardManager pattern covers gates 1-3 in one class: _detectMode() returns 'crazygames' when the SDK exists, 'simulated' otherwise; showRewarded(cb) guards with busy and wraps every SDK call in try/catch; happytime()/gameLoadStart/gameLoadStop are thin wrappers that no-op without the SDK. The game code never touches the SDK directly — which is exactly what makes the submission formality instead of a gamble.
Pitfalls
- Submitting before testing without the SDK — reviewers run it without; your simulated mode must be flawless.
- External calls in the iframe — the top rejection reason; audit your build’s network requests before submitting.
- Reward-only progression — no non-ad path = rejection; design the alternative into the economy, not as a patch.
- Skipping lifecycle signals — hurts placement even if you pass review.
- Ignoring iframe sizing — a game that breaks at 16:9→portrait swap fails the responsive check.
Bottom line
CrazyGames submission is a technical checklist first, a game-quality question second. If your build runs in an iframe with no external calls, loads small, works without the SDK, and gives every reward a non-ad alternative — the review becomes a formality. I built my game against these gates from day one, integrated the SDK behind one manager, and the submission will be the last step, not the risky one. Realistic earnings after approval are in the income breakdown.