Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions skills/levelplay-unity-integration/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## v0.10.0 — 2026-08-21 — Workflow spine, and a hard install gate

Moves reference material out of `SKILL.md` and makes the SDK install a verified step rather than an assumed one.

**Changed:**
- `SKILL.md` is now the workflow spine only, going from about 1,100 lines to 435. The dependency-resolution, testing-and-validation and troubleshooting material that was inlined in it moves into `references/`. Nothing was dropped; it is read on demand instead. `SKILL.md` is loaded in full on every invocation while a reference file is read only when a step links it, so this is a saving on every run that does not need the detail.
- The reference set grows from nine files to twelve: `dependency-resolution.md`, `testing-and-validation.md` and `troubleshooting.md` are now separate files.

**Added:**
- **A hard install-verification gate at Step 3.** No LevelPlay code is written until `com.unity.services.levelplay` is confirmed present in `Packages/packages-lock.json`, read from the project rather than taken from the Package Manager window or an earlier turn. The package is easy to believe is installed: its display name is **Ads Mediation** while the recorded id is `com.unity.services.levelplay`, two similarly named packages are the wrong ones, and the install prompts for a second package partway through. Code written before the id resolves fails with `CS0246` on every LevelPlay symbol, which reads as a code problem rather than an install problem. The gate also distinguishes "the install never happened" from "Unity has not resolved it yet", because the fix differs.
- The deprecated-APIs section now states explicitly that `SetGDPRConsents(Dictionary)` is **not** deprecated on SDK 9.4.x, where it is the correct call, and only becomes `[Obsolete]` on 9.5.0+. It is kept out of the deprecated list rather than listed with a caveat, so it cannot be read the wrong way round.

## v0.9.0 — 2026-08-17 — SDK 9.x migration support

Adds guided migration to the LevelPlay 9.x SDK and the current Ad Unit (MADU) APIs.
Expand Down
14 changes: 9 additions & 5 deletions skills/levelplay-unity-integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,19 @@ You can jump in at any step. If the Unity package and SDK are already installed,

```
levelplay-unity-integration/
├── SKILL.md # Core skill instructions
├── references/ # Detailed API guides for each ad format
├── SKILL.md # The workflow spine: decisions, checkpoints, questions
├── references/ # Detail read on demand, linked from the step that needs it
│ ├── initialization-api.md
│ ├── rewarded-api.md
│ ├── interstitial-api.md
│ ├── banner-api.md
│ ├── ios-setup.md
│ ├── privacy-settings.md
│ ├── ilrd-api.md
│ ├── initialization-api.md
│ ├── privacy-settings.md
│ ├── ios-setup.md
│ ├── dependency-resolution.md
│ ├── testing-and-validation.md
│ ├── troubleshooting.md
│ ├── migration-sdk-9.md
│ └── best-practices.md
├── CHANGELOG.md
└── README.md
Expand Down
968 changes: 142 additions & 826 deletions skills/levelplay-unity-integration/SKILL.md

Large diffs are not rendered by default.

23 changes: 15 additions & 8 deletions skills/levelplay-unity-integration/references/banner-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ public class BannerAdManager : MonoBehaviour
// Create the banner ad object using constructor
bannerAd = new LevelPlayBannerAd(adUnitId);

// ILRD (SDK 9.5.0+): if impression-revenue tracking is enabled, also subscribe here —
// bannerAd.OnAdImpressionDataReady += OnImpressionDataReady; // see references/ilrd-api.md

// Register event listeners
bannerAd.OnAdLoaded += OnAdLoaded;
bannerAd.OnAdLoadFailed += OnAdLoadFailed;
Expand Down Expand Up @@ -65,6 +68,7 @@ public class BannerAdManager : MonoBehaviour
bannerAd.OnAdExpanded -= OnAdExpanded;
bannerAd.OnAdCollapsed -= OnAdCollapsed;
bannerAd.OnAdLeftApplication -= OnAdLeftApplication;
// ILRD (9.5.0+): bannerAd.OnAdImpressionDataReady -= OnImpressionDataReady;
}

// Destroy banner
Expand Down Expand Up @@ -102,7 +106,7 @@ public class BannerAdManager : MonoBehaviour
// Event Callbacks
private void OnAdLoaded(LevelPlayAdInfo adInfo)
{
Debug.Log("Banner ad loaded");
Debug.Log($"Banner ad loaded - network: {adInfo.AdNetwork}, revenue: ${adInfo.Revenue}");
// Banner is ready, can call ShowAd() if needed
}

Expand All @@ -115,7 +119,7 @@ public class BannerAdManager : MonoBehaviour

private void OnAdDisplayed(LevelPlayAdInfo adInfo)
{
Debug.Log("Banner ad displayed");
Debug.Log($"Banner ad displayed - network: {adInfo.AdNetwork}, placement: {adInfo.PlacementName}");
}

private void OnAdDisplayFailed(LevelPlayAdInfo adInfo, LevelPlayAdError error)
Expand All @@ -127,24 +131,24 @@ public class BannerAdManager : MonoBehaviour

private void OnAdClicked(LevelPlayAdInfo adInfo)
{
Debug.Log("Banner ad clicked");
Debug.Log($"Banner ad clicked - network: {adInfo.AdNetwork}");
}

private void OnAdExpanded(LevelPlayAdInfo adInfo)
{
Debug.Log("Banner ad expanded");
Debug.Log($"Banner ad expanded - network: {adInfo.AdNetwork}");
// Optionally pause game if banner expands to full screen
}

private void OnAdCollapsed(LevelPlayAdInfo adInfo)
{
Debug.Log("Banner ad collapsed");
Debug.Log($"Banner ad collapsed - network: {adInfo.AdNetwork}");
// Resume game if paused
}

private void OnAdLeftApplication(LevelPlayAdInfo adInfo)
{
Debug.Log("Banner ad left application");
Debug.Log($"Banner ad left application - network: {adInfo.AdNetwork}");
}
}
```
Expand Down Expand Up @@ -612,7 +616,7 @@ LevelPlayBannerPosition.Center

All events are properties of the `LevelPlayBannerAd` object.

**Threading:** All ad callbacks run on the Unity main thread, so you can safely call Unity APIs (update UI, access GameObjects, etc.) directly in these callbacks. This is different from the ILRD impression callback (see `references/ilrd-api.md`), which runs on a background thread.
**Threading:** All ad callbacks run on the Unity main thread, so you can safely call Unity APIs (update UI, access GameObjects, etc.) directly in these callbacks. This is different from `LevelPlay.OnImpressionDataReady` which runs on a background thread.

#### `OnAdLoaded`
Fired when a banner ad is loaded.
Expand Down Expand Up @@ -832,11 +836,14 @@ void OnDestroy()
```csharp
void Update()
{
// WRONG - Don't call LoadAd() in Update(); it runs every frame
// WRONG - never call LoadAd() every frame.
// Banners load once and then auto-refresh on their own.
bannerAd.LoadAd();
}
```

**Note:** Banner ads have no `IsAdReady()` method (unlike Rewarded and Interstitial ads) — a banner is ready to show once `OnAdLoaded` fires, so there is nothing to poll for here.

**Why to avoid:** A banner object takes exactly one `LoadAd()` call for its lifetime, whether or not auto-refresh is enabled. New creatives come from auto-refresh (based on your platform settings), and visibility is controlled with `ShowAd()`/`HideAd()` — never by reloading. Banner ads don't throw errors for repeated loads like interstitial/rewarded ads do, but extra `LoadAd()` calls waste resources and can cause unexpected behavior.

**Solution:** Call `LoadAd()` once after creating the banner:
Expand Down
Loading