Files
Commercialization.tapadn/GLOBAL_DESIGN.md

159 lines
8.5 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 全局设计
## 目标
本模块把 TapADN / Dirichlet 聚合广告 SDK 接到 `CC-Framework.Commercialization` 抽象层后面,让业务项目继续只关心 `ADManager``ADConfig`
当前实现对齐 `Commercialization.topon` 的分层:
* `CC-Framework.Commercialization`: `ADManager``IAdController``ADPlayer` 抽象。
* `Commercialization.tapadn`: 平台 controller、广告播放器、构建自动化。
* `DirichletMediation`: 官方 SDK 和平台桥。
## 目录
* `Assets/DirichletMediation`: 官方聚合 Unity SDK `4.2.5.0`,已删除官方 Sample。
* `Assets/Plugins/Android`: 官方 Android AAR、Manifest、ProGuard、本地微信 OpenSDK AAR。
* `Assets/Plugins/iOS`: iOS Objective-C++ bridge。
* `Assets/Tapadn_Adapter/Runtime/Scripts`: 商业化抽象层适配。
* `Assets/Tapadn_Adapter/Editor`: Android 构建后处理和依赖声明。
* `Assets/DirichletMediation/Editor`: Android Gradle 后处理与 iOS Xcode/CocoaPods 后处理。
* `Assets/Samples~`: 可选调试样例预留,不随主包自动进入业务项目。
## Runtime 设计
`TapadnAdController` 实现 `IAdController`
*`ADConfig` 和可选 `args` 解析 `TapadnControllerOptions`
* 构造 `DirichletAdConfig` 并调用 `DirichletSdk.Init`
* 根据 `AD_Type` 创建 `TapadnAwardVideoPlayer``TapadnInteractionPlayer``TapadnSplashPlayer`
`TapadnCommercialization` 是便捷入口:
* `CreateController()` 隐藏 controller 创建细节。
* `InitADManager(...)` 由模块负责创建 controller 并交给 `ADManager`
* `CreateConfig(...)` 用代码生成临时 `ADConfig`,适合游戏项目不想维护 TapADN SDK 细节时使用。
## 广告播放器
默认方案:优先手动 load/show避免把 `ADManager.AsyncAdPlayer` 的时序语义与 TapADN auto 语义混用。
原因:
* TapADN auto-ad 是官方 Android 场景下的“加载 + 展示合并”调用,不等价于完整场景分发与实时 readiness 能力。
* `ADManager.AsyncAdPlayer` 先做 `IsReadly` 决策,未 ready 则调用 `LoadAD`ready 后再 `ShowAD`,所以手动模式下生命周期和失败收口更稳定。
备选方案:手动 load/show。
* 已通过 `tapadn.rewarded_auto_load=false` 等 key 保留。
* 手动模式保存 SDK 返回的 ad handle并在 `Closed` 时销毁。
不确定点:
* 官方文档说明 auto-ad 目前主要是 Android 能力。本模块在 iOS 对激励、插屏、开屏 auto API 做 load-then-show 兼容 fallback但不承诺 Android native auto 缓存语义;真正 iOS 出包前需要用 TapADN iOS 账号和广告位做真机验证。
* `AD_Type` 抽象层没有 Banner 类型,所以本轮没有将 TapADN Banner 暴露到 `ADManager`。如果抽象层后续新增 Banner可以直接复用官方 `ShowBannerAutoAd`
## 配置设计
基础字段复用 `ADConfig`
* `Id`: MediaId。
* `Key`: MediaKey。
* `Key2`: MediaName。
* `BaseAwardAdKeyValue.value`: 激励视频 SpaceId。
* `BaseInteractionAdKeyValue.value`: 插屏 SpaceId。
* `BaseSplashAdKeyValue.value`: 开屏 SpaceId。
高级配置通过 `CommonKeyValues` 或字典传入,使用 `tapadn.*` 前缀,避免和 TopOn 现有 key 冲突。
## Android 构建设计
保留官方 `DirichletGradlePostProcessor`,它负责 Dirichlet AAR 和 Maven 依赖注入。
新增 `TapadnBuildAndroidProcess`,只负责本模块集成层额外需求:
* TapADN Manifest 权限补齐。
* `com.tapsdk.tapad.internal.TapADFileProvider``@xml/tapad_ad_file_path`
* 微信 OpenSDK 的 `com.tencent.mm` queries 与 `.wxapi.WXEntryActivity`
* AndroidX / Jetifier 开关。
方案选择记录:
* 方案 A只放 `WXDependencies.xml`,依赖宿主 EDM4U 下载微信 SDK。风险是业务项目没有 EDM4U 或未 resolve 时构建失败。
* 方案 B只放本地微信 AAR。风险是宿主 EDM4U 依赖图不可见。
* 当前选择:本地 AAR + `WXDependencies.xml` 同时保留。这样最接近 TopOn 当前工程,也能覆盖无 EDM4U 的构建场景。
## iOS 构建设计
保留 iOS Objective-C++ bridge并通过 `DirichletMediationIOSPostProcessor` 自动生成 Xcode 集成:
* Pod 默认版本为官方 iOS 聚合 SDK `4.2.0.1`,可用 `DIRICHLET_IOS_SDK_VERSION``EditorPrefs("Dirichlet.iOS.SDKVersion")` 覆盖。
* 所有 Dirichlet iOS Pods 放到 Unity Framework target保持 bridge、SDK、adapter 在同一二进制上下文。
* 自动补 `SKAdNetworkItems``NSUserTrackingUsageDescription``AppTrackingTransparency.framework``AdSupport.framework`
* 构建后执行 `pod install`,缺失 CocoaPods 或 Pod 源异常时让 Unity 构建失败,避免产出半配置 Xcode 工程。
* GDT 动态 framework 在 `pod install` 后嵌入 App target。
iOS runtime 桥接负责:
* 初始化时传入 `MediaId``MediaKey``MediaName``gameChannel``shakeEnabled``allowIDFAAccess``aTags`
* `RequestPermissionIfNecessary()` 在 iOS 14+ 请求 ATT。
* 加载/展示激励、插屏、开屏;展示前检查 root view controller 和 `isReady`,失败时回传 `show_error`
## 编辑器可见性
本模块不提供默认可见面板。构建自动化通过 `IPostGenerateGradleAndroidProject` 静默执行;调试能力放入 `Samples~`,由业务项目显式导入。
若后续需要可视化配置面板,应使用宏包裹菜单入口,例如 `COMMERCIALIZATION_TAPADN_DEBUG_MENU`,默认不在业务项目菜单里出现。
## UPM 与本机验证约定
发布包入口是 `Assets/package.json`,其中 `com.foldcc.cc-framework.commercialization` 依赖保持为远程 Git URL
```json
"com.foldcc.cc-framework.commercialization": "http://private.lightyears.ltd:18650/foldcc/CC-Framework.Commercialization.git#1.0.14"
```
当前仓库自身作为 Unity 验证工程时,可以在 `Packages/manifest.json` 使用本地 `file:` 引用:
```json
"com.foldcc.cc-framework.commercialization": "file:CC-Framework.Commercialization/Assets"
```
该路径以 `Packages/manifest.json` 所在目录为基准,符合 Unity 本地 UPM package 规则;`Packages/CC-Framework.Commercialization` 只是本机验证副本,已被 `.gitignore` 排除,不进入发布包。
如果 batchmode 出现 `Failed to resolve packages: The "path" argument must be of type string. Received undefined`,不把它直接归因为 manifest 路径错误,也不使用 `-noUpm` 绕过。处理顺序是保存 Unity Editor log 和 `%LOCALAPPDATA%\Unity\Editor\upm.log`,确认没有并发 Unity/UPM 进程,再用官方 `Unity.exe -batchmode -quit -projectPath <project> -logFile <log>` 做一次只解析 package 的验证;若仍复现,则用 Unity Hub/已打开 Editor 作为 GUI 对照入口继续看 Console 编译错误。
## 策略验收与可视化
模块内置智能预加载策略评估脚本已接入,默认次留验收目标为 `35%`,用于验证 `PreloadThreshold``CooldownSeconds` 在不同留存下的策略敏感度。
验收输出位于:
* `Tools/SmartLoadSensitivity/output/TapADN_智能预加载_敏感度验收报告.md`
* `Tools/SmartLoadSensitivity/output/smartload_sensitivity_summary.csv`
* `Tools/SmartLoadSensitivity/output/smartload_retention_rank.csv`
* `Tools/SmartLoadSensitivity/output/*.png`
推荐复现命令:
```bash
python Tools/SmartLoadSensitivity/smartload_sensitivity_simulation.py --users 5000 --out-dir Tools/SmartLoadSensitivity/output
```
核心对比维度(含 35%次留):
* `threshold` 的下调会提升 `Immediate`,但会抬高 `Waste`
* `cooldown` 拉长可压低 waste、降低重复预加载频次但也会把 show 等待时延上抬。
* 默认策略建议先用 `threshold=0.20~0.40` 做高即时性验证,再通过 waste 上限(如 8%~12%)回退到 `0.35~0.55` 区间。
### 全局缓存归因
`CC-Framework.Commercialization` 当前是一类广告一个全局 `ADPlayer`,场景只是播放与策略标签,不是缓存隔离单位。因此 TapADN 智能预加载按两层口径统计:
* 策略触发层:哪个场景触发了真实 SDK load记录 `preload_request/preload_success/preload_fail`
* 播放消费层:哪个场景实际发起 `AsyncPlayAD` 并展示,记录 `immediate_hit/show_start/smart_cache_hit`
如果 A 场景触发的全局缓存最终在 B 场景展示A 会记录 `smart_preload_consumed_other_scene`B 会记录 `smart_cache_cross_scene_hit`。这不会改变玩家实际体验,只用于避免把“全局缓存命中”误读成“同场景完全自消费”。
验收产物建议每周回放:用最近 7 天留存分布与 fill 成功率替换脚本默认参数,再做一次敏感度重算并对比排名变化。