技术讨论:游戏服务器开发、编程语言与AI辅助编码 | 原创,AI翻译
两位参与者:一位游戏开发者与 lzwjava。
以下对话通过 Whisper 在 RTX 4070 上转录,随后借助 AI 工具进行精炼和整理。原始对话为中文。
注:由于转录和精炼均借助 AI 辅助,部分细节可能不准确或经过转述。在依赖任何重要信息前,请自行核实。
本次会议涵盖了两位后端工程师之间广泛的技术讨论,重点涉及游戏服务器开发、编程语言(C++、Go)、网络协议(TCP vs. UDP)、游戏中的数据结构,以及 AI 在软件开发流程中日益增长的作用。对话还涉及技术面试方法、基础设施考量,以及 AI 辅助编码工具(如 Web Coding 和 Cline)的演变。
背景与上下文
参与者首先介绍了各自的背景。一位参与者主要从事服务器端开发,在游戏行业的多家公司和项目中拥有经验。另一位参与者同样从事服务器端工作,但领域不同——主要在一家大型金融机构工作,曾在中国的一家游戏公司任职。两位都是后端工程师,只是各自所在的行业领域不同——一位在游戏行业,另一位在金融服务行业。
本次会议最初被定位为技术讨论,而非正式面试。一位参与者提到,他们会对对话进行录音,手动移除任何敏感内容,将清理后的版本分享给另一位参与者批准,然后可能将其发布到网上。
编程语言与经验
主要使用的语言
当被问及编程语言时,一位参与者分享了自己的背景:职业生涯初期大量使用 C++,之后广泛使用 Go。除了这两种语言,几乎没用过其他。当被追问最精通哪种语言时,他们不愿声称自己精通任何一种——尤其是 C++,并指出任何自称“C++ 专家”的人很可能是夸大其词。他们形容自己在 Go 方面“足够胜任实际工作”。
另一位参与者提到了自己的专业背景:在公司日常使用 Java,但在个人项目和 AI 辅助编码中也在探索其他语言。最近开始尝试 Rust,作为学习练习编写了大约 2000 行 Rust 代码,不过他们承认自己仍处于学习曲线的早期阶段。
语言哲学
一位参与者表示,编程语言本质上只是完成工作的工具,选择完全取决于项目现有的技术栈。他们将 C++ 描述为“带有面向对象特性的 C”。这种务实、以项目为导向的语言选择方法贯穿了整个讨论。
C++ 的挑战
讨论简要触及了 C++ 常见的痛点——指针、空指针和内存泄漏。一位参与者指出,相比其他语言,C++ 的入门门槛极高,这也是 Go 能够找到立足之地的原因之一。Go 介于 C++ 和更动态的语言之间,在保持良好性能的同时,学习曲线相对较低。另一位参与者同意,这些问题本质上是语法层面的,而非架构层面的。
编码风格与范式
当被问及编码风格——是否偏向函数式编程、面向对象编程或过程式编程时,一位参与者表示自己没有固定的风格。他们的方法完全由项目决定。他们估计,在 C++ 和 Go 代码中,过程式编程是最常见的模式。他们还提到曾参与过纯 C 项目,这些项目完全没有面向对象特性。
参与者指出,尤其是在游戏开发中,传统的面向对象编程(带有继承层次结构)与另一种称为 ECS(实体-组件-系统) 的范式之间存在重大张力。ECS 是一种架构模式,其中组件被组合成实体,而不是构建深层的继承树。一位参与者确认,ECS 在游戏开发中广泛使用,尤其是基于 Lua 的框架。
游戏服务器架构与网络
游戏专用后端框架的需求
一位参与者解释了为什么游戏服务器通常需要专用框架,而不是使用像 Spring Boot 这样在互联网应用开发中无处不在的通用解决方案。关键区别在于传输数据的性质以及实时游戏的具体要求——例如,需要在会话中多个玩家之间同步状态。这就是游戏公司经常开发自己内部服务器框架的原因,而不是依赖广泛共享的开源解决方案。
Skynet 与 Big World
讨论触及了两个著名的游戏服务器框架:
- Skynet 是一个基于 Lua 的开源框架。然而,一位参与者指出,尽管它是开源的并且有用户社区,但它并未被广泛使用——他们之前所在的游戏公司都没有采用。小型工作室有时会用它来快速发布产品。
- Big World(Big World Engine)是一个商业引擎/框架,专门用于构建大型多人在线(MMO)游戏。它内置了用于多玩家同步的基础设施。这个框架较老,今天已不太常用,但网上仍可查到相关文档。
一位参与者澄清说,在游戏领域,这些通常被称为“引擎”,而非“框架”。
游戏网络中的 TCP 与 UDP
讨论的很大一部分集中在游戏网络中选择 TCP 还是 UDP 的问题上。一位参与者提到,根据他们的经验,游戏项目中 TCP 与 UDP 的使用比例大约为 50/50,具体取决于游戏类型和特定需求。
TCP 通过三次握手、确认(ACK)、重传机制和保守的超时行为提供可靠、有序的交付。它保证数据会到达。相比之下,UDP 更轻量,可以实现更高的吞吐量,但不保证交付、有序性或可靠性。UDP 通常用于实时应用,如视频流和游戏。
一位参与者提出了一个问题:考虑到现代 4G/5G 网络和快速的家庭互联网,TCP 是否可以在大多数游戏场景中直接取代 UDP?答案是:UDP 并非关乎原始速度——而是关乎处理弱网络条件。在较差的网络环境中,TCP 的保守行为(重传、指数退避超时)实际上会进一步恶化玩家体验。对于处于弱网络环境中的单个玩家,TCP 可能使情况变得更糟,而不是更好。这就是为什么一些游戏在实时游戏玩法中选择 UDP,尤其是在战斗场景中。
实时多人游戏的常见模式
一位参与者讨论了大规模实时多人游戏中的常见网络模式:
- 大多数此类游戏使用长连接(持久连接),而非 HTTP 轮询。
- 这些持久连接通常不是 WebSocket——它们使用基于原始 TCP 或 UDP 的自定义协议。
- 对于战斗内操作(战斗、技能使用),游戏通常使用 UDP,因为低延迟至关重要。丢弃几个数据包比等待 TCP 重传更可取。战斗操作对时间极其敏感。
- 对于战斗外操作(菜单交互、大厅管理),游戏通常使用 TCP,因为轻微的延迟是可以接受的。这些操作对延迟不敏感。
一位参与者描述了数据包丢失在游戏中的表现:在激烈的战斗时刻,当许多玩家同时活跃时,网络数据可能会突然激增。一些数据包可能会丢失。然而,他们强调,所有网络优化的目标都是最小化这种情况。没有游戏希望玩家体验到技能丢失或橡皮筋效应。游戏在诸如进出电梯或地铁(连接变化)等场景中投入了大量资源进行网络优化。
反作弊与外部工具
当被问及作弊和外部工具(例如,代表人类玩家进行竞技游戏的 AI 机器人)时,一位参与者解释了服务器端的反作弊方法:
- 基本原则是:永远不要信任客户端发送的任何数据。所有客户端提交的数据都必须在服务器上严格验证。
- 作弊有不同的类别。历史上,一种常见类型是内存修改(在客户端修改游戏内存)。客户端混淆和代码加固等技术使得这种作弊类型不那么普遍了。
- 服务器还可以检测异常行为模式——例如,如果客户端以异常高的速率发送请求,服务器可以直接拒绝这些请求。
游戏开发与软件工程中的 AI
AI 辅助的游戏玩法与作弊
一位参与者问道,AI 是否可以用来编写能够“攻克”竞技游戏(例如策略游戏或 MOBA 游戏)的机器人,以至于人类玩家停止游玩。回答是,这种情况在实践中非常罕见。虽然在竞技游戏中有 AI 系统的使用,但广泛使用 AI 生成的机器人使人类玩家无法游玩的想法被认为不太可能。
AI 辅助编码(Web Coding / Cline)
对话转向了两位参与者如何在开发中使用 AI。一位参与者指出,他们在工作流程中广泛使用 AI 辅助编程。常见用例包括:
- 调试和错误日志分析——错误在路由给开发人员之前,会先自动通过 AI 工具处理。
- 开发工具链中的一般生产力提升。
另一位参与者描述了一种更激进的方法:他们依赖 Web Coding(也被称为 Cline)来完成大部分编码工作。他们的工作流程包括:
- 让 AI 代理自主运行,可能连续执行数百个命令。
- 在过程中使用 Git 跟踪每一次代码变更。
- 在 AI 完成后,进行回顾性审查:阅读 AI 的推理步骤和 Git 历史,以了解发生了什么以及为什么。
- 如果出现问题,回溯记录的过程以找到错误的源头。
他们将此描述为“让它运行直到出错,然后回去查看哪里出了问题”。
AI 工具采用与风险承受能力
一位参与者指出,在他们目前所在的公司(一家大型金融机构,用户量相对较小——数万级别),他们放心让 AI 自主编写代码,因为风险较低。然而,如果他们是在一个拥有数百万用户且涉及金融资产的系统上工作,他们会采取不同的方法:首先自己设计整体架构,然后与 AI 工具“讨论”设计,以收敛到最优方案,最后才让 AI 实现。
Bug 与事故管理
一位参与者问对方是否曾导致影响数十万或数百万用户的 Bug,以及公司是否因此追究责任。回答是,是的,生产环境 bug 时有发生。影响程度根据范围和持续时间来评估。重大事故可能被归类为“事故”并触发正式流程,但实际上,对个人的后果通常并不严重。
数据结构、优化与底层细节
位运算与内存优化的作用
一位参与者具有 OI(信息学奥林匹克竞赛)背景,他询问了位运算、位操作(异或、位集)以及底层内存布局(一个字节有多少位、字符串内存占用)在游戏开发中的重要性。他想了解这些来自竞赛编程的技术是否在生产游戏服务器中常用。
回答是,是的,这些技术会用到——但它们被认为是基础工具,而非特殊成就。当某个函数需要在负载测试下达到特定性能目标时,会应用位运算优化。然而,参与者认为这个问题与对话焦点有些不匹配:“我不太明白你问题的意图——这些只是优化,是日常工作的部分,并不是什么特别重要的事情。”
游戏中的数据结构
一位参与者强调,数据结构在游戏开发中非常重要——对象的形状、它们之间的关系以及数据的组织方式。另一位参与者表示同意,但指出游戏服务器开发与其他服务器端开发并无本质区别。使用的核心工具相同:Redis、消息队列、数据库。具体的数据结构取决于游戏的数据模型。
基础设施与部署
集群部署 vs. 单机
一位参与者询问游戏服务器是部署在单台高性能机器上(例如 32 GB 或 64 GB 内存、高端 CPU)还是以集群方式部署。答案明确是:集群。他们温和地反驳道:“我觉得你可能对游戏开发有些偏见。如果一个服务流量很大,它不可能是单机部署——游戏领域也是如此。”游戏中的不同服务可能有不同的扩展需求——有些需要扩容(更多实例),有些则不需要。这是通过容器编排工具如 Kubernetes (K8s) 来管理的。
然而,一位参与者承认他们个人并不熟悉 Kubernetes 集群管理——在他们的经验中,这个领域通常属于 SRE(站点可靠性工程)团队。他们自己的重点是 CI/CD 流水线和本地开发流程,而非集群操作。
本地开发与模拟数据
当被问及本地开发流程——特别是如何处理对其他服务(微服务架构)的依赖时,一位参与者描述了金融服务中的方法。在微服务架构中,一个单一服务(例如基金服务)可能需要同时调用 account-user 服务和 transaction 服务。在本地开发中,他们会设置本地模拟,将 URL 重定向到本地端点,并使用模拟数据进行测试。
另一位参与者回应说,在游戏开发中,方法不同:如果可能,他们只是简单地在本地启动所有所需的服务。如果不可行(例如缺少某个依赖),他们要么模拟数据,要么手动在数据库(可能是 MySQL 或 PostgreSQL)中构造测试数据。他们强调“这取决于具体的业务场景”——如果服务需要用户账户,他们只需注册一个即可。
数据库与中间件
两位参与者都认同核心基础设施栈:
- Redis 被广泛用于有序集合、排行榜、消息队列以及其他常见模式。
- Kafka 在某些项目中使用,但并非全部。决策取决于是否真正需要消息队列,以及项目现有技术栈(例如 Redis 已经作为消息队列)是否使得添加 Kafka 变得不必要。
- 数据库 包括 MySQL 和 PostgreSQL。一位参与者提到他们主要使用 MySQL,也使用一些 PostgreSQL。
一位参与者指出,询问 Redis 的使用模式(例如“你使用有序集合吗?”)基本上没有意义,因为每个后端工程师都根据业务需求使用 Redis——“你用的我也用——都是基于场景的。”
对讨论的反思
AI 与行业变革
一位参与者反思了由 AI 驱动的更广泛的行业变革。他们指出,自 2023 年底强大的大语言模型发布以来,公司们一直在更积极地推动 AI 辅助编码。在此之前,雇主对此并不特别感兴趣——而现在这是一个热门话题。他们提到,AI 领域的一些知名人物每年在 token 上的花费超过一百万美元,将当前时代描述为“谁有钱买 token 和 GPU,谁就能在 AI 生态系统中占据强势地位”。
对话的性质
临近结束时,一位参与者反思说,这次对话相当分散,跳跃了很多主题——编程语言、网络协议、数据结构、AI 工具、开发工作流程和基础设施。他们建议未来的对话或许应该有一个更清晰的焦点。
联系与分享
会议结束时,一位参与者提醒对方,他们将清理转录内容,移除敏感部分,分享以待批准,然后可能将其发布到网上。
行动项
- 行动项: 会议记录者将清理转录稿,移除任何敏感内容,并将清理后的版本分享给另一位参与者批准,然后再发布到网上。
- 行动项(未分配): 研究 ECS(实体-组件-系统)架构模式,该模式在游戏开发中作为传统 OOP 继承的替代方案使用。
- 行动项(未分配): 考虑未来的技术讨论是否应该有一个更聚焦的主题结构。