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

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

63abaeb46ee35c09800d76a47f82b7db.jpeg

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年问世以来,在多个领域获得了广泛的应用和认可。

b86b4dbb51bcca17faf68b5e71ccfc3b.png

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 < iterations; 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 <iostream>
#include <chrono>
#include <vector>

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

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

    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double, std::milli> elapsed = end - start;
    std::cout << "C++ 分配内存时间: " << elapsed.count() << " ms" << std::endl;

    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]等。

dc34d8be2ae7fb322f79a63e23dc132c.png

  • 跨平台工具或编辑器

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

5. 小结

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

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


往期推荐


Gopher部落知识星球[5]在2024年将继续致力于打造一个高品质的Go语言学习和交流平台。我们将继续提供优质的Go技术文章首发和阅读体验。同时,我们也会加强代码质量和最佳实践的分享,包括如何编写简洁、可读、可测试的Go代码。此外,我们还会加强星友之间的交流和互动。欢迎大家踊跃提问,分享心得,讨论技术。我会在第一时间进行解答和交流。我衷心希望Gopher部落可以成为大家学习、进步、交流的港湾。让我相聚在Gopher部落,享受coding的快乐! 欢迎大家踊跃加入!

66810d16e6d3039c1ae5fc48bb351221.jpeg81595ff3ffa04afb835a3929e7ae0680.png

2f6c2b9f29993f7965bc71e04c1b27f6.pngaa443f1eba0ba8010610cb1c63150c36.jpeg

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址[6]:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻) - https://gopherdaily.tonybai.com

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx

  • 微博2:https://weibo.com/u/6484441286

  • 博客:tonybai.com

  • github: https://github.com/bigwhite

  • Gopher Daily归档 - https://github.com/bigwhite/gopherdaily

  • Gopher Daily Feed订阅 - https://gopherdaily.tonybai.com/feed

f8cd9e5718c65d624dee4e67f980b744.jpeg

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

参考资料

[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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值