专栏名称: GoCN
最具规模和生命力的 Go 开发者社区
目录
相关文章推荐
江西省邮政管理局  ·  江西卫视:快递进村 打通物流“最后一公里” ·  2 天前  
中央网信办举报中心  ·  中央网信办发布2025年“清朗”系列专项行动 ... ·  2 天前  
中央网信办举报中心  ·  中央网信办发布2025年“清朗”系列专项行动 ... ·  2 天前  
申妈的妹子圈  ·  阿里第三季度营收2801亿,超市场预期 ·  3 天前  
申妈的妹子圈  ·  阿里第三季度营收2801亿,超市场预期 ·  3 天前  
青岛新闻网  ·  本科毕业6年半!他已任985高校博导 ·  3 天前  
青岛新闻网  ·  本科毕业6年半!他已任985高校博导 ·  3 天前  
51好读  ›  专栏  ›  GoCN

从“黑神话:悟空”看Go为什么不适合AAA游戏开发

GoCN  · 公众号  ·  · 2024-09-13 17:03

正文

2024年8月20日,国产AAA游戏《黑神话:悟空》正式发布!凭借其卓越的画面表现、成熟的玩法和令人惊叹的技术细节,迅速引爆了全球游戏市场,在上线不到一周的时间内,全平台已经大卖超1000万套,一举成为全球游戏玩家瞩目的焦点,并获得普遍的好评。作为一款AAA级大作,它不仅在艺术设计上精益求精,背后更是依托于极高的技术标准。这类游戏的开发对编程语言和技术栈的要求十分严苛,尤其是在图形渲染、物理引擎、多线程处理等方面。

Go语言近年来因其在云计算、后端开发中的出色表现吸引了大量开发者的关注。凭借简洁的语法和强大的并发支持,Go已经成为很多领域中的热门选择。那么问题来了: Go语言能否适应像《黑神话:悟空》这样的AAA游戏开发呢

尽管Go语言在服务器端开发中大放异彩,但当我们仔细审视AAA游戏的核心需求时,会发现它在这个领域面临着诸多挑战。本文将从《黑神话:悟空》为例,粗略分析一下为什么Go难以胜任AAA游戏开发的角色,并探讨它在游戏开发中的潜在应用场景。

1. 什么是AAA游戏开发?

AAA游戏代表着业界顶尖的游戏开发水平,通常伴随着高预算、高人力投入和高技术标准。这类游戏通常具有以下特征:

  • 庞大的制作团队和高昂的开发成本
  • 先进的图形渲染和逼真的视觉效果
  • 复杂的游戏机制和丰富的内容
  • 高度优化的性能,以确保流畅的游戏体验

为了实现极高的画面质量、复杂的物理系统以及流畅的用户体验,AAA游戏开发对技术栈提出了以下几大核心需求:

  • 图形渲染

AAA游戏需要对实时3D图形进行极致优化,确保画面细节丰富、光影逼真,同时保持高帧率,特别是在当前4K甚至8K分辨率的趋势下。

  • 物理引擎

真实的物理模拟是游戏沉浸感的核心,要求引擎能够处理复杂的碰撞检测、重力模拟、流体动态等。

  • 多线程和并发处理

为了最大化利用现代多核处理器的性能,AAA游戏通常依赖多线程编程来处理不同的任务(如渲染、物理、AI等)。

  • 资源管理

在大型游戏中,如何有效管理海量的资源文件(如纹理、音效、模型等),并在需要时进行动态加载,是一项关键任务。

  • AI系统

构建复杂的 人工智能系统 ,控制NPC行为和游戏世界的动态变化。

这些核心需求是否与Go的优势相契合呢?我们继续往下看。

2. Go语言的优势及应用场景

我们知道Go语言作为由Google开发的开源编程语言,自2009年问世以来,在多个领域获得了广泛的应用和认可。

Go的主要特点包括:

  • 简洁的语法和快速的编译速度
  • 内置的并发支持(goroutines和channels)
  • 强大的标准库
  • 跨平台编译能力
  • 垃圾回收机制

这些特性使得 Go在云计算、Web服务、网络编程和并发处理等领域表现出色

然而,正是这些优势,却在游戏开发,包括AAA游戏开发中,变成了局限。下面我们基于黑神话的核心技术需求来看看Go在游戏开发方面的局限。

3. 从黑神话看Go语言在游戏开发中的局限性

作为一款备受期待的国产AAA大作,《黑神话:悟空》在开发过程中采用了高度优化的图形引擎和复杂的物理系统,这些技术需求与Go语言的设计理念存在较大的差距。

  • 图形渲染需求

对于像《黑神话:悟空》这样的游戏,实时渲染复杂的3D场景和角色模型对性能的要求极高。当前业界主流的游戏开发语言和引擎,如C++和Unreal Engine 5(虚幻5引擎),能够在内存分配、指针操作和底层硬件控制上实现精细优化。相比之下, Go的垃圾回收机制 虽然简化了内存管理,但却容易在高频内存操作中带来延迟(内存分配和垃圾回收),这对于追求极致性能的AAA游戏来说是难以接受的。

下面写了两个简单程序,对比一下go与c++的内存分配性能:

// malloc-mem.go
// go build -o malloc-mem-go malloc-mem.go

package main

import (
    "fmt"
    "time"
)

func main() {
    const iterations = 1000 // 多次分配的次数
    start := time.Now()

    for i := 0; i         arr := make([]int, 1_000_000) // 每次分配一个大小为1000的数组
        for j := range arr {
            arr[j] = j
        }
    }

    elapsed := time.Since(start).Milliseconds()
    fmt.Printf("Go 分配内存时间: %d ms\n", elapsed)
}

// malloc-mem.cpp
// g++ -std=c++11 -O3  -o malloc-mem-cpp malloc-mem.cpp 

#include 
#include 
#include 

int main() {
    const int iterations = 1000; // 多次分配的次数
    auto start = std::chrono::high_resolution_clock::now();

    for (int i = 0; i         std::vector arr(1000000); // 每次分配一个大小为1000的数组
        for (size_t j = 0; j             arr[j] = j;
        }
    }

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration elapsed = end - start;
    std::cout <"C++ 分配内存时间: " <" ms" <
    return 0;
}

在我的linux虚拟机上,上述两个程序的输出结果如下:

$ ./malloc-mem-go
Go 分配内存时间: 1644 ms
$ ./malloc-mem-cpp
C++ 分配内存时间: 451.621 ms

我们看到:C++轻松击败Go!

此外,Go标准库虽然全面,但缺乏专门的游戏开发和图形处理库,多数是对C/C++图形库的Go binding,但由于cgo引入的额外性能开销,开发人员都不愿使用这样的binding。

  • 物理模拟

AAA游戏中的物理引擎不仅需要实时模拟角色动作和环境交互,还要求高精度的碰撞检测、布料模拟、流体动态等。C++由于能够直接访问底层硬件,并且通过手动管理内存实现高效计算,成为了开发物理引擎的首选。而Go虽然最初也是以系统编程语言身份诞生的,但真实情况是它的底层硬件控制能力较C++要弱上很多。Go语言的抽象层次较高,难以实现同等水平的优化,cgo又不受大家待见。

  • 多线程和并发处理

尽管Go在并发处理上有明显优势,但AAA游戏开发中的多线程并非仅是简单的任务并发,更需要对线程的调度、同步和共享内存的管理进行精细控制。C++允许开发者手动优化这些过程,而Go的 goroutine虽然简便 ,但其自动化的调度策略往往难以达到AAA游戏中对性能的严格要求。

说到这里, 很多Gopher已经感到“绝望”了 ,在游戏开发领域,Go在C++这样的霸主面前似乎“一无是处”啊。其实也不用这样,在游戏开发领域,尤其是AAA游戏开发领域,C++是一家独大的,即便像C、 Rust 这样的同等性能level的编程语言也是不抗打的。

那么Go在游戏开发领域就真的没有用武之地了么?也不见得,下面我们看看Go在游戏开发领域有哪些潜力可挖。

4. Go语言是否有机会进入游戏开发?

其实这是个妥妥的伪命题!

尽管Go不适合传统的AAA游戏开发,但 它在一些特定的游戏开发领域中发挥作用,并且已经在大规模使用 。早在 GopherChina 2015年大会上,就有一家厦门的游戏公司分享了Go替换Erlang开发游戏服务端(页游和手游)的案例。

下面列出一些Go可以发挥作用的游戏开发领域:

  • 游戏服务器开发

Go在处理并发请求时表现优异,非常适合用于开发游戏的后端服务器,尤其是多人在线游戏的服务器部分,Go的高效并发和简洁性可以降低开发成本。国内很多手游/页游的服务端都是基于Go实现的。相信屏幕前的Gopher们就有不少从从事Go游戏服务端开发的。

  • 独立游戏或休闲游戏

对于对性能要求不如AAA游戏那么高的独立游戏和休闲游戏,Go语言的开发效率和跨平台能力可能会成为一种优势。目前Go社区在这一领域有很多成熟的开源引擎项目,比如著名的 Ebiten [1] ,一个简单易用的 2D 游戏引擎,支持多平台(Windows、macOS、Linux、移动设备等)。在github已经收获万stars。并且 在2024年还举办了Game Jam大会活动 [2] ,显然发展的很不错!3D引擎较少,可用的包括: g3n [3] raylib-go [4] 等。

  • 跨平台工具或编辑器

Go的快速编译和执行速度,也使得它在开发游戏编辑器或跨平台工具时有一定的优势。

5. 小结

从《黑神话:悟空》这样一个AAA级游戏的技术需求来看,Go语言目前显然还无法满足这一领域的核心性能要求,未来大概率也不会满足。尽管Go在云计算、后端服务等领域大放异彩,但它在游戏开发领域,尤其是AAA级别的大作中,受限于性能、内存管理和生态系统等因素,难以与C++这样的AAA游戏老大竞争。

不过,Go语言的优势也并非完全无用武之地。随着游戏开发需求的多样化和服务器端的扩展, Go已经在游戏服务端、页游/手游等独立游戏方面发光发热,并占据了一席之地 。对于那些对Go语言感兴趣的开发者而言,尽管在前台画面和底层性能上暂时无缘AAA游戏,但后端和辅助工具仍然是一个值得学习和探索的方向。

参考资料
[1]

Ebiten: https://github.com/hajimehoshi/ebiten

[2]

在2024年还举办了Game Jam大会活动: https://itch.io/jam/ebitengine-game-jam-2024

[3]

g3n: https://github.com/g3n/engine

[4]

raylib-go: https://github.com/gen2brain/raylib-go

[5]

Gopher部落知识星球: https://public.zsxq.com/groups/51284458844544

[6]

链接地址: https://m.do.co/c/bff6eed92687


- END -



推荐阅读:

6 个必须尝试的将代码转换为引人注目的图表的工具

Go 1.23新特性前瞻

Gopher的Rust第一课:第一个Rust程序







请到「今天看啥」查看全文