前 78 天我们一直在「做游戏」,今天开始「发货」。这两件事的难度完全不在一个维度上:游戏能跑只说明代码对,能不能上架则取决于你能不能让一条可重复的流水线稳定产出安装包。手工点导出按钮的开发者,第一次更新就会开始害怕——因为你不记得上次点了哪些勾。

今天把 Godot 官方导出文档和 Steamworks 的 SteamPipe 上传文档对起来读,串成一条从 Export 按钮到 steamcmd 的最小闭环。

今日速览

  • 导出 = 导出模板 + 导出预设。模板版本必须和编辑器版本一致,否则报 No export template found;预设名(不是平台名)才是命令行里要写的字符串。
  • Steam 不关心你用什么引擎,它只认 depot:一个 depot 就是一份「文件夹快照」,客户端装的就是这些快照拼起来的结果。
  • 上传靠 steamcmd + app_build.vdf + depot_build.vdf 三件套,一行命令搞定,可塞进 CI。
  • SteamPipe 把文件切成约 1 MB 的块做二进制差分,只传变化的块——所以文件顺序稳定比压缩率更重要。
  • 上线顺序永远是:preview 看体积 → 传私有分支自测 → setlive 才真正推给玩家。

一、Godot 侧:把导出变成一条命令

先在 项目 → 导出 里加一个 Windows Desktop 预设,重点改四处:

  1. Export Path:build/windows/MyGame.exe(命令行会覆盖,但预设里必须填,否则 Export All 会跳过)。
  2. Embed PCK:建议开。单 exe 分发最省事,也避免玩家把 pck 删了来问你「为什么黑屏」。
  3. Application → Config → Version:在项目设置里填 0.1.0,将来商店页版本号才对得上。
  4. 导出模板:编辑器 → 管理导出模板 下载与编辑器完全相同的版本。

然后就可以脱离 GUI 了:

# 无头导出,CI 友好
godot --headless --path . \
  --export-release "Windows Desktop" build/windows/MyGame.exe

三个容易踩的点:--headless 在 4.x 才有;预设名带空格要加引号;导出前先 --import 一次,否则新导入的素材可能不在包里。

二、Steam 侧:depot 与两个 VDF

目录先摆清楚,后面全是填空题:

MyGame/
├── build/windows/                 # depot 的内容根(只放要发给玩家的东西)
└── steam/scripts/
    ├── app_build_1234560.vdf      # 应用级:这次要传哪些 depot
    └── depot_build_1234561.vdf    # 仓库级:这个目录里的文件怎么映射

app_build_*.vdf 的关键字段是 appid、desc、buildoutput(日志目录)、contentroot、setlive(留空 = 只上传不上线)、preview(1 = 只算体积不真传),以及 depots 段把 depot 映射到它的 vdf。depot_build_*.vdf 里则是 DepotID、ContentRoot 和 FileMapping(LocalPath "*" + DepotPath "." + recursive 1)。

上传:

steamcmd +login <build_account> \
  +run_app_build ../scripts/app_build_1234560.vdf +quit

强烈建议单独建一个 Steam Build Account,只给它上传权限。用主账号跑 CI,等于把整个商店的后台钥匙挂在构建机上。

三、三个「传上去了但玩家装不到」的真实原因

  • 忘了 setlive:构建成功只是进了 Steam 的候选区,default 分支还指着旧 build。后台 Builds 页面确认一下「当前 build」变了没有。
  • 更新包大得离谱:多半是导出目录里混进了日志、crash dump、上一次的 .pck。SteamPipe 按块差分,文件名或时间戳每次变化就会让整块重传。
  • Content validation failed:depot 里有 0 字节文件、符号链接,或路径带中文。上传前跑一遍 find build -size 0 能省半小时。

🎯 DeepSeek 提示词

提示词 1:生成一键发布脚本

你是一名熟悉 Godot 4 与 Steamworks 的发布工程师。
任务:为我的项目生成一条「导出 + 上传」的发布脚本(bash,Linux CI 可用)。
输入信息:
- 项目路径:/home/me/MyGame
- 导出预设名:Windows Desktop
- 导出目标:build/windows/MyGame.exe
- AppID:1234560;DepotID:1234561
- Steam 构建账号:build_bot
输出要求:
1. 脚本分 4 段并带注释:环境检查(godot/steamcmd 是否存在、版本是否匹配)、清理 build 目录、无头导出、steamcmd 上传。
2. 任一步失败立即 exit 1,并打印可读的错误提示。
3. 上传前自动检测 build 目录中的 0 字节文件与 .log/.dmp 文件,发现则列出并中止。
4. 最后输出一段「本次发布检查清单」,供我人工确认。
约束:不要使用需要交互输入的命令;密码通过环境变量 STEAM_PASSWORD 传入。

提示词 2:生成并审查两个 VDF

你是一名 SteamPipe 配置专家。请根据以下信息生成两个 VDF 文件,并逐字段解释作用。
信息:AppID=1234560,DepotID=1234561,内容根目录=build/windows,
构建日志目录=steam/output,首次上传希望「只上传不自动上线」。
要求:
1. 输出 app_build_1234560.vdf 与 depot_build_1234561.vdf 的完整内容(标准 VDF 缩进格式)。
2. 说明 setlive 留空、preview 设为 1 分别会发生什么。
3. 指出如果我以后要加 macOS 分支,需要新增哪些行、新增哪个 DepotID 占位。
4. 列出 3 个最常见的配置错误及其报错原文。

提示词 3:上传报错诊断

你是 Steamworks 上传排错助手。我会贴一段 steamcmd 或 Godot 的报错日志。
请按以下格式回答:
【报错归类】导出阶段 / VDF 配置 / 内容校验 / 账号权限
【最可能原因】按可能性排序,最多 3 条,每条注明判断依据(引用日志中的关键行)
【修复步骤】可直接执行的命令或后台操作路径
【如何避免复发】一条流程改进建议
约束:只依据我提供的日志推断,信息不足时明确说「需要补充 X」,不要编造 Steamworks 后台不存在的菜单名。
我的日志:
<在此粘贴日志>

学习心得

今天最大的收获是认清一件事:「能玩」和「能发」是两条独立的技术栈。前者靠引擎,后者靠工程纪律。对「用 DeepSeek 从零做一款 Steam 游戏」这个目标来说,这意味着我们不该等到最后才碰导出——第一个可玩原型就应该跑通一次「导出 exe → 上传私有分支 → 从 Steam 客户端装下来玩」的全流程。跑通一次,之后每次更新都只是替换 build 号;不跑通,发售前一周会同时面对引擎 bug 和上传报错,那是最容易崩盘的时刻。

明日关注

  • 在 Godot 里建好 Windows 预设,跑通一次 --headless --export-release
  • 申请 Steam Build Account,把 app_build.vdf 的 preview 设为 1 试算一次体积
  • 检查 build/windows/ 是否混入日志/临时文件,写进 .gitignore

本文由自动化学习流水线每日生成,坚持即学即记。