Files
Commercialization.tapadn/README.md
2026-06-17 15:52:26 +08:00

251 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Commercialization.tapadn
`Commercialization.tapadn` 是 TapADN / Dirichlet 聚合广告平台在 `CC-Framework.Commercialization` 抽象层上的实现包。
## 接入定位
业务项目只需要同时引入:
```json
{
"com.foldcc.cc-framework.commercialization": "http://private.lightyears.ltd:18650/foldcc/CC-Framework.Commercialization.git#1.0.15",
"com.commercialization.tapadn": "http://private.lightyears.ltd:18650/foldcc/Commercialization.tapadn.git?path=/Assets#1.0.5"
}
```
项目层继续面向 `ADManager``ADConfig``AD_Type` 工作,不直接依赖 TapADN SDK API。
## 初始化方式
推荐让本模块创建 controller 并初始化广告管理器:
```csharp
var config = TapadnCommercialization.CreateConfig(
mediaId: "100000",
mediaKey: "media-key",
mediaName: "GameName",
rewardSlotId: "200000",
interstitialSlotId: "200001",
splashSlotId: "200002");
TapadnCommercialization.InitADManager(
onCallback: () => Debug.Log("AD ready"),
userId: userId,
adConfig: config);
```
如项目已有 `ADConfig` 资产,也可以直接调用:
```csharp
ADManager.Instance.Init(callback, userId, adConfig, new TapadnAdController());
```
`ADConfig` 字段约定:
* `Id`: TapADN MediaId。
* `Key`: TapADN MediaKey。
* `Key2`: MediaName。
* `BaseAwardAdKeyValue.value`: 激励视频广告位 SpaceId。
* `BaseInteractionAdKeyValue.value`: 插屏广告位 SpaceId。
* `BaseSplashAdKeyValue.value`: 开屏广告位 SpaceId。
## 配置 key
可通过 `ADConfig.CommonKeyValues``InitADManager(..., args)` 中传入 `IDictionary` 覆盖:
* `tapadn.media_id`
* `tapadn.media_key`
* `tapadn.media_name`
* `tapadn.channel`
* `tapadn.sub_channel`
* `tapadn.debug`
* `tapadn.tap_client_id`
* `tapadn.shake_enabled`
* `tapadn.custom_config_json`
* `tapadn.data_json`
* `tapadn.atags`
* `tapadn.allow_idfa_access`
* `tapadn.request_permission_on_init`
* `tapadn.reward_name`
* `tapadn.reward_amount`
* `tapadn.rewarded_auto_load`
* `tapadn.rewarded_prewarm_on_init`
* `tapadn.rewarded_max_load_attempts`
* `tapadn.rewarded_load_retry_delay_ms`
* `tapadn.rewarded_show_timeout_ms`
* `tapadn.rewarded_scene_slot.<scene_id>`(激励视频场景广告位映射,值为对应 SpaceId
* `tapadn.rewarded_scene_slots`(激励视频场景广告位批量映射,格式 `scene_a=10001,scene_b=10002`
* `tapadn.rewarded_scene_slots_json`(激励视频场景广告位 JSON格式见下方
* `tapadn.rewarded_cache_max_age_seconds`(可选本地缓存年龄上限;默认 `600` 秒,设为 `0` 表示只使用 SDK `IsValid` 判断)
* `tapadn.interstitial_auto_load`
* `tapadn.interstitial_prewarm_on_init`
* `tapadn.interstitial_max_load_attempts`
* `tapadn.interstitial_load_retry_delay_ms`
* `tapadn.interstitial_show_timeout_ms`
* `tapadn.splash_auto_load`
* `tapadn.splash_prewarm_on_init`
* `tapadn.splash_max_load_attempts`
* `tapadn.splash_load_retry_delay_ms`
* `tapadn.splash_show_timeout_ms`
* `tapadn.smart_preload_enabled`(开启智能预加载策略)
* `tapadn.smart_preload_config_json`(智能预加载静态配置 JSON
* `tapadn.smart_preload_config_asset_path`(预加载策略资源表路径,默认 `TapadnSmartLoadPolicy_Default`
* `tapadn.smart_preload_remote_json`(远端覆盖配置 JSON按场景覆盖静态配置
* `tapadn.express_width`
* `tapadn.express_height`
默认激励、插屏、开屏都使用手动 load/show如无特殊策略验证需求不建议开启 auto-ad。若要做 auto-ad AB 测试,再将对应 `*_auto_load` 设为 `true`
### 激励视频场景广告位
激励视频支持按游戏场景路由不同 TapADN SpaceId。项目层继续调用 `ADManager.EnterAdScenario(AD_Type.AwardVideo, sceneId)``ADManager.AsyncPlayAD(AD_Type.AwardVideo, sceneId, callback)`TapADN adapter 会按 `sceneId` 查表:
* 命中 `tapadn.rewarded_scene_slot.<scene_id>` 或批量配置时,使用该场景 SpaceId。
* 未传场景、场景为空、场景未配置、配置的 SpaceId 非法时,回退到 `BaseAwardAdKeyValue.value` 默认激励视频广告位。
* 手动 load/show 模式下,缓存按 SpaceId 隔离A 场景加载的激励视频不会被 B 场景误认为 ready。
单项配置示例:
```csharp
adConfig.CommonKeyValues.Add(new AdKeyValue
{
key = "tapadn.rewarded_scene_slot.level_clear",
value = "200101"
});
```
批量字符串配置示例:
```csharp
adConfig.CommonKeyValues.Add(new AdKeyValue
{
key = "tapadn.rewarded_scene_slots",
value = "level_clear=200101,daily_bonus=200102"
});
```
JSON 配置示例:
```json
{
"Mappings": [
{ "Scene": "level_clear", "SlotId": "200101" },
{ "Scene": "daily_bonus", "SlotId": "200102" }
]
}
```
生命周期策略按官方文档保持保守:
* `DirichletAdNative` 仍由每个 TapADN player 统一持有,不在每个场景重复创建。
* 手动加载返回的 `DirichletRewardVideoAd` 按 SpaceId 缓存展示关闭、展示失败、SDK `IsValid == false` 或超过 `tapadn.rewarded_cache_max_age_seconds` 后销毁。
* 官方文档没有给出固定过期秒数;本模块默认 10 分钟未消费主动销毁,同时每次 ready/show 前仍调用 SDK `IsValid`
* Android auto-ad 仍交给官方 `ShowRewardVideoAutoAd` / `PreLoad` 的 native 缓存管理iOS/Editor fallback 仍是 load 成功后立即 show不承诺 native 缓存语义。
### 智能预加载(实验)
默认会按“场景进入次数 + 场景播放请求次数”维护一个小样本统计:
* 进入场景时记录 `EnterCount`
* `AsyncPlayAD` 执行前调用的 `OnPlayRequestStarted` 记录 `PlayRequestCount`
* 按置信加权算法推算场景播放概率,达到阈值后触发 `ADManager.LoadAD` 预加载
* 预加载归因按“全局广告类型缓存”记录:触发场景记录 `preload_request/success/fail`,实际播放场景记录 `show/immediate/smart_cache_hit`
* 当 A 场景触发的全局缓存在 B 场景展示时A 会记录 `smart_preload_consumed_other_scene`B 会记录 `smart_cache_cross_scene_hit`
配置 JSON 示例(可通过 `CommonKeyValues` 下发):
```json
{
"GlobalDefault": {
"AdType": -1,
"Scene": "__default__",
"BaseProbability": 0.08,
"PreloadThreshold": 0.75,
"CooldownSeconds": 120,
"MinSamplesForConfidence": 8,
"DecayHalfLifeHours": 72
},
"ScenePolicies": [
{
"AdType": 0,
"Scene": "reward_debug",
"BaseProbability": 0.6,
"PreloadThreshold": 0.5,
"CooldownSeconds": 60,
"MinSamplesForConfidence": 4,
"DecayHalfLifeHours": 48
}
]
}
```
说明:
* `AdType` 使用 `AD_Type` 枚举值:`0=AwardVideo`, `1=Splash`, `2=Interaction`
* `Scene` 用于和 `ADManager.EnterAdScenario` 的场景名对齐;场景未命中时回退到对应广告位的默认场景配置。
* `ExportSnapshotCsv()` 会额外导出 `immediate_hit``smart_cache_hit``smart_preload_consumed``smart_preload_expired` 等列,用于区分“哪个场景触发预加载”和“哪个场景最终消费缓存”。
## Android 构建
包内包含官方 `DirichletMediation` SDK、Android AAR、iOS bridge、EDM4U 依赖声明和构建后处理。
维护和升级说明见 `SDK_MAINTENANCE.md`其中记录了官方源码改动清单、Android/iOS/Unity SDK 升级步骤和发布流程。
构建后处理会自动补齐:
* TapADN 所需权限。
* TapADN `TapADFileProvider``tapad_ad_file_path.xml`
* 微信 OpenSDK `WXEntryActivity``queries`、本地 `wechat-sdk-android-6.8.34.aar`
* Pangle `com.pangle.cn:ads-sdk-pro:7.6.1.2` 和 GDT `com.qq.e.union:union:4.690.1560` Maven 依赖。
* `android.useAndroidX=true``android.enableJetifier=true`
包内不默认暴露可视化编辑面板;调试样例通过 `Samples~` 作为可选导入内容。
## iOS 构建
iOS 侧通过 `DirichletMediationIOSPostProcessor` 在 Unity 导出 Xcode 工程后自动处理:
* 生成 `Podfile`,默认接入 `DirichletMediationSDK``DirichletMediationAdapterDRA``DirichletMediationAdapterCSJ``DirichletMediationAdapterGDT` 的 iOS `4.2.0.1` Pod。
* 将 Pods 放到 Unity Framework target避免 adapter 被 strip 后运行时找不到类。
* 补齐 `SKAdNetworkItems``NSUserTrackingUsageDescription``AppTrackingTransparency.framework``AdSupport.framework`
* 执行 `pod install`;若构建机没有 CocoaPods会在日志里给出手动执行路径。
* 将 GDT 的动态 framework 嵌入 App target。
可选覆盖:
* `DIRICHLET_IOS_SDK_VERSION``EditorPrefs("Dirichlet.iOS.SDKVersion")`:临时切换 iOS Pod 版本。
* `DIRICHLET_IOS_ATT_DESCRIPTION``EditorPrefs("Dirichlet.iOS.TrackingUsageDescription")`:替换 ATT 弹窗文案。
* `DIRICHLET_UNITY_FRAMEWORK_TARGET` / `DIRICHLET_UNITY_APP_TARGET`:极端自定义 Xcode target 名称时手动指定。
iOS 的 auto-ad 原生接口仍按官方口径视为 Android 能力;本模块在 iOS 上对激励、插屏、开屏做了“load 成功后立即 show”的兼容 fallback不承诺 native 缓存语义。正式联调仍需要用 TapADN iOS 媒体账号和 iOS 广告位做真机验证重点看初始化、ATT、三类广告 load/show/close/reward 回调,以及无填充/未 ready 的失败收口。
## 智能预加载敏感度验收(默认次留 35%
本模块包含一套本地仿真脚本,用于模拟 IAA 场景下不同 `PreloadThreshold``CooldownSeconds` 的收益差异,输出完整 CSV 与变化曲线。
默认次留基线设置为 `35%`(你可以改保留率列表),默认模型参数位于 `Assets/Tapadn_Adapter/Runtime/Resources/TapadnSmartLoadPolicy_Default.json`
```bash
python Tools/SmartLoadSensitivity/smartload_sensitivity_simulation.py --users 5000 --out-dir Tools/SmartLoadSensitivity/output
```
输出文件(可复现):
* `Tools/SmartLoadSensitivity/output/smartload_sensitivity_summary.csv`
* `Tools/SmartLoadSensitivity/output/smartload_retention_rank.csv`
* `Tools/SmartLoadSensitivity/output/TapADN_智能预加载_敏感度验收报告.md`
* `Tools/SmartLoadSensitivity/output/*.png`(热力图和曲线)
重点图示(`TapADN_智能预加载_敏感度验收报告.md` 中已自动嵌入):
* `heatmap_immediate_r_0.35.png`(次留 35% 下的即时命中率)
* `heatmap_wait_ms_r_0.35.png`(次留 35% 下的平均等待时延)
* `heatmap_waste_ratio_r_0.35.png`(次留 35% 下的 waste 率)
* `line_immediate_vs_retention.png`(留存与即时命中率关系)
* `line_wait_vs_retention.png`(留存与等待时延关系)
你也可以直接查看部分曲线对比:
![Immediate vs retention](Tools/SmartLoadSensitivity/output/line_immediate_vs_retention.png)
![Wait vs retention](Tools/SmartLoadSensitivity/output/line_wait_vs_retention.png)
![Heatmap immediate 35%](Tools/SmartLoadSensitivity/output/heatmap_immediate_r_0.35.png)