上一篇《我用 AI 四天做了 103 个小游戏,还真上架了 TapTap》发出后,不少人问上架细节。 真相是:写游戏 4 天,上架折腾的时间不比写代码少------不过这些活我也全部自动化了。 本文拆解截图、封面、打包、提审四层流水线,以及被拒审 3 次换来的真实教训。
先说结果
截至写这篇文章:
- TapTap 已在线 3 款:《光廊冲刺》《水滴排序》《连连看塔》,搜索名字就能玩
- 游戏合集(免费直接玩):shuangyueliao.github.io/game-arcade...
- 每款游戏的商店素材(图标、横图、截图、描述、zip 包)零人工介入
上架的本质不是"传个包",而是伺候每个平台自己的素材格式。我整理过一张需求矩阵:
| 平台 | 图标/封面 | 截图/横图 | 包体 | 其他 |
|---|---|---|---|---|
| TapTap | 1:1 图标 | 至少 3 张截图 | H5 zip(首包 <5MB) | 隐私政策链接、适龄、AI 内容声明 |
| GameDistribution | 512×384 | 512×512、200×120、1280×720、1280×550 共 5 种 | 根目录必须 index.html | 人工质检 |
| GameMonetize | 512×340 起 | 多尺寸封面 | 根目录 index.html | 后台 iframe 广告验证 |
| 互站 | 350×280 缩略图 | 详情长图 | 源码 zip + 演示站 | 安全码二次校验 |
| 闲鱼 | 750×750 首图 | 可加细节图 | 聊天窗口发文件 | 描述禁 emoji |
同一个游戏,素材要出 5 种封面规格 + 4 种截图规格 + 3 种打包格式。103 个游戏就是上千张图------人肉 P 图必死,所以从第一天的设计里,素材就是流水线的一部分。
第一层:自动截图
游戏画面截图用 headless Chrome,一条命令:
bash
chrome --headless=new --disable-gpu --hide-scrollbars \
--force-device-scale-factor=1 \
--window-size=512,384 \
--screenshot=cover-512-384.png \
"https://shuangyueliao.github.io/game-arcade/tunnel-run/"
三个实测踩坑:
- 最小窗口宽度 500px :Chrome headless 对 window-size 有下限,
--window-size=200,120这类小尺寸会返回裁剪过的图。解法是按目标尺寸截图后用sips/ffmpeg缩放,别硬怼窗口尺寸。 - 截图时机 :游戏是 Canvas 渲染,
--virtual-time-budget=4000让页面先跑 4 秒再截,避开加载白屏。 - 状态多样性 :商店要"玩法中"的截图而不是"开始菜单"。每款游戏我都在代码里留了一个测试钩子(比如
window.__tr暴露分数和状态),截图脚本可以注入一段 JS 让游戏跳到有障碍物、有连击的"好看"状态再截。
第二点展开说:给游戏留自动化钩子不是负担,是上架流水线的基础设施。截图、自动化测试、调试三件事都靠它。
第二层:封面卡是 HTML,不是设计稿
商店封面卡本质是"大字 + 游戏画面 + 价格/卖点",这种东西用 HTML 写比开 PS 快十倍:
html
<div class="stage" style="width:750px;height:750px">
<div class="h1">水滴排序<br><em>液体解谜</em></div>
<div class="feat"><span>300+ 关卡</span><span>零广告打扰</span></div>
<div class="p1">¥0</div>
</div>
写一个封面模板,每款游戏只换三样东西:游戏名、一句卖点、主色。然后还是 headless Chrome 截图,750×750(闲鱼)、512×384(GD)、350×280(互站缩略图)全从一个模板出,只改 CSS。
这样做的额外收益:封面风格天然统一,商店主页看起来像"一个工作室的作品",而不是素材散装。
第三层:打包------一个目录约定解决三个平台
python
game-dir/
index.html ← 全部代码,单文件
(无其他文件)
所有游戏强制单文件:Canvas 程序化画图、WebAudio 现场合成音效、零第三方素材。这个约束带来的打包自由:
- GD/GM :
zip根目录放 index.html 直接传 - TapTap:同样的 zip 直接当 H5 包体
- 互站/闲鱼:同样内容当"源码商品"卖
一个 zip 通吃所有平台,打包脚本只剩"改商店文案 + 换描述"这一件事。
但有个关键细节:平台 SDK 要按域名条件加载。我的每款游戏里有这样一段:
js
if (host.indexOf("gamedistribution") !== -1 || host.indexOf("gd.games") !== -1) {
// 加载 GD SDK
} else {
// 独立运行:零请求、零依赖
}
同一个 zip 在平台域名下自动接 SDK,在 GitHub Pages / 本地就是纯净版。卖源码时买家也不用担心"代码里有没有你的账号 ID"------条件不满足就完全不加载。
第四层:表单提交自动化
发布 103 款 × 5 平台,表单也是体力活。Web 表单的文件上传有个通用解法------DataTransfer 注入:
js
const resp = await fetch(coverUrl);
const blob = await resp.blob();
const dt = new DataTransfer();
dt.items.add(new File([blob], "cover.png", { type: "image/png" }));
input.files = dt.files;
input.dispatchEvent(new Event("change", { bubbles: true }));
但注意:不是所有上传组件都吃这一套 。GameMonetize 用的是 Dropzone.js,合成事件完全无效,最后是绕过组件直接 fetch POST FormData 到它的上传接口才通的。遇到 React antd/MUI 的下拉框也一样,合成事件打不进去,老老实实用坐标点击。
提审被拒 3 次的真实教训
这部分最值钱,都是真金白银的时间换来的:
1. TapTap 首发额度 新游戏首次上线占平台的"首发额度":24 小时内 1 次、168 小时内 3 次。第二次提交被系统挡回来时我才知道这规则。解法:把 3 款游戏的提审时间错开排。
2. 闲鱼商品描述禁 emoji ✔、✅ 这种"清一色"字符直接被拒:"商品描述不能包含 emoji"。全换成 √ 和 ·。
3. 打包商品 vs 单款商品 在互站发"10 款游戏源码打包 ¥30"被人工驳回:"严禁发布多套打包出售"。改成每款游戏单独一个商品才过。反过来,闲鱼就吃打包这套。同一份货,两个平台要用完全相反的商品形态。
另外还有个没走通的渠道也如实说:GameMonetize 的测试对我们这批 AI 生成的小游戏判了"质量不达标",且账号有前科的情况下连坐拒绝。结论就是这渠道暂时放弃,精力转给 TapTap 和源码销售------这也是为什么现在主打 TapTap 三款 + 卖源码两条线。
现在的形态
- 三款 TapTap 在线:搜「光廊冲刺」「水滴排序」「连连看塔」
- 合集(不用下载,点开就玩):shuangyueliao.github.io/game-arcade...
- 下一篇文章写广告 SDK 接入:GD/GM 的 SDK_OPTIONS 静音钩子、CrazyGames 的 1000 游玩广告门槛怎么过
流水线的源码组织和上架清单我整理成了手册,系列文章写完后一并放出来。有问题评论区见。
上一篇:《我用 AI 四天做了 103 个小游戏,还真上架了 TapTap》