下载 App
广告位到底怎么才会生效:一个「模拟器能播、上真机全挂」的坑
4 小时前14 浏览综合 包含 AI 合成内容
结论先放:TapTap 制造的官方模拟器能拉起激励视频,不代表你的广告能用;玩家能不能看广告,只取决于你的工程里有没有那份广告位配置。 没配,模拟器一声不响,真机直接全部失败。
适用范围:TapTap 制造(Maker / UrhoX + Lua)接入激励视频广告。本文只讲这条链路,Banner / 插屏 / 开屏不在范围内。
现象:只有我看不到问题
同一台手机、同一个 TapTap 账号:
| 小游戏 | 模拟器 | 真机 |
| A(早就接过广告) | 能拉起 | 能拉起 |
| B(新接的) | 能拉起 | 体力+100、看广告解锁答案,全部提示「广告暂不可用,请稍后重试」 |
B 的代码是照着 A 抄的,连守卫、防重入、防重复发奖都一样。可 B 真机就是一次都没成功过。
更迷惑的是:B 在模拟器里「看起来成功」了——广告能播、能关,甚至播放结束。但看完之后没有任何奖励,界面上只有一行小字说广告不可用。
根因:模拟器根本没用你的广告位
引擎在 WASM 宿主没有暴露广告桥、以及桌面本地运行时,会走到 FakeAd:load 直接同步回调 success = true,show 给一个占位广告,完全不读你的广告位配置。
也就是说,模拟器上的「广告能播」永远成立,跟你的配置一点关系都没有。它是个恒真的假信号。
而真机宿主读的是构建产物里 .project/settings.json 的 @runtime.ad:
B 的这个文件里,@runtime 只有 multiplayer——没有 ad 字段。宿主拿不到广告位,于是每次请求都失败,游戏侧只能降级成一句「广告暂不可用」。
而 A 的这个文件里有 ad,所以真机一直正常。
注意一个反直觉的点:广告位是开发者级的,不是按应用分配的。B 补齐配置后拿到的两组广告位 ID,和 A 一模一样。所以差别从来不是「B 没有广告位」,而是「B 从来没把配置同步进自己的工程」。
为什么会漏:配置有四个副本,没有任何一处会提醒你
| 层 | 在哪 | 谁写 | 谁读 |
| 平台开通状态 | 开发者控制台(广告结算) | 人 | get_ad_config 的 status |
| 云端工作区 | 云端 workspace/.project/settings.json | get_ad_config | 云端构建 |
| 本地工程 | .project/settings.json(要入库) | 云端回写 + merge | 本地预览、下一次构建 |
| 构建产物 | dist/assets/<hash>.json | 构建 | 真机宿主 |
get_ad_config 只写云端,不写本地。于是最典型的一条断链是:
- 开发者根本没跑过 get_ad_config → 云端没配置;
- 或者跑了,但没再跑一次 build → 本地文件没有 ad → 打出来的包还是没有;
- 或者本地有了,但这份源码没进构建 → 产物里还是没有。
这三个断点,模拟器全都测不出来,因为模拟器不看这份文件。
正确接入流程
再补三条 Maker 构建链的固定副作用,别被它们带偏:
- 每次构建都会产生一个空提交 chore: wake maker build server,历史会脏,正常。
- 云端还会追加 [<epoch>] sync at ... 提交,可能把你的 project.json version 顶上去。工程里若有版本对账(比如埋点常量要跟 project.json 对齐),不同步就会红。
- Maker 工程常配双 remote(Maker 源 + 代码镜像),构建只推 Maker 那条,镜像要单独推。
为什么这个坑特别贵
- 模拟器没有任何提示。它不但不报错,还给你一个「成功」的假象。
- 失败发生在最贵的时候:本地全绿、真机自测……如果你恰好没有真机自测的环境,就是发布给玩家之后才炸。
- 它长得像「只有正式版才能看广告」。公测阶段有人跑不通,很容易归因成「等正式上线就好了」。等真上线,问题一模一样地留给玩家——这是最危险的一次误判。
- 失败信息只有一句「广告暂不可用」,从文案上完全看不出是「没配广告位」「播放没看完」「宿主报错」还是「请求被防抖拒了」。
给官方的三条建议
1)模拟器应该内置广告模拟
现在的模拟器只会「成功」。而广告的真实分支至少有五种:完整观看、中途关闭、直接关闭、无填充/加载失败、宿主报错。开发者在本地根本造不出后四种,只能靠真机碰运气。
建议把模拟器的占位广告做成可选结果的组件:
- 看完(发奖)
- 中途退出(不发奖)
- 直接关闭(不发奖)
- 加载失败 / 无填充(给出错误码)
- 宿主不回调(验证防卡死)
官方做一次,所有接入方都省一套。现在只能自己封装:给广告模块注入假宿主,把五种结果跑成用例——能做,但每个团队重复造一遍。
2)广告位配置必须显式、且和「开通广告服务」绑定
必须先在开发者控制台开通广告服务(广告结算),才会有广告位;然后本地代码/工程里也要有这份广告位配置,玩家才看得到广告。公测和正式阶段都依赖它,跟版本阶段无关。
这条建议真实存在的原因:上面的四层副本没有任何一处做交叉校验。工程里没有 @runtime.ad,构建、预览、真机都不会提前拦你。
3)模拟器就该是「配置体检 + 广告模拟」二合一
官方完全可以在这里一次说清两件事:
- 配置到底对不对:没配广告位的工程,普通玩家绝对看不了广告——这句话应该在模拟器里直接展示,而不是等真机。顺带给一句 AI 可执行的接入指引(调哪个工具、传什么参数、配置落到哪个文件、怎么验证)。
- 给你几种模拟结果:配置对了,还要能测错分支;配置不对,就别让你继续往下写。
一个「广告配置:未开通 / 本地未同步 / 产物未包含」的红黄绿灯,价值比一堆文档都高。
4)甚至可以再激进一点,发布给玩家之前如果是非无广游戏应该人工确认
当然,说一千道一万,也只能怪开发者自己学艺不精,多踩踩坑也就经验丰富了。值
给同行的自测清单
真机不能播时,按这个顺序查,别跳、别先怀疑代码:
- git show HEAD:.project/settings.json 里有没有 @runtime.ad.ad_spaces?
- 当前产物里的 settings 载体 JSON 有没有同内容?
- 这份产物是不是最新一次构建?版本号对不对?
- 日志里 AD show path=new|legacy 走哪条?AD WARN load fail code=… message=… 的 code 是什么?
- 后台的广告服务是不是真的开通了?
以及一条纪律:预览能播 = 状态机可用,不等于广告可用。 广告链路的验收只有真机。











