版本体系总览
Category
production / 版本体系。节点定位:版本不是单个数字,而是一组按不同节奏演进的构件——先承认这一点,发布体系才可能设计对。production 树总纲。
Definition
游戏项目里的“版本”从来不是一个单独的数字,而是一组同时存在、彼此依赖、却又不按同一节奏变化的构件。客户端包、资源补丁、脚本层、配置表、协议定义、服务端逻辑、运营活动数据,通常都在独立演进。只有先承认这一点,发布体系才有可能被设计对。
很多版本事故之所以难查,不是某个构件本身错了,而是两组原本各自合法的构件组合在一起时失配了。例如旧客户端拉到了新配置,新协议遇到旧资源,热更脚本跑在未准备好的宿主代码上。只要系统继续把版本理解成“当前线上版本”这一个抽象,类似问题就几乎不可能被提前看见。
Problem
长线项目的版本问题像系统问题:客户端包受审核约束、资源和配置要快迭代、协议和服务端要留兼容窗口——绑在一个版本号上,所有变化都走最慢那条路;「当前线上版本」这种说法掩盖了多版本共存的常态,出问题时连「线上到底在跑什么」都答不出。
为什么项目越长线,版本问题越像系统问题
短周期项目有时还能靠“大家一起发、一起切、一起替换”勉强跑起来。但一旦进入长期运营,下面这些现实会把版本问题从发布动作变成系统问题:
- 多端并行和多渠道发行
- 资源、配置和活动需要高频迭代
- 热更新和灰度成为常态
- 平台审核导致客户端包更新天然滞后
- 老玩家和新玩家长期运行在不同构件组合上
这时,如果没有正式的版本模型,团队就只能依赖经验去猜兼容关系,事故会越来越难控制。
一个版本体系真正要回答什么
成熟的版本体系,至少应该能回答四个问题:
- 当前玩家到底运行着哪一组构件
- 这组构件是否在官方支持范围内
- 哪些构件必须同步升级,哪些可以独立升级
- 出问题时能否快速退回上一组稳定组合
注意,这里真正重要的不是版本号形式,而是系统是否具备“可判定性”。如果团队不能明确判断一组构件是否合法,后面的灰度、回滚和兼容都无从谈起。
为什么“当前线上版本”这个说法经常有害
它有害,不是因为这个词不能说,而是因为它掩盖了真实结构。线上通常并不存在一个绝对唯一的版本状态,而是至少会同时存在:
- 不同客户端包版本
- 不同热更层级
- 不同资源清单版本
- 不同配置生效批次
- 不同服务端灰度分组
如果系统仍然只以一个统一版本号来思考问题,很多实际存在的失配和事故路径就会被语言本身掩盖。
更接近现实的版本视角
比较稳妥的做法,是把版本看成“构件组合 + 依赖关系 + 生效时机”的集合:
- 构件组合说明系统由哪些可变部分组成
- 依赖关系说明哪些组合合法,哪些组合不被允许
- 生效时机说明它们何时对玩家真正生效
有了这套视角,很多原本模糊的问题才会清楚起来,例如“某活动是不是要求新资源和新配置同时存在”“某个老包是否还能与当前协议共存”“热更是否覆盖了当前崩溃机型”。
版本体系不是工具替代品
CI/CD、包管理、热更平台、配置平台都很重要,但它们本身不等于版本治理。工具能自动执行流程,却不能替团队定义:
- 版本边界是什么
- 兼容窗口有多长
- 回滚目标是哪一组构件
- 哪些变化可以独立放量
这些判断如果没人明确做,流程再自动化,事故也只会自动发生得更快。
常见误区
最常见的错误,是把版本问题外包给流水线和发布平台,以为有工具就等于有治理。第二类错误,是系统里实际已经存在多种独立版本,却仍然用单一版本号思考兼容和回滚。第三类错误,是只关注“新版本怎么发”,不关注“旧版本怎样继续活着以及何时下线”,结果兼容窗口长期失控。
Used By
版本体系设计(四类构件分开治理);多版本共存期的兼容窗口规划;发布事故复盘(版本口径不清时的归因)。
Related
关系链:构件拆分 → 各自节奏 → 依赖关系显式化 → 组织方式 → 测试难点。下游:四类版本(02)、灰度回滚(03)、协同与平台约束(04)、配置管线(05 与 config 子树)。
Reference
本页为工程经验归纳。