这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《MMO 服务器开发》18.1 卷一回顾:我们造出了什么
卷一 17 章各造了一件零件,却从没按一条主线串起来看过。本节把帧格式、会话表、路由、时间轮、Actor 邮箱、幂等窗口、同步模型与权威校验按依赖顺序排成一张「零件 → 文件 → 验收方式 → 实测结论」总账,逐章交代它解决了什么问题、留下了什么接口、下一章为什么需要它,并用五条贯穿全卷的伏笔说明这些零件如何拼成一个可裁决的世界。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
卷一 17 章各造了一件零件,却从没按一条主线串起来看过。本节把帧格式、会话表、路由、时间轮、Actor 邮箱、幂等窗口、同步模型与权威校验按依赖顺序排成一张「零件 → 文件 → 验收方式 → 实测结论」总账,逐章交代它解决了什么问题、留下了什么接口、下一章为什么需要它,并用五条贯穿全卷的伏笔说明这些零件如何拼成一个可裁决的世界。
站内没有 k6/wrk,压测器得自己写。本节给出 aegis 自带的机器人客户端:用错峰建连绕开 macOS 的 accept backlog 上限,登录进世界后连发请求、按往返时延汇总 QPS 与 P50/P90/P99,最后交出本机第一组真实承载数字——吞吐天花板约三千消息每秒,以及连接数继续上升后延迟如何塌方。
三个真实客户端连上网关、登录进世界、各自移动,靠一套 AOI 均匀网格做到彼此可见。本节讲清「世界是一个 actor」的事件循环、权威移动的速度校验、以及 AOI 广播只发「集合差」的做法,再用一个 L2 测试与真起三进程的日志证明这条链路确实跑通、瞬移确实被拒。
前 16 章各自造了零件却从没装在一起跑过。本节把 proto、session、router、timing、aoi、world 按依赖顺序装配成可执行文件 aegis,讲清配置结构、启动顺序与优雅关停,并用一次真进程启动与关停日志验证「端口绑定失败即退出」与「SIGTERM 后连接与计数正确收摊」。
加密解决「别人看不懂」,完整性解决「别人改不动」——两者缺一不可。本节给 aegis 的封包加一层 AES-256-GCM 的 Sealer:seq|nonce|密文+tag 的封套、以 seq 作附加认证数据、64 位滑动窗口抗重放,并讲清方向密钥为什么必须由握手密钥材料按标签派生(与 6.3 重连票据呼应)。
连接耗尽靠的不是带宽,而是数量:几十万条只握手、不登录、不发数据的连接就能把接入层拖垮。本节只讲怎么加固自己的服务端——每 IP 连接上限、未登录连接上限、全局上限、握手令牌桶、slowloris 的读写超时兜底与拒绝策略,并用本机 loopback 的几十条连接做真跑验证。
长度字段来自网络,是不可信输入:一个声明「长度 = 4 GiB」的畸形包就能让服务端按声明预分配巨量内存。本节用 Go 原生 testing.F 给 internal/proto 的帧解析写一个 fuzzer,覆盖长度越界、截断、超长与 flags 组合,讲清「解析器必须对任意字节序列都不 panic、不无限分配」,并给出本机 5 秒百万级执行的实测。
主线程为什么是瓶颈、哪些活能挪出去、挪出去要付什么代价。本节讲清 Worker 的数据边界——结构化克隆的复制成本与 Transferable 的零拷贝,用可跑的纯 TS 代码量化两者差异;说明 cc.d.ts 并不导出 Worker,必须走平台全局对象并做特性检测;最后给出分片计算任务与并行化的工程判断。
把《方块冲刺》接一个三方 SDK 的完整链路走一遍:先看 Android/iOS 原生工程里插件该落在哪,再分别写 Java 与 Objective-C 桥接类,然后用 TypeScript 门面包一层平台适配,让业务代码只见接口不见平台;重点讲清原生结果回传给 JS 时的线程约束、回调注册与生命周期坑,最后算一笔插件维护成本的账。
从原生构建产物入手,讲清 Cocos Creator 3.8 在 Android/iOS 上如何把 JS 引擎嵌进 C++ 宿主,JSB 绑定怎样把 cc 的类暴露给脚本层;用 cc.d.ts 实测划出「平台无关 API」与「原生运行时注入对象」的边界,讲对 sys.isNative 与 sys.platform 的用法,量化反射式原生调用的成本,给出下沉原生的工程判断。
卷二 13.3 讲清了帧预算四段与 Profiler 面板怎么开。本节把它升成一个可重复的闭环:采样、定位、修复、验证,每一步给出 cc.d.ts 能证明的 API,并用纯 TS 写一个带分位数的帧时间采样器配 vitest 断言。核心纪律是先量再改、一次只改一处、改完同设备复测。
7.1 说明资源内存在引擎与 GPU 侧、不归 GC 管。本节把这笔账算细:落到 cc.d.ts 里的 PixelFormat 与 gfx.Format 两套枚举,把块压缩对齐与 mipmap 的 1.33 倍写进公式,用纯 TS 写一个可单测的显存计算函数,并给出整包资源预算表与读取真实显存的 API。
卷二 13.2 算过纹理内存、也定了引用计数纪律,但没回答字节到底躺在哪、Asset 从加载到消失经历了什么、GC 何时被触发。本节把 Cocos 运行时内存切成 JS 堆、原生堆与 GPU 显存三块,给出 Asset 生命周期与引用计数的 cc.d.ts 证据,并用纯 TS 写一个对象池加触发式回收模型,配 vitest 断言。
动画的代价分两块:CPU 每帧采样曲线并混合,内存里躺着关键帧数据、烘焙关节纹理与合批图集。本节算清这笔账,讲明采样率、烘焙、图集三者如何互相兑换,用纯 TS 写一个可单测分位数的帧耗时统计器,并给出《方块冲刺》这类项目能直接落地的动画预算清单与排查顺序。
骨骼动画把动画数据从「节点属性」换成「几十上百个关节的变换矩阵」。本节讲清 Skeleton 资源里的 joints 与 bindposes、SkeletalAnimation 的烘焙开关、蒙皮顶点的加权计算,以及蒙皮模型为什么难以合批、SkinnedMeshBatchRenderer 又如何把共享骨骼的模型合并。
Cocos 动画由 AnimationClip 的 track/channel/curve 三层数据驱动,AnimationState 按时间采样并混合出当前姿态。本节拆开整条求值链路:关键帧插值、weight 混合、crossFade 过渡,用纯 TS 写一个可单测的关键帧求值器,并核对事件常量到底挂在哪个类上。
讲清 Cocos 2D 物理的主动查询与自定义碰撞响应:用 PhysicsSystem2D.instance 的 raycast、testPoint、testAABB 做射线与区域查询,用 Contact2DType 的四个回调写自定义响应,并指出 IPhysics2DContact 的字段是 colliderA/colliderB 而非 selfCollider/otherCollider。
讲清 Cocos 2D 物理的可观测性:用 PhysicsSystem2D 的 debugDrawFlags 与 EPhysics2DDrawFlags 位掩码把物理世界画出来,理解 fixedTimeStep、maxSubSteps、autoSimulation 与求解器迭代参数的语义,并用 profiler.stats.physics 定位物理帧开销,附可单测的固定步长累加器实现。
从 cc.d.ts 与引擎源码路径实证 Cocos 2D 物理的两套后端:内置 builtin 与 Box2D,讲清 PhysicsSystem2D 的后端选择、PHYSICS_2D_PTM_RATIO 单位换算、刚体类型与碰撞体家族,以及两套后端在碰撞回调与动力学上的能力差异,最后落到工程选型。
8.1 的 A2A 端是 Python 写的,可真实团队里另一半服务可能是 TypeScript。协议的价值正在于此:只要双方说同一种「线上语言」,语言就不重要。本节用 TypeScript(Node 26,只用可擦除语法)实现一个 A2A 端,与 8.1 的 Python 端跨语言真跑一次双向协作:TS 服务端被 Python 客户端调用,TS 客户端又反过来调用 Python 服务端。