这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《MMO 服务器开发》8.2 并发修改与事务
同一个背包会被战斗结算、任务奖励、交易行回调同时修改。本节用「副本 + 提交 + 回滚」把一组改动包成事务,用原子指针让读路径完全无锁,并用操作号实现幂等,挡住客户端重发与上游事件重放;配套的 32 goroutine 并发加物用例在 go test -race 下真跑。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
同一个背包会被战斗结算、任务奖励、交易行回调同时修改。本节用「副本 + 提交 + 回滚」把一组改动包成事务,用原子指针让读路径完全无锁,并用操作号实现幂等,挡住客户端重发与上游事件重放;配套的 32 goroutine 并发加物用例在 go test -race 下真跑。
背包最容易被低估的是「一个物品到底是什么」。本节把配置表物品 ID 与背包内实例 ID 拆开,用一套结构同时表达可堆叠与不可堆叠物品,并把堆叠合并、容量预检与「失败即整体不动」的原子性写成一份能跑过的 Go 实现,为 8.2 的并发事务打底。
纯随机会让倒霉的玩家永远倒霉,所以要有保底;纯随机又让客服无法自证清白,所以要有审计。本节在 internal/loot 里加两个部件:硬保底与软保底计数器,以及把每次掉落串成哈希链的审计日志,让整条掉落链路可复算、可追责,并全部用 go test 真跑验证。
本节定稿全卷的随机口径:用 math/rand/v2 的 PCG,为每个实体单独构造 PRNG,种子 = hash(玩家ID, 掉落批次序号),禁止全局 rand。把为什么全局随机源会让结果不可复算讲透,并给出可测的种子推导与重放实现,这是后续所有随机玩法的地基。
掉落是玩法系统的第一个随机点:怪物死了掉什么、掉几个。本节从零写 internal/loot 包,用权重表描述候选物品、在 [Min,Max] 区间取数量,把多次抽取聚合成一次可复算的掉落结算,并附一份能直接 go test 跑过的 L1 测试。
本节给出引擎升级的完整决策链:先判断该不该升,再列差异面清单,用两份 cc.d.ts 做 API 变更核对,按冒烟清单与卷二 13.3 的帧预算做回归验证,最后落到锁 tag、分支与回退方案。文末提供一个纯 TypeScript 的导出符号差异比对器,可在升级前先跑一遍。
本节把引擎定制拆成两条路:不改代码的模块裁剪与改代码的实现级修改。前者讲项目设置里的功能裁剪面板、engine.json 与引擎侧 cc.config.json 的 features 依赖闭包,后者以 2D 框架的 UITransform 源码为例给出改前改后对照,并说明编译、运行时守卫与回退的完整流程。
本节从 GitHub cocos/cocos-engine 的 v3.8.8 tag 拉取源码讲起,覆盖仓库四层目录、native external 第三方库的三种获取方式、Node 与 gulp 依赖安装、编辑器偏好设置里的自定义引擎接入,以及 TypeScript 引擎与原生引擎各自的编译路径和产物 bin 目录,并给出一个可类型检查的运行时版本核对脚本。
全卷收官:把从引擎分层、渲染管线、Effect、光照、物理、动画到内存、原生、定制、架构与跨引擎选型的线索收成一张全景图,按四个部分回顾每条主线解决的问题与交付的能力,给出一段可直接单测的能力矩阵数据结构与一段可类型检查的自检组件,列出继续深入的四条方向与不同读者的下一步,最后回望从「会用」到「懂」这段路。
把跨引擎对照落成可操作的选型方法:先问三个前置问题,再按目标平台、团队栈、包体与 3D 需求走决策树,用一段可直接单测的加权打分逻辑把直觉量化;随后拆解迁移成本的分项口径与参考系数,比较全量重写、逐模块替换、双引擎并存三种策略,并给出一段可类型检查的平台能力探测脚本,最后列出「什么时候不该换引擎」的判断清单。
把前 10 章讲的 Cocos 机制放进横向坐标系:对照 Cocos Creator、Godot、Phaser、Defold 四款引擎在对象模型、脚本语言、2D/3D 侧重、导出目标与生态上的核心差异,给出生命周期、资源加载、合批与物理的逐项对照表,并用一段可类型检查的组件脚本和一段可直接单测的引擎无关状态机,说明横向对照该用在哪、不该用在哪。
规范靠自觉必然失效,必须钉进工具。本节把 ESLint、TypeScript 严格模式与对 cc.d.ts 的类型门禁组成三道静态检查:用 no-restricted-imports 守住 core 不碰引擎、用严格编译项挡住空值与索引越界、用 tsc --noEmit 校验每个 cc 符号,最后给出三道门禁在 CI 里的落点与失败判定。
大工程最先崩的不是性能而是依赖关系。本节把 assets/scripts 的四层职责深化成可强制的依赖方向,讲清 Bundle 与代码模块的对应、平台层如何用接口隔离三端差异,并给出一个纯 TypeScript 的循环依赖扫描器与 vitest 用例,把「core 不许 import cc」这类纪律从口头约定变成会变红的检查。
Cocos 是组件-节点模型而非纯 ECS。本节先把两者的结构差异摆清楚,再划出「数据驱动的纯逻辑层」与「交给引擎的视图层」的边界:用纯 TypeScript 写一个 SoA 结构的数据层并配 vitest 断言,再用一层薄组件把它接回节点与预制体,最后给出该用与不该用的工程判据。
训模型不是默认答案。本节给出一张「何时该训、何时调提示」的成本收益决策清单,把调提示、换模型、加工具、微调、RL 五种干预按成本与收益排开,说清每种手段的前置条件与失效场景;并配一个可运行的决策打分小脚本,对「冷启动无标注」与「有 5k 可验证轨迹」两种场景真跑排序,帮你在动手训之前先算清楚这笔账。
SFT 教会模型「格式」,RL 才教会它「取舍」。本节讲清从监督微调到强化学习的完整流程,聚焦工具使用与多步推理:对比偏好奖励与可验证奖励,说明为什么「工具调用成功、引用可回溯」这类可自动判分的信号特别适合 Agent,并给出一个真跑的离线策略打分例子——给定若干轨迹与奖励函数,算出每条的分数并选出最优。
Agent 的强化学习不是给分类任务换个 loss。本节把 Agent 的多步交互形式化成轨迹(状态、动作、奖励序列),讲清奖励设计与信用分配——到底是哪一步的功劳。配一段可运行的轨迹与奖励数据结构,以及一个按折扣回报做信用归因、再按总回报给轨迹排序的离线小例子,真跑贴输出;全程不训练模型,不编造任何实验曲线。
一次公会战结算要同时做对三件事:命中扣血、判定死亡、发放奖励,而且重复到达的结算请求只能发一次奖。本节给 aegis 从零写战斗结算与防重复发奖:为什么结算和发奖必须分开、迟到的伤害包怎么被死亡状态挡掉、为什么发奖的去重键是业务指纹而不是传输序号,并链回卷一的幂等窗口。
战斗里最容易写崩的两块是技能冷却和 Buff 叠加。本节给 aegis 从零建技能与 Buff 模型:施法为什么拆成请求、前摇、命中三段,技能冷却与公共冷却怎么记,Buff 的刷新与叠层两种策略怎么选、周期伤害怎么按 tick 精确结算,并用真跑的 L1 测试把每条边界钉死。
客户端在多个连接线程里收包,战斗却必须在一个场景线程里按固定顺序结算。本节从零写 aegis 的按帧指令队列:每实体单调序号怎么挡住重试与乱序、排空顺序为什么必须确定、每帧预算怎么把突发流量摊平,并用真跑的 L1 测试与本机实测的投递成本把这几条边界钉死。