nccgs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/nccgs-accessibility-specialist.md +26 -0
- package/.claude/agents/nccgs-adversarial-reviewer.md +26 -0
- package/.claude/agents/nccgs-ai-programmer.md +26 -0
- package/.claude/agents/nccgs-analytics-engineer.md +26 -0
- package/.claude/agents/nccgs-art-direction-lead.md +26 -0
- package/.claude/agents/nccgs-audio-direction-lead.md +26 -0
- package/.claude/agents/nccgs-creative-director.md +26 -0
- package/.claude/agents/nccgs-documentation-manager.md +26 -0
- package/.claude/agents/nccgs-economy-designer.md +26 -0
- package/.claude/agents/nccgs-engine-programmer.md +26 -0
- package/.claude/agents/nccgs-game-design-lead.md +26 -0
- package/.claude/agents/nccgs-game-designer.md +26 -0
- package/.claude/agents/nccgs-gameplay-programmer.md +26 -0
- package/.claude/agents/nccgs-level-designer.md +26 -0
- package/.claude/agents/nccgs-live-ops-designer.md +26 -0
- package/.claude/agents/nccgs-localization-lead.md +26 -0
- package/.claude/agents/nccgs-narrative-lead.md +26 -0
- package/.claude/agents/nccgs-network-programmer.md +26 -0
- package/.claude/agents/nccgs-performance-analyst.md +26 -0
- package/.claude/agents/nccgs-producer.md +26 -0
- package/.claude/agents/nccgs-production-coordinator.md +23 -0
- package/.claude/agents/nccgs-programming-lead.md +26 -0
- package/.claude/agents/nccgs-prototyper.md +26 -0
- package/.claude/agents/nccgs-qa-engineer.md +26 -0
- package/.claude/agents/nccgs-qa-lead.md +26 -0
- package/.claude/agents/nccgs-release-engineer.md +26 -0
- package/.claude/agents/nccgs-release-lead.md +26 -0
- package/.claude/agents/nccgs-security-engineer.md +26 -0
- package/.claude/agents/nccgs-sound-designer.md +26 -0
- package/.claude/agents/nccgs-systems-designer.md +26 -0
- package/.claude/agents/nccgs-technical-architect.md +26 -0
- package/.claude/agents/nccgs-technical-artist.md +26 -0
- package/.claude/agents/nccgs-technical-director.md +26 -0
- package/.claude/agents/nccgs-tools-programmer.md +26 -0
- package/.claude/agents/nccgs-ui-programmer.md +26 -0
- package/.claude/agents/nccgs-unity-build-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-content-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-implementer.md +26 -0
- package/.claude/agents/nccgs-unity-rendering-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-systems-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-ui-specialist.md +26 -0
- package/.claude/agents/nccgs-ux-designer.md +26 -0
- package/.claude/agents/nccgs-verification-engineer.md +26 -0
- package/.claude/agents/nccgs-world-builder.md +26 -0
- package/.claude/agents/nccgs-writer.md +26 -0
- package/.claude/nccgs/THIRD_PARTY_NOTICES.md +13 -0
- package/.claude/nccgs/VERSION +1 -0
- package/.claude/nccgs/constitution.md +131 -0
- package/.claude/nccgs/hooks/agent-audit.mjs +10 -0
- package/.claude/nccgs/hooks/common.mjs +41 -0
- package/.claude/nccgs/hooks/post-compact.mjs +1 -0
- package/.claude/nccgs/hooks/pre-compact.mjs +8 -0
- package/.claude/nccgs/hooks/protect-git.mjs +22 -0
- package/.claude/nccgs/hooks/protect-write.mjs +17 -0
- package/.claude/nccgs/hooks/session-start.mjs +15 -0
- package/.claude/nccgs/hooks/session-stop.mjs +7 -0
- package/.claude/nccgs/protocols/agent-contract.md +34 -0
- package/.claude/nccgs/protocols/context-packets.md +13 -0
- package/.claude/nccgs/protocols/evidence.md +15 -0
- package/.claude/nccgs/protocols/model-routing.md +22 -0
- package/.claude/nccgs/protocols/orchestration.md +26 -0
- package/.claude/nccgs/protocols/unity-boundary.md +11 -0
- package/.claude/nccgs/settings.fragment.json +77 -0
- package/.claude/nccgs/studio.json +347 -0
- package/.claude/nccgs/tools/configure-models.mjs +39 -0
- package/.claude/nccgs/unity-skills-manifest.json +727 -0
- package/.claude/nccgs/workflow-catalog.json +317 -0
- package/.claude/rules/nccgs-canonical-docs.md +19 -0
- package/.claude/rules/nccgs-editor-tools.md +12 -0
- package/.claude/rules/nccgs-localization.md +12 -0
- package/.claude/rules/nccgs-networking.md +13 -0
- package/.claude/rules/nccgs-performance.md +14 -0
- package/.claude/rules/nccgs-rendering.md +16 -0
- package/.claude/rules/nccgs-security.md +13 -0
- package/.claude/rules/nccgs-tests.md +18 -0
- package/.claude/rules/nccgs-ui.md +14 -0
- package/.claude/rules/nccgs-unity-assets.md +21 -0
- package/.claude/rules/nccgs-unity-code.md +22 -0
- package/.claude/skills/accessibility-review/SKILL.md +14 -0
- package/.claude/skills/architecture-decision/SKILL.md +14 -0
- package/.claude/skills/asset-audit/SKILL.md +14 -0
- package/.claude/skills/audit/SKILL.md +16 -0
- package/.claude/skills/audit/references/dimensions.md +46 -0
- package/.claude/skills/balance-review/SKILL.md +14 -0
- package/.claude/skills/bug-triage/SKILL.md +14 -0
- package/.claude/skills/build-live-game/SKILL.md +317 -0
- package/.claude/skills/build-live-game/references/achievements.md +779 -0
- package/.claude/skills/build-live-game/references/apis.md +280 -0
- package/.claude/skills/build-live-game/references/authentication.md +437 -0
- package/.claude/skills/build-live-game/references/battlepass.md +860 -0
- package/.claude/skills/build-live-game/references/cloud-code.md +563 -0
- package/.claude/skills/build-live-game/references/cloud-save.md +474 -0
- package/.claude/skills/build-live-game/references/deployment.md +216 -0
- package/.claude/skills/build-live-game/references/player-account.md +813 -0
- package/.claude/skills/build-live-game/references/remote-config.md +96 -0
- package/.claude/skills/build-live-game/references/tooling.md +431 -0
- package/.claude/skills/closure/SKILL.md +14 -0
- package/.claude/skills/code-review/SKILL.md +14 -0
- package/.claude/skills/compatibility-review/SKILL.md +14 -0
- package/.claude/skills/context-pack/SKILL.md +14 -0
- package/.claude/skills/dependency-review/SKILL.md +14 -0
- package/.claude/skills/design/SKILL.md +20 -0
- package/.claude/skills/design-review/SKILL.md +14 -0
- package/.claude/skills/evidence-review/SKILL.md +14 -0
- package/.claude/skills/hotfix/SKILL.md +14 -0
- package/.claude/skills/implement-in-app-purchases/README.md +233 -0
- package/.claude/skills/implement-in-app-purchases/SKILL.md +158 -0
- package/.claude/skills/implement-in-app-purchases/references/api-notes.md +562 -0
- package/.claude/skills/implement-in-app-purchases/references/codeless-catalog.md +331 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-adapty.md +268 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-essentialkit.md +239 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-revenuecat.md +275 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-unipay.md +145 -0
- package/.claude/skills/implement-in-app-purchases/references/migration-v4-to-v5.md +204 -0
- package/.claude/skills/implement-in-app-purchases/references/path-add-iap-to-new-project.md +198 -0
- package/.claude/skills/implement-in-app-purchases/references/path-convert-native-google-billing.md +356 -0
- package/.claude/skills/implement-in-app-purchases/references/path-convert-native-storekit.md +446 -0
- package/.claude/skills/implement-in-app-purchases/references/path-implement-iap-d2c.md +680 -0
- package/.claude/skills/implement-in-app-purchases/references/platform-notes.md +204 -0
- package/.claude/skills/implement-in-app-purchases/references/pre-check.md +205 -0
- package/.claude/skills/incident-recovery/SKILL.md +14 -0
- package/.claude/skills/initialize-ai-navigation/SKILL.md +95 -0
- package/.claude/skills/initialize-ai-navigation/references/navigation-system.md +794 -0
- package/.claude/skills/levelplay-unity-integration/CHANGELOG.md +57 -0
- package/.claude/skills/levelplay-unity-integration/README.md +74 -0
- package/.claude/skills/levelplay-unity-integration/SKILL.md +1126 -0
- package/.claude/skills/levelplay-unity-integration/references/banner-api.md +920 -0
- package/.claude/skills/levelplay-unity-integration/references/best-practices.md +536 -0
- package/.claude/skills/levelplay-unity-integration/references/ilrd-api.md +337 -0
- package/.claude/skills/levelplay-unity-integration/references/initialization-api.md +630 -0
- package/.claude/skills/levelplay-unity-integration/references/interstitial-api.md +899 -0
- package/.claude/skills/levelplay-unity-integration/references/ios-setup.md +491 -0
- package/.claude/skills/levelplay-unity-integration/references/migration-sdk-9.md +666 -0
- package/.claude/skills/levelplay-unity-integration/references/privacy-settings.md +608 -0
- package/.claude/skills/levelplay-unity-integration/references/rewarded-api.md +902 -0
- package/.claude/skills/localization/SKILL.md +135 -0
- package/.claude/skills/localization/references/api-notes.md +76 -0
- package/.claude/skills/localization/resources/L10nBatchProcessor.cs +69 -0
- package/.claude/skills/localization/resources/LocalizedFontAsset.cs +18 -0
- package/.claude/skills/localize-game/SKILL.md +14 -0
- package/.claude/skills/migrate-project/SKILL.md +21 -0
- package/.claude/skills/migrate-project/references/procedure.md +63 -0
- package/.claude/skills/milestone-review/SKILL.md +14 -0
- package/.claude/skills/new-unity-project/SKILL.md +179 -0
- package/.claude/skills/optimize-audio/SKILL.md +199 -0
- package/.claude/skills/optimize-audio/resources/audio-import-api.md +146 -0
- package/.claude/skills/optimize-audio/resources/platform-settings.md +48 -0
- package/.claude/skills/optimize-text-mesh-pro/SKILL.md +182 -0
- package/.claude/skills/optimize-web/SKILL.md +393 -0
- package/.claude/skills/optimize-web/resources/WebOptimizer.cs +21 -0
- package/.claude/skills/optimize-web/resources/toktx-examples.sh +11 -0
- package/.claude/skills/performance-audit/SKILL.md +14 -0
- package/.claude/skills/physics-3d-collision/SKILL.md +442 -0
- package/.claude/skills/physics-3d-collision/references/troubleshooting.md +41 -0
- package/.claude/skills/physics-3d-collision/resources/CollisionDebugger.cs +33 -0
- package/.claude/skills/plan-feature/SKILL.md +14 -0
- package/.claude/skills/playtest/SKILL.md +14 -0
- package/.claude/skills/project-stage/SKILL.md +14 -0
- package/.claude/skills/prototype-feature/SKILL.md +14 -0
- package/.claude/skills/qa-plan/SKILL.md +14 -0
- package/.claude/skills/release/SKILL.md +18 -0
- package/.claude/skills/release-readiness/SKILL.md +14 -0
- package/.claude/skills/retrospective/SKILL.md +14 -0
- package/.claude/skills/review/SKILL.md +16 -0
- package/.claude/skills/security-audit/SKILL.md +14 -0
- package/.claude/skills/setup-multiplayer-services/SKILL.md +39 -0
- package/.claude/skills/setup-multiplayer-services/references/dgs-entrypoint.md +79 -0
- package/.claude/skills/setup-multiplayer-services/references/entrypoints.md +213 -0
- package/.claude/skills/setup-multiplayer-services/references/examples.md +33 -0
- package/.claude/skills/setup-multiplayer-services/references/implementation-fit.md +30 -0
- package/.claude/skills/setup-multiplayer-services/references/underlying-services.md +11 -0
- package/.claude/skills/setup-multiplayer-services/references/workflows-prerequisites.md +17 -0
- package/.claude/skills/setup-vivox-voice-chat/SKILL.md +118 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/.env.example +6 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/README.md +101 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/promptfooconfig.yaml +32 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/init-and-login.yaml +76 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/text-chat.yaml +65 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/voice-channels.yaml +74 -0
- package/.claude/skills/setup-vivox-voice-chat/references/events-and-participants.md +79 -0
- package/.claude/skills/setup-vivox-voice-chat/references/init-and-login.md +92 -0
- package/.claude/skills/setup-vivox-voice-chat/references/text-chat.md +93 -0
- package/.claude/skills/setup-vivox-voice-chat/references/troubleshooting.md +47 -0
- package/.claude/skills/setup-vivox-voice-chat/references/voice-channels.md +90 -0
- package/.claude/skills/shader-graph-create-custom-node/SKILL.md +25 -0
- package/.claude/skills/shader-graph-create-custom-node/resources/all_hints.hlsl +182 -0
- package/.claude/skills/sprint-plan/SKILL.md +14 -0
- package/.claude/skills/sprite-editor/SKILL.md +66 -0
- package/.claude/skills/sprite-editor/references/api_reference.md +151 -0
- package/.claude/skills/sprite-editor/references/background.md +112 -0
- package/.claude/skills/sprite-editor/references/templates.md +72 -0
- package/.claude/skills/sprite-editor/scripts/AutomaticSliceTexture.cs +40 -0
- package/.claude/skills/sprite-editor/scripts/GenerateNewSpriteRects.cs +200 -0
- package/.claude/skills/sprite-editor/scripts/GetTextureSourceImageSize.cs +32 -0
- package/.claude/skills/sprite-editor/scripts/GetTextureToSlice.cs +55 -0
- package/.claude/skills/sprite-editor/scripts/GridSliceTexture.cs +40 -0
- package/.claude/skills/sprite-editor/scripts/IsometricSliceTexture.cs +141 -0
- package/.claude/skills/sprite-editor/scripts/README.md +134 -0
- package/.claude/skills/sprite-editor/scripts/SetPivotExample.cs +58 -0
- package/.claude/skills/sprite-editor/scripts/SpriteToPng.cs +88 -0
- package/.claude/skills/status/SKILL.md +16 -0
- package/.claude/skills/story-readiness/SKILL.md +14 -0
- package/.claude/skills/test/SKILL.md +16 -0
- package/.claude/skills/ui/SKILL.md +142 -0
- package/.claude/skills/ui-imgui/SKILL.md +186 -0
- package/.claude/skills/ui-imgui/references/gui-elements.md +156 -0
- package/.claude/skills/ui-imgui/references/templates.md +141 -0
- package/.claude/skills/ui-review/SKILL.md +14 -0
- package/.claude/skills/ui-ugui/SKILL.md +282 -0
- package/.claude/skills/ui-ugui/references/scrollview-setup.md +29 -0
- package/.claude/skills/ui-uitk/SKILL.md +235 -0
- package/.claude/skills/ui-uitk/references/common-issues.md +74 -0
- package/.claude/skills/ui-uitk/references/custom-elements.md +241 -0
- package/.claude/skills/ui-uitk/references/painter2d.md +282 -0
- package/.claude/skills/ui-uitk/references/pointermanipulator-guide.md +94 -0
- package/.claude/skills/ui-uitk/references/svg-icons.md +136 -0
- package/.claude/skills/ui-uitk/references/ui-runtime-binding.md +234 -0
- package/.claude/skills/ui-uitk/references/uss-guide.md +138 -0
- package/.claude/skills/unity-cli/CHANGELOG.md +233 -0
- package/.claude/skills/unity-cli/SECURITY.md +22 -0
- package/.claude/skills/unity-cli/SKILL.md +414 -0
- package/.claude/skills/unity-cli/references/auth-license-cloud.md +146 -0
- package/.claude/skills/unity-cli/references/build-run-test.md +349 -0
- package/.claude/skills/unity-cli/references/collaboration.md +472 -0
- package/.claude/skills/unity-cli/references/config-hub.md +103 -0
- package/.claude/skills/unity-cli/references/diagnostics-maintenance.md +326 -0
- package/.claude/skills/unity-cli/references/editors-install.md +327 -0
- package/.claude/skills/unity-cli/references/integration-advanced.md +472 -0
- package/.claude/skills/unity-cli/references/projects-templates.md +574 -0
- package/.claude/skills/unity-package-management/SKILL.md +304 -0
- package/.claude/skills/unity-package-management/references/select-packages.md +108 -0
- package/.claude/skills/urp-postprocessing/SKILL.md +188 -0
- package/.claude/skills/urp-postprocessing/references/code-templates.md +119 -0
- package/.claude/skills/urp-postprocessing/references/effect-reference.md +86 -0
- package/.claude/skills/validate-urp-render-graph-renderer-feature/SKILL.md +269 -0
- package/.claude/skills/work/SKILL.md +36 -0
- package/.claude/skills/work/references/classification.md +41 -0
- package/.claude/skills/work/references/closure.md +50 -0
- package/.claude/skills/work/references/feature-contracts.md +32 -0
- package/.claude/skills/work/references/verification.md +26 -0
- package/CLAUDE.md +6 -0
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/UPGRADING.md +32 -0
- package/VERSION +1 -0
- package/docs/ARCHITECTURE.md +73 -0
- package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +324 -0
- package/docs/MIGRATION-MATRIX.md +23 -0
- package/docs/PROJECT-POLICY.md +67 -0
- package/docs/WORKFLOWS.md +61 -0
- package/package-assets/setup-vivox-voice-chat-evals.gitignore +7 -0
- package/package.json +41 -0
- package/scaffold/.nccgs/bugs/.gitkeep +1 -0
- package/scaffold/.nccgs/closures/.gitkeep +1 -0
- package/scaffold/.nccgs/context/.gitkeep +1 -0
- package/scaffold/.nccgs/decisions/.gitkeep +1 -0
- package/scaffold/.nccgs/evidence/.gitkeep +1 -0
- package/scaffold/.nccgs/features/.gitkeep +1 -0
- package/scaffold/.nccgs/migrations/.gitkeep +1 -0
- package/scaffold/.nccgs/playtests/.gitkeep +1 -0
- package/scaffold/.nccgs/project.yaml +103 -0
- package/scaffold/.nccgs/requirements.yaml +10 -0
- package/scaffold/.nccgs/reviews/.gitkeep +1 -0
- package/scaffold/.nccgs/state.md +40 -0
- package/scaffold/.nccgs/templates/agent-handoff.md +25 -0
- package/scaffold/.nccgs/templates/architecture-decision.md +27 -0
- package/scaffold/.nccgs/templates/closure-record.md +51 -0
- package/scaffold/.nccgs/templates/context-packet.yaml +17 -0
- package/scaffold/.nccgs/templates/evidence-record.md +23 -0
- package/scaffold/.nccgs/templates/feature-contract.md +35 -0
- package/scaffold/.nccgs/templates/migration-plan.md +40 -0
- package/scaffold/.nccgs/templates/waiver.md +11 -0
- package/scripts/cli.mjs +56 -0
- package/scripts/install.mjs +267 -0
- package/scripts/sync-unity-skills.mjs +126 -0
- package/scripts/validate.mjs +205 -0
- package/tests/framework.test.mjs +121 -0
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
# LevelPlay Ad Unit Implementation Best Practices
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- [Overview](#overview)
|
|
5
|
+
- [Strategic Framework: Revenue vs UX Optimization](#strategic-framework-revenue-vs-ux-optimization)
|
|
6
|
+
- [Ad Format Strategy by Goal](#ad-format-strategy-by-goal)
|
|
7
|
+
- [Placement Strategy](#placement-strategy)
|
|
8
|
+
- [Implementation Patterns](#implementation-patterns)
|
|
9
|
+
- [Frequency Management](#frequency-management)
|
|
10
|
+
- [Error Handling and Graceful Degradation](#error-handling-and-graceful-degradation)
|
|
11
|
+
- [A/B Testing Considerations](#ab-testing-considerations)
|
|
12
|
+
- [Common Mistakes to Avoid](#common-mistakes-to-avoid)
|
|
13
|
+
- [Platform-Specific Considerations](#platform-specific-considerations)
|
|
14
|
+
- [Success Metrics by Strategy](#success-metrics-by-strategy)
|
|
15
|
+
- [Final Recommendations](#final-recommendations)
|
|
16
|
+
|
|
17
|
+
## Overview
|
|
18
|
+
|
|
19
|
+
This reference compiles best practices from the LevelPlay enablement playbook, covering strategy selection, placement optimization, and common implementation patterns that drive both revenue and user satisfaction.
|
|
20
|
+
|
|
21
|
+
## Strategic Framework: Revenue vs UX Optimization
|
|
22
|
+
|
|
23
|
+
### Understanding the Trade-off
|
|
24
|
+
|
|
25
|
+
Every ad implementation involves a fundamental trade-off between revenue generation and user experience. Your optimization goal should guide every decision.
|
|
26
|
+
|
|
27
|
+
| Optimization Goal | Philosophy | Typical Outcome |
|
|
28
|
+
|-------------------|------------|-----------------|
|
|
29
|
+
| **Revenue-Focused** | Maximize impression opportunities | Higher revenue, potential UX impact |
|
|
30
|
+
| **UX-Focused** | Protect user experience at all costs | Better retention, lower short-term revenue |
|
|
31
|
+
| **Balanced** | Optimize for sustainable long-term value | Moderate revenue with good UX |
|
|
32
|
+
|
|
33
|
+
### Choosing Your Optimization Goal
|
|
34
|
+
|
|
35
|
+
**Ask yourself:**
|
|
36
|
+
1. What stage is your app in? (Early = UX focus, Mature = revenue optimization)
|
|
37
|
+
2. What's your business model? (Ads-only = revenue, Hybrid = balanced)
|
|
38
|
+
3. What's your competitive landscape? (High competition = UX focus)
|
|
39
|
+
4. What are your user expectations? (Casual games = more ads tolerated)
|
|
40
|
+
|
|
41
|
+
## Ad Format Strategy by Goal
|
|
42
|
+
|
|
43
|
+
### Revenue-Focused Implementation
|
|
44
|
+
|
|
45
|
+
**Goal**: Maximize ad revenue and impression opportunities
|
|
46
|
+
|
|
47
|
+
**Rewarded Ads** (Primary):
|
|
48
|
+
- Implement 3-5 placements across high-value moments
|
|
49
|
+
- Examples: Hints, extra lives, power-ups, bonus currency, skip levels
|
|
50
|
+
- Always keep a rewarded ad loaded and ready
|
|
51
|
+
- Reload immediately after showing
|
|
52
|
+
|
|
53
|
+
**Interstitial Ads** (Secondary):
|
|
54
|
+
- Show at every natural transition point
|
|
55
|
+
- Frequency cap: Every 3-5 minutes of active gameplay
|
|
56
|
+
- Placements: Level complete, game over, returning to menu
|
|
57
|
+
- Load proactively before transitions
|
|
58
|
+
|
|
59
|
+
**Banner Ads** (Tertiary):
|
|
60
|
+
- Show persistently during gameplay
|
|
61
|
+
- Position: Bottom (less intrusive than top)
|
|
62
|
+
- Keep loaded throughout session for continuous impressions
|
|
63
|
+
- Accept some visual clutter for revenue
|
|
64
|
+
|
|
65
|
+
**Expected Outcomes:** *(Industry benchmarks, not LevelPlay-specific)*
|
|
66
|
+
- ✅ 30-50% higher ad revenue
|
|
67
|
+
- ⚠ 5-15% increase in early abandonment
|
|
68
|
+
- ⚠ Lower user satisfaction scores
|
|
69
|
+
- ✅ Strong monetization from engaged users
|
|
70
|
+
|
|
71
|
+
### UX-Focused Implementation
|
|
72
|
+
|
|
73
|
+
**Goal**: Maintain excellent user experience while monetizing thoughtfully
|
|
74
|
+
|
|
75
|
+
**Rewarded Ads** (Only or Primary):
|
|
76
|
+
- Single placement or 2 maximum
|
|
77
|
+
- User-initiated only (player chooses to watch)
|
|
78
|
+
- High-value rewards that feel generous
|
|
79
|
+
- Never force ads
|
|
80
|
+
|
|
81
|
+
**Interstitial Ads** (Optional, Rare):
|
|
82
|
+
- Only at major session boundaries (returning to menu, closing app)
|
|
83
|
+
- Frequency cap: 10+ minutes or once per session
|
|
84
|
+
- Skip during active gameplay entirely
|
|
85
|
+
|
|
86
|
+
**Banner Ads** (Avoid or Minimize):
|
|
87
|
+
- Show only in menus, never during gameplay
|
|
88
|
+
- If used, small sizes (standard 320x50, not rectangles)
|
|
89
|
+
- Hide during any active user engagement
|
|
90
|
+
|
|
91
|
+
**Expected Outcomes:** *(Industry benchmarks, not LevelPlay-specific)*
|
|
92
|
+
- ⚠ 40-60% lower ad revenue vs revenue-focused
|
|
93
|
+
- ✅ Better user retention and satisfaction
|
|
94
|
+
- ✅ Higher organic growth and word-of-mouth
|
|
95
|
+
- ✅ Premium brand perception
|
|
96
|
+
|
|
97
|
+
### Balanced Implementation (Recommended for Most Apps)
|
|
98
|
+
|
|
99
|
+
**Goal**: Sustainable monetization with good user experience
|
|
100
|
+
|
|
101
|
+
**Rewarded Ads** (Primary):
|
|
102
|
+
- 2-3 well-chosen placements
|
|
103
|
+
- Focus on moments of high user engagement
|
|
104
|
+
- Make rewards feel valuable but not exploitative
|
|
105
|
+
- Examples: Extra attempts, time skips, premium currency
|
|
106
|
+
|
|
107
|
+
**Interstitial Ads** (Moderate):
|
|
108
|
+
- Natural transition points only (level complete, game over)
|
|
109
|
+
- Frequency cap: Every 5-7 minutes
|
|
110
|
+
- Never interrupt active gameplay
|
|
111
|
+
- Respect user flow
|
|
112
|
+
|
|
113
|
+
**Banner Ads** (Selective):
|
|
114
|
+
- Show in menus and low-attention moments
|
|
115
|
+
- Hide during intense or immersive gameplay
|
|
116
|
+
- Position at bottom with proper UI offset
|
|
117
|
+
- Rotation: Show/hide based on context
|
|
118
|
+
|
|
119
|
+
**Expected Outcomes:** *(Industry benchmarks, not LevelPlay-specific)*
|
|
120
|
+
- ✅ Strong ad revenue (70-85% of revenue-focused approach)
|
|
121
|
+
- ✅ Good user retention
|
|
122
|
+
- ✅ Sustainable long-term monetization
|
|
123
|
+
- ✅ Positive user sentiment
|
|
124
|
+
|
|
125
|
+
## Placement Strategy
|
|
126
|
+
|
|
127
|
+
### Identifying Strong Placement Moments
|
|
128
|
+
|
|
129
|
+
**High-value moments** (Best for rewarded ads):
|
|
130
|
+
- Post-victory celebrations
|
|
131
|
+
- Level progression milestones
|
|
132
|
+
- Unlock opportunities
|
|
133
|
+
- User feels positive emotion
|
|
134
|
+
|
|
135
|
+
**Natural transitions** (Good for interstitials):
|
|
136
|
+
- Level complete
|
|
137
|
+
- Game over
|
|
138
|
+
- Returning to main menu
|
|
139
|
+
- Session boundaries
|
|
140
|
+
|
|
141
|
+
**Low-attention periods** (Acceptable for banners):
|
|
142
|
+
- Waiting screens
|
|
143
|
+
- Loading periods
|
|
144
|
+
- Menu browsing
|
|
145
|
+
- Non-interactive moments
|
|
146
|
+
|
|
147
|
+
### Placement Anti-Patterns (Avoid These)
|
|
148
|
+
|
|
149
|
+
❌ **Mid-gameplay interruptions**: Never show interstitials during active play
|
|
150
|
+
❌ **Bait-and-switch**: Don't offer rewards then show unrewarded interstitials
|
|
151
|
+
❌ **Excessive frequency**: Showing ads every 1-2 minutes frustrates users
|
|
152
|
+
❌ **Punitive ads**: Using ads as punishment for failure feels manipulative
|
|
153
|
+
❌ **Blocking progression**: Making ads mandatory to continue playing
|
|
154
|
+
❌ **Poor timing**: Showing ads right before key moments or cliffhangers
|
|
155
|
+
|
|
156
|
+
## Implementation Patterns
|
|
157
|
+
|
|
158
|
+
### Pattern 1: Rewarded Hints System
|
|
159
|
+
|
|
160
|
+
**Use case**: Puzzle or strategy games where hints add value
|
|
161
|
+
|
|
162
|
+
```csharp
|
|
163
|
+
public class HintSystem : MonoBehaviour
|
|
164
|
+
{
|
|
165
|
+
[SerializeField] private RewardedAdManager adManager;
|
|
166
|
+
[SerializeField] private int hintsAvailable = 3;
|
|
167
|
+
|
|
168
|
+
public void RequestHint()
|
|
169
|
+
{
|
|
170
|
+
if (hintsAvailable > 0)
|
|
171
|
+
{
|
|
172
|
+
// User has free hints remaining
|
|
173
|
+
UseHint();
|
|
174
|
+
hintsAvailable--;
|
|
175
|
+
}
|
|
176
|
+
else
|
|
177
|
+
{
|
|
178
|
+
// Offer ad-based hint
|
|
179
|
+
if (adManager.IsRewardedAdAvailable())
|
|
180
|
+
{
|
|
181
|
+
ShowHintAdOffer();
|
|
182
|
+
}
|
|
183
|
+
else
|
|
184
|
+
{
|
|
185
|
+
ShowHintNotAvailableMessage();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private void ShowHintAdOffer()
|
|
191
|
+
{
|
|
192
|
+
// Show dialog: "Watch an ad to get a hint?"
|
|
193
|
+
// If user accepts:
|
|
194
|
+
adManager.ShowRewardedAd(OnHintAdCompleted);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private void OnHintAdCompleted(LevelPlayAdInfo adInfo, LevelPlayReward reward)
|
|
198
|
+
{
|
|
199
|
+
if (reward != null && !string.IsNullOrEmpty(reward.Name))
|
|
200
|
+
{
|
|
201
|
+
// User completed ad, grant hint
|
|
202
|
+
UseHint();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
private void UseHint()
|
|
207
|
+
{
|
|
208
|
+
// Show hint to player
|
|
209
|
+
Debug.Log("Showing hint");
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private void ShowHintNotAvailableMessage()
|
|
213
|
+
{
|
|
214
|
+
// Inform user that hints aren't available right now
|
|
215
|
+
Debug.Log("Hints not available at the moment");
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Why this works:**
|
|
221
|
+
- User has free hints first (generous)
|
|
222
|
+
- Ad is optional, not forced
|
|
223
|
+
- Clear value exchange (ad for hint)
|
|
224
|
+
- Graceful handling when ads unavailable
|
|
225
|
+
|
|
226
|
+
### Pattern 2: Level Transition Interstitial (Frequency Capped)
|
|
227
|
+
|
|
228
|
+
**Use case**: Showing interstitials between levels without annoying users
|
|
229
|
+
|
|
230
|
+
```csharp
|
|
231
|
+
public class LevelTransitionAds : MonoBehaviour
|
|
232
|
+
{
|
|
233
|
+
[SerializeField] private InterstitialAdManager adManager;
|
|
234
|
+
private int levelsCompletedSinceAd = 0;
|
|
235
|
+
private int levelsRequiredBetweenAds = 3; // Show ad every 3 levels
|
|
236
|
+
|
|
237
|
+
public void OnLevelComplete()
|
|
238
|
+
{
|
|
239
|
+
levelsCompletedSinceAd++;
|
|
240
|
+
|
|
241
|
+
if (levelsCompletedSinceAd >= levelsRequiredBetweenAds)
|
|
242
|
+
{
|
|
243
|
+
ShowInterstitialOpportunistically();
|
|
244
|
+
levelsCompletedSinceAd = 0;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
ProceedToNextLevel();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
private void ShowInterstitialOpportunistically()
|
|
251
|
+
{
|
|
252
|
+
// Try to show, but don't wait if not ready
|
|
253
|
+
if (adManager.IsInterstitialReady())
|
|
254
|
+
{
|
|
255
|
+
adManager.ShowInterstitialAd();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private void ProceedToNextLevel()
|
|
260
|
+
{
|
|
261
|
+
// Load next level regardless of ad status
|
|
262
|
+
// Never block user flow waiting for ads
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Why this works:**
|
|
268
|
+
- Frequency capping prevents ad fatigue
|
|
269
|
+
- Opportunistic showing (doesn't block if not ready)
|
|
270
|
+
- User flow never interrupted
|
|
271
|
+
- Predictable pattern users can adapt to
|
|
272
|
+
|
|
273
|
+
### Pattern 3: Context-Aware Banner Management
|
|
274
|
+
|
|
275
|
+
**Use case**: Showing banners in menus but hiding during gameplay
|
|
276
|
+
|
|
277
|
+
```csharp
|
|
278
|
+
public class ContextAwareBanners : MonoBehaviour
|
|
279
|
+
{
|
|
280
|
+
[SerializeField] private BannerAdManager bannerManager;
|
|
281
|
+
|
|
282
|
+
public enum AppContext
|
|
283
|
+
{
|
|
284
|
+
MainMenu,
|
|
285
|
+
Playing,
|
|
286
|
+
Paused,
|
|
287
|
+
GameOver
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
private AppContext currentContext;
|
|
291
|
+
|
|
292
|
+
public void SetContext(AppContext newContext)
|
|
293
|
+
{
|
|
294
|
+
currentContext = newContext;
|
|
295
|
+
UpdateBannerVisibility();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
private void UpdateBannerVisibility()
|
|
299
|
+
{
|
|
300
|
+
switch (currentContext)
|
|
301
|
+
{
|
|
302
|
+
case AppContext.MainMenu:
|
|
303
|
+
case AppContext.GameOver:
|
|
304
|
+
// Show banners in menu contexts
|
|
305
|
+
bannerManager.ShowBanner();
|
|
306
|
+
break;
|
|
307
|
+
|
|
308
|
+
case AppContext.Playing:
|
|
309
|
+
// Hide during active gameplay
|
|
310
|
+
bannerManager.HideBanner();
|
|
311
|
+
break;
|
|
312
|
+
|
|
313
|
+
case AppContext.Paused:
|
|
314
|
+
// Optional: Show or hide based on your preference
|
|
315
|
+
// For UX-focused: Hide
|
|
316
|
+
// For revenue-focused: Show
|
|
317
|
+
bannerManager.ShowBanner();
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Why this works:**
|
|
325
|
+
- Banners shown only in appropriate contexts
|
|
326
|
+
- Gameplay experience uninterrupted
|
|
327
|
+
- Easy to adjust strategy by changing visibility logic
|
|
328
|
+
- Clean separation of concerns
|
|
329
|
+
|
|
330
|
+
## Frequency Management
|
|
331
|
+
|
|
332
|
+
### Time-Based Frequency Capping
|
|
333
|
+
|
|
334
|
+
Implement minimum time intervals between ads:
|
|
335
|
+
|
|
336
|
+
```csharp
|
|
337
|
+
public class FrequencyManager : MonoBehaviour
|
|
338
|
+
{
|
|
339
|
+
private float minSecondsBetweenInterstitials = 300f; // 5 minutes
|
|
340
|
+
private float lastInterstitialTime = -300f; // Allow first ad immediately
|
|
341
|
+
|
|
342
|
+
public bool CanShowInterstitial()
|
|
343
|
+
{
|
|
344
|
+
float timeSinceLast = Time.realtimeSinceStartup - lastInterstitialTime;
|
|
345
|
+
return timeSinceLast >= minSecondsBetweenInterstitials;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
public void RecordInterstitialShown()
|
|
349
|
+
{
|
|
350
|
+
lastInterstitialTime = Time.realtimeSinceStartup;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Recommended intervals:**
|
|
356
|
+
- Revenue-focused: 3-5 minutes
|
|
357
|
+
- Balanced: 5-7 minutes
|
|
358
|
+
- UX-focused: 10+ minutes
|
|
359
|
+
|
|
360
|
+
### Count-Based Frequency Capping
|
|
361
|
+
|
|
362
|
+
Implement minimum actions between ads:
|
|
363
|
+
|
|
364
|
+
```csharp
|
|
365
|
+
private int actionsRequiredBetweenAds = 3;
|
|
366
|
+
private int actionsSinceLastAd = 0;
|
|
367
|
+
|
|
368
|
+
public void OnUserAction()
|
|
369
|
+
{
|
|
370
|
+
actionsSinceLastAd++;
|
|
371
|
+
|
|
372
|
+
if (actionsSinceLastAd >= actionsRequiredBetweenAds)
|
|
373
|
+
{
|
|
374
|
+
// Eligible to show ad
|
|
375
|
+
TryShowAd();
|
|
376
|
+
actionsSinceLastAd = 0;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
**Examples of "actions":**
|
|
382
|
+
- Levels completed
|
|
383
|
+
- Games played
|
|
384
|
+
- Sessions started
|
|
385
|
+
- Feature uses
|
|
386
|
+
|
|
387
|
+
## Error Handling and Graceful Degradation
|
|
388
|
+
|
|
389
|
+
### Always Have a Fallback
|
|
390
|
+
|
|
391
|
+
Never let ad failures block user flow:
|
|
392
|
+
|
|
393
|
+
```csharp
|
|
394
|
+
public void OnAdLoadFailed()
|
|
395
|
+
{
|
|
396
|
+
// Log for debugging
|
|
397
|
+
Debug.LogWarning("Ad failed to load");
|
|
398
|
+
|
|
399
|
+
// Continue with user flow
|
|
400
|
+
ProceedWithoutAd();
|
|
401
|
+
|
|
402
|
+
// Schedule retry
|
|
403
|
+
Invoke(nameof(RetryLoadAd), 30f);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private void ProceedWithoutAd()
|
|
407
|
+
{
|
|
408
|
+
// Your app continues normally
|
|
409
|
+
// Never block users because ads aren't available
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Reward Users Even When Ads Fail
|
|
414
|
+
|
|
415
|
+
For rewarded ads, consider granting rewards even if ad fails:
|
|
416
|
+
|
|
417
|
+
```csharp
|
|
418
|
+
public void OnRewardedAdShowFailed()
|
|
419
|
+
{
|
|
420
|
+
// User intended to watch ad, but it failed
|
|
421
|
+
// Consider granting reward anyway (generous approach)
|
|
422
|
+
if (shouldBeGenerousOnFailure)
|
|
423
|
+
{
|
|
424
|
+
GrantReward();
|
|
425
|
+
ShowMessage("Reward granted! (Ad unavailable)");
|
|
426
|
+
}
|
|
427
|
+
else
|
|
428
|
+
{
|
|
429
|
+
ShowMessage("Ad unavailable, please try again later");
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**When to be generous:**
|
|
435
|
+
- UX-focused strategy
|
|
436
|
+
- High-value users
|
|
437
|
+
- Failure is on your end (not user's fault)
|
|
438
|
+
|
|
439
|
+
## A/B Testing Considerations
|
|
440
|
+
|
|
441
|
+
### What to Test
|
|
442
|
+
|
|
443
|
+
**High-impact variables:**
|
|
444
|
+
1. **Frequency caps**: 3min vs 5min vs 7min between interstitials
|
|
445
|
+
2. **Placement timing**: Immediate vs delayed interstitials
|
|
446
|
+
3. **Reward generosity**: 1x vs 2x multiplier for rewarded ads
|
|
447
|
+
4. **Banner visibility**: Always vs context-aware vs never during gameplay
|
|
448
|
+
5. **Interstitial presence**: With vs without interstitials
|
|
449
|
+
|
|
450
|
+
**How to test:**
|
|
451
|
+
- Split users into cohorts
|
|
452
|
+
- Track both revenue AND retention
|
|
453
|
+
- Run tests for 7-14 days minimum
|
|
454
|
+
- Focus on long-term value (LTV), not just day-1 revenue
|
|
455
|
+
|
|
456
|
+
### Metrics to Track
|
|
457
|
+
|
|
458
|
+
**Revenue metrics:**
|
|
459
|
+
- ARPDAU (Average Revenue Per Daily Active User)
|
|
460
|
+
- Impression per DAU
|
|
461
|
+
- eCPM (effective Cost Per Mille)
|
|
462
|
+
|
|
463
|
+
**UX metrics:**
|
|
464
|
+
- D1, D7, D30 retention
|
|
465
|
+
- Session length
|
|
466
|
+
- Session frequency
|
|
467
|
+
- Organic virality (shares, referrals)
|
|
468
|
+
|
|
469
|
+
**Balance metrics:**
|
|
470
|
+
- LTV (Lifetime Value)
|
|
471
|
+
- ARPU / Retention ratio
|
|
472
|
+
- User satisfaction scores
|
|
473
|
+
|
|
474
|
+
## Common Mistakes to Avoid
|
|
475
|
+
|
|
476
|
+
1. **Over-monetizing early**: Don't show tons of ads before users are engaged
|
|
477
|
+
2. **Ignoring retention**: High revenue means nothing if users quit
|
|
478
|
+
3. **Blocking without ads**: Never require watching ads to progress
|
|
479
|
+
4. **Poor frequency capping**: Ads every minute frustrate users
|
|
480
|
+
5. **Forcing rewarded ads**: Rewarded ads should always be optional
|
|
481
|
+
6. **Ignoring load failures**: Always handle ad failures gracefully
|
|
482
|
+
7. **One-size-fits-all**: Different user segments may need different strategies
|
|
483
|
+
8. **Neglecting testing**: Always A/B test major monetization changes
|
|
484
|
+
|
|
485
|
+
## Platform-Specific Considerations
|
|
486
|
+
|
|
487
|
+
### iOS
|
|
488
|
+
- Lower opt-in rates post-ATT (iOS 14.5+)
|
|
489
|
+
- Users who deny tracking see lower-value ads
|
|
490
|
+
- More privacy-conscious user base
|
|
491
|
+
- Consider more UX-focused approach
|
|
492
|
+
|
|
493
|
+
### Android
|
|
494
|
+
- Higher ad fill rates
|
|
495
|
+
- More permissive user expectations
|
|
496
|
+
- Diverse hardware requires testing
|
|
497
|
+
- Can push frequency slightly higher
|
|
498
|
+
|
|
499
|
+
## Success Metrics by Strategy
|
|
500
|
+
|
|
501
|
+
*(Example benchmarks from industry typical ranges, not LevelPlay-specific targets)*
|
|
502
|
+
|
|
503
|
+
### Revenue-Focused Success
|
|
504
|
+
- ARPDAU > $0.15
|
|
505
|
+
- Impression/DAU > 8
|
|
506
|
+
- D7 retention > 20%
|
|
507
|
+
|
|
508
|
+
### UX-Focused Success
|
|
509
|
+
- D7 retention > 35%
|
|
510
|
+
- Session length > 15 minutes
|
|
511
|
+
- Low uninstall rate (<5% weekly)
|
|
512
|
+
- ARPDAU > $0.05
|
|
513
|
+
|
|
514
|
+
### Balanced Success
|
|
515
|
+
- ARPDAU > $0.10
|
|
516
|
+
- D7 retention > 28%
|
|
517
|
+
- Impression/DAU > 5
|
|
518
|
+
- High user satisfaction
|
|
519
|
+
|
|
520
|
+
## Final Recommendations
|
|
521
|
+
|
|
522
|
+
1. **Start UX-focused**: Better to under-monetize early than drive users away
|
|
523
|
+
2. **Increase gradually**: Add monetization as users become engaged
|
|
524
|
+
3. **Always test**: Data beats assumptions
|
|
525
|
+
4. **Watch retention closely**: It's easier to add ads than win back users
|
|
526
|
+
5. **Be transparent**: Users appreciate honesty about ad-supported models
|
|
527
|
+
6. **Reward patience**: Give users free options before pushing ads
|
|
528
|
+
7. **Optimize continuously**: Ad strategy should evolve with your product
|
|
529
|
+
|
|
530
|
+
## Additional Resources
|
|
531
|
+
|
|
532
|
+
For detailed API implementation, see:
|
|
533
|
+
- `rewarded-api.md`: Rewarded ad implementation
|
|
534
|
+
- `interstitial-api.md`: Interstitial ad implementation
|
|
535
|
+
- `banner-api.md`: Banner ad implementation
|
|
536
|
+
- `initialization-api.md`: SDK setup and configuration
|