4.3 平台能力矩阵与审核红线

包体和加载定完之后,最后一关是平台能力与审核。本节把账号、支付、广告、分享、云存档、录屏、排行榜这八项能力在六个平台上的支持情况写成一份可校验的矩阵,再用一段 S 层脚本断言设计案用到的能力在目标平台都可用,并校验每条审核红线都写下了可执行的缓解措施。

本节目标:把「这个设计要用到哪些平台能力」变成一张可校验的表,在立项阶段就发现能力缺口,而不是等到提审被驳回。

站内那套 46 篇的小程序专题 覆盖的是小程序工程与审核口径——资质、域名、类目、提审流程那一套。本节不复述流程,讲的是小游戏包体与冷启动约束如何反向裁剪玩法与架构的最后一环:玩法设计依赖的平台能力,在目标平台到底给不给。前两节管的是「装不装得下、等不等得起」,这一节管的是「做不做得成」。

前两节把包体压到了限额内、把加载耗时算清楚了。但一个玩法能不能落地,还取决于一件更根本的事:它依赖的平台能力,目标平台有没有。如果《合成小岛》的核心留存设计依赖「分享得体力」,而目标平台的分享能力只支持部分形态,那这个设计从立项那天就是错的。

4.3 平台能力矩阵与审核红线

4.3.1 能力不是「有没有」,是「在哪个平台是什么程度」

先区分两件事:

  • 能力清单——一款小游戏可能用到的平台能力。常用的是八项:账号登录、内购支付、激励视频广告、Banner 广告、分享转发、云存档、录屏/精彩时刻、排行榜。
  • 支持程度——同一项能力,在不同平台上的支持程度并不相同。本节用三级口径描述:full(原生支持,接入即可用)、partial(支持但需额外条件,如资质、审核、白名单、开放域,或能力受限)、none(平台不提供)。

把这两件事交叉起来,就得到一张能力矩阵。它的价值在于把「我以为能用」变成「表上写着能用」——能力缺口是立项阶段最便宜的问题,是提审阶段最贵的问题。

4.3.2 能力矩阵与设计案声明(D 层)

下面这份是 D 层配置:八项能力、六个平台、完整支持矩阵,外加一份设计案声明——目标平台、必选能力、可选能力——以及五条审核红线与它们的缓解措施。

平台支持情况是公开可观察的机制,观察时点 2026-10;full / partial / none 的取值全部是可配置参数,具体以各平台最新文档为准。文中矩阵只用于演示校验流程,不代表任何平台的正式能力清单。

{
  "observation": "平台能力为公开可观察,观察时点 2026-10;support 取值 full/partial/none 是可配置参数,具体以各平台最新文档为准",
  "supportLevels": {
    "full": "平台原生支持,接入即可用",
    "partial": "支持但需额外条件(资质 / 审核 / 白名单 / 开放域),或能力受限",
    "none": "平台不提供该能力"
  },
  "capabilities": [
    {"id": "login", "label": "账号登录"},
    {"id": "pay", "label": "内购支付"},
    {"id": "rewardedAd", "label": "激励视频广告"},
    {"id": "bannerAd", "label": "Banner 广告"},
    {"id": "share", "label": "分享 / 转发"},
    {"id": "cloudSave", "label": "云存档"},
    {"id": "recording", "label": "录屏 / 精彩时刻"},
    {"id": "leaderboard", "label": "排行榜"}
  ],
  "platforms": [
    {"id": "wechat", "label": "微信小游戏"},
    {"id": "douyin", "label": "抖音小游戏"},
    {"id": "kuaishou", "label": "快手小游戏"},
    {"id": "qq", "label": "QQ 小游戏"},
    {"id": "baidu", "label": "百度小游戏"},
    {"id": "alipay", "label": "支付宝小游戏"}
  ],
  "support": {
    "wechat":   {"login": "full", "pay": "full", "rewardedAd": "full", "bannerAd": "full", "share": "partial", "cloudSave": "full", "recording": "none", "leaderboard": "partial"},
    "douyin":   {"login": "full", "pay": "full", "rewardedAd": "full", "bannerAd": "full", "share": "full", "cloudSave": "full", "recording": "full", "leaderboard": "partial"},
    "kuaishou": {"login": "full", "pay": "full", "rewardedAd": "full", "bannerAd": "partial", "share": "full", "cloudSave": "partial", "recording": "full", "leaderboard": "none"},
    "qq":       {"login": "full", "pay": "full", "rewardedAd": "full", "bannerAd": "full", "share": "full", "cloudSave": "full", "recording": "none", "leaderboard": "full"},
    "baidu":    {"login": "full", "pay": "partial", "rewardedAd": "full", "bannerAd": "full", "share": "full", "cloudSave": "partial", "recording": "none", "leaderboard": "none"},
    "alipay":   {"login": "full", "pay": "full", "rewardedAd": "partial", "bannerAd": "partial", "share": "partial", "cloudSave": "full", "recording": "none", "leaderboard": "none"}
  },
  "design": {
    "game": "merge-island",
    "targetPlatforms": ["wechat", "douyin"],
    "requiredCapabilities": ["login", "rewardedAd", "bannerAd", "share", "cloudSave", "leaderboard"],
    "optionalCapabilities": ["pay", "recording"]
  },
  "redlines": [
    {"id": "induce-share", "label": "诱导分享 / 诱导关注", "mitigation": "分享入口不做强制前置,奖励与分享次数解耦"},
    {"id": "minor-protection", "label": "未成年人保护", "mitigation": "接入平台实名与时段限制,不做绕过设计"},
    {"id": "false-ad", "label": "虚假广告与夸大宣传", "mitigation": "广告素材与实际玩法一致,不承诺收益"},
    {"id": "pay-qualification", "label": "无资质收费", "mitigation": "内购走平台代收,资质未过审不放开支付入口"},
    {"id": "lottery-boundary", "label": "随机抽奖与赌博边界", "mitigation": "宝箱概率公示,奖励不可兑换现金"}
  ]
}

requiredCapabilities 是设计案硬依赖——缺一项,玩法就跑不起来;optionalCapabilities 是加分项——缺了只是少一个功能,不影响主流程。这个区分很关键:它决定了校验脚本对缺口的严重程度判定。

4.3.3 断言:设计案用到的能力,目标平台都可用(S 层)

下面这段是 S 层仿真脚本。它读上面那份矩阵,对每个目标平台逐条核对必选能力:遇到 none 记一条 FAIL(硬缺口),遇到 partial 记一条 WARN(可用但需额外条件);可选能力遇到 none 只记 WARN(设计降级即可)。脚本还会校验五条审核红线是否都写了非空的缓解措施。产出 JSON 与 CSV。

#!/usr/bin/env python3
# file: sim/ch04_capability.py
# tier: S
# verify: /opt/homebrew/bin/python3 sim/ch04_capability.py --config config/ --out out/
"""平台能力矩阵校验:设计案用到的能力,在目标平台是否都可用。

读 config/ch04_platform_matrix.json:能力清单 × 平台清单 × 支持矩阵,外加一份设计案
(目标平台 + 必选 / 可选能力)。判定规则:必选能力在某目标平台为 none 即违例;为
partial 记为警告(可用但需额外条件);可选能力为 none 只记录不报警。另外校验每条审核
红线都写了可执行的缓解措施。产出 out/ch04_capability.json + out/ch04_capability.csv。
"""

from __future__ import annotations

import argparse
import csv
import json
import os
import sys

OK, PARTIAL, NONE = "full", "partial", "none"


def load(cfg_dir, name):
    with open(os.path.join(cfg_dir, f"{name}.json"), encoding="utf-8") as f:
        return json.load(f)


def check_design(cfg):
    design = cfg["design"]
    caps = [c["id"] for c in cfg["capabilities"]]
    label = {c["id"]: c["label"] for c in cfg["capabilities"]}
    for cid in design["requiredCapabilities"] + design["optionalCapabilities"]:
        if cid not in caps:
            raise SystemExit(f"设计案引用了未定义的能力:{cid}")

    rows, errors, warns = [], [], []
    for pid in design["targetPlatforms"]:
        sup = cfg["support"][pid]
        for cid in design["requiredCapabilities"]:
            st = sup.get(cid, NONE)
            rows.append({"platform": pid, "capability": cid, "label": label[cid],
                         "level": "required", "support": st})
            if st == NONE:
                errors.append(f"{pid} 缺少必选能力 {label[cid]}")
            elif st == PARTIAL:
                warns.append(f"{pid} 的必选能力 {label[cid]} 仅部分支持,需额外条件")
        for cid in design["optionalCapabilities"]:
            st = sup.get(cid, NONE)
            rows.append({"platform": pid, "capability": cid, "label": label[cid],
                         "level": "optional", "support": st})
            if st == NONE:
                warns.append(f"{pid} 的可选能力 {label[cid]} 不可用,设计需降级")
    return rows, errors, warns


def check_redlines(cfg):
    errors, rows = [], []
    for r in cfg.get("redlines", []):
        mit = (r.get("mitigation") or "").strip()
        rows.append({"id": r["id"], "label": r["label"], "mitigation": mit, "covered": bool(mit)})
        if not mit:
            errors.append(f"审核红线 {r['label']} 未写缓解措施")
    return rows, errors


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--config", default="config/")
    ap.add_argument("--out", default="out/")
    args = ap.parse_args()

    cfg = load(args.config, "ch04_platform_matrix")
    rows, errors, warns = check_design(cfg)
    redlines, red_errors = check_redlines(cfg)
    errors += red_errors
    os.makedirs(args.out, exist_ok=True)

    report = {
        "source": "sim/ch04_capability.py",
        "observation": cfg["observation"],
        "design": cfg["design"],
        "matrix": rows,
        "redlines": redlines,
        "errors": errors,
        "warnings": warns,
        "ok": not errors,
    }
    with open(os.path.join(args.out, "ch04_capability.json"), "w", encoding="utf-8") as f:
        json.dump(report, f, ensure_ascii=False, indent=2)
    with open(os.path.join(args.out, "ch04_capability.csv"), "w", encoding="utf-8", newline="") as f:
        w = csv.writer(f)
        w.writerow(["platform", "capability", "label", "level", "support"])
        for r in rows:
            w.writerow([r["platform"], r["capability"], r["label"], r["level"], r["support"]])

    print(f"design={cfg['design']['game']} platforms={cfg['design']['targetPlatforms']} "
          f"required={len(cfg['design']['requiredCapabilities'])} optional={len(cfg['design']['optionalCapabilities'])}")
    for r in rows:
        if r["support"] != OK:
            print(f"  {r['platform']:>8} {r['label']:<12} level={r['level']:<8} support={r['support']}")
    print(f"redlines={len(redlines)} covered={sum(1 for r in redlines if r['covered'])}")
    for e in errors:
        print(f"FAIL {e}")
    for w_ in warns:
        print(f"WARN {w_}")
    print("== 平台能力:OK" if report["ok"] else "== 平台能力:FAIL")
    return 0 if report["ok"] else 1


if __name__ == "__main__":
    sys.exit(main())

本机实跑输出:

design=merge-island platforms=['wechat', 'douyin'] required=6 optional=2
    wechat 分享 / 转发      level=required support=partial
    wechat 排行榜          level=required support=partial
    wechat 录屏 / 精彩时刻    level=optional support=none
    douyin 排行榜          level=required support=partial
redlines=5 covered=5
WARN wechat 的必选能力 分享 / 转发 仅部分支持,需额外条件
WARN wechat 的必选能力 排行榜 仅部分支持,需额外条件
WARN wechat 的可选能力 录屏 / 精彩时刻 不可用,设计需降级
WARN douyin 的必选能力 排行榜 仅部分支持,需额外条件
== 平台能力:OK

读这份输出:没有 FAIL,但有四条 WARN。含义是「能做,但有两处要改设计」:

  • 微信的分享是 partial。这不代表不能分享,而是分享形态受限——不能做「分享才给奖励」这种强制前置。设计上必须把它降级为「可选加速」:不分享也能玩,分享了能快一点。
  • 微信与抖音的排行榜都是 partial。排行榜通常需要额外条件(如开放数据域或审核)。设计上要有兜底:做不到实时榜就退化成「异步榜」或「好友榜」。
  • 微信的录屏是 none,但它是可选能力,所以只记 WARN。设计上把「精彩时刻」从录屏改成截图分享即可。

再看红线部分:5 条红线全部有缓解措施,covered=5。如果哪条没写,脚本会打一条 FAIL——这就是把「合规」从一句口号变成一条可断言的规则。

脚本的 FAIL 分支也可以验证:把微信的 rewardedAd 从 full 改成 none,再跑一遍,输出会多出一行 FAIL wechat 缺少必选能力 激励视频广告,退出码变成 1。激励视频是《合成小岛》的必选能力(它是主要变现方式),所以这一条会硬失败——这正是矩阵校验要拦住的场景:一个平台的广告能力变了,设计案会在脚本层就报出来,而不是等到买量投放之后才发现赚不到钱。

4.3.4 审核红线:能力「怎么用」的问题

能力矩阵管的是「有没有」,审核红线管的是「怎么用」。同一项能力,用得合规是功能,用得不合规就是违规。本节列出的五条红线:

红线典型踩法缓解措施
诱导分享 / 诱导关注必须分享才能领奖励分享入口不做强制前置,奖励与分享次数解耦
未成年人保护绕过实名与时段限制接入平台实名与时段限制,不做绕过设计
虚假广告与夸大宣传广告素材与实际玩法不符素材与实际玩法一致,不承诺收益
无资质收费资质未过审就放开支付内购走平台代收,未过审不放开支付入口
随机抽奖与赌博边界宝箱概率不公示、奖励可换现金概率公示,奖励不可兑换现金

红线的处理方式和能力缺口不同:能力缺口可以换平台或者砍功能,红线没有协商空间。所以本节把它们写进同一份配置,让脚本一起校验——不是为了自动化审核,而是为了在写设计案的时候就逼自己回答「这条我打算怎么处理」。写不出缓解措施的红线,就是设计案里的一颗雷。

需要说明的是:具体审核标准是平台公开可观察的政策,观察时点 2026-10,会随监管与平台规则变化;本节的五条只是一个最小集合,实际立项要按目标平台的最新审核规范逐条过一遍。真实的审核结果需真实业务环境,命令行不可复现(X)。

4.3.5 能力缺口落到设计上

把矩阵校验的结果翻译成设计动作:

  1. 能力缺口优先改设计,而不是改平台。先问「这个玩法能不能换个不依赖该能力的实现」,再问「要不要换平台」。多数情况下,降级实现比换平台便宜。
  2. partial 要按 none 来设计兜底。partial 意味着「现在能用,但有条件」,而条件可能变。把它当成「随时可能不可用」来设计降级路径,比假设它一直可用安全。
  3. 必选能力清单要写进设计案。它是「这份设计的最小依赖集」,评审时第一件事就是核这张表。

小结

  • 能力矩阵把「这个设计要用到哪些平台能力」变成一张可校验的表;三级口径 full / partial / none 区分支持程度。
  • 设计案要显式声明目标平台 + 必选能力 + 可选能力;必选缺 none 是硬失败,partial 是警告。
  • S 层脚本对每个目标平台逐条断言,本机实跑:无 FAIL、四条 WARN——微信的分享与排行榜是 partial、录屏是 none(可选),抖音的排行榜是 partial;五条审核红线全部有缓解措施。
  • 审核红线管的是「能力怎么用」,没有协商空间;写不出缓解措施的红线就是设计案里的雷。
  • 平台能力与审核标准都是公开可观察机制,观察时点 2026-10;矩阵取值是可配置参数,真实审核结果需真实业务环境,命令行不可复现(X)。

三节下来,平台约束这一章就走完了:包体预算决定能装什么,加载耗时决定玩家等不等,能力矩阵决定能不能做。约束摸清楚之后,第 5 章回到玩家这一侧——我们要服务的到底是谁。

阅读导航:上一节:首包加载与冷启动约束 · 下一节:小游戏用户画像与使用场景 。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「minigame」更多文章

  1. 附录 F:全书公式、参数与数据集索引
  2. 9.3 同意管理与数据出境
  3. 9.2 COPPA 与儿童向游戏的限制