Blog
Godot2 min read

Godot 4 游戏导出网页教程(HTML5 与 itch.io)

一步步教你把 Godot 4 游戏以 HTML5 和 WebAssembly 导出到网页,包括导出模板、无需特殊响应头的默认单线程导出、在 itch.io 上托管,以及黑屏问题的解决方法。

Godot 可以以 HTML5 和 WebAssembly 的形式导出到网页,这意味着你的游戏可以直接在浏览器标签页中运行,无需下载,也无需插件。这是把可玩版本送到别人面前最快的方式。你发一个链接,对方点开就能玩。

「导出到网页」其实是两件事,而不是一件。生成文件大约只需要一分钟。让这些文件在浏览器中跑起来,才是大家遇到黑屏的地方,原因通常是文件的提供方式不对,或者某个导出选项悄悄开启了托管服务无法满足的要求。本指南涵盖这两个环节、具体设置,以及大多数导出失败背后的错误。

本指南适用于 Godot 4.3 及以上版本。更早的 4.x 版本一律使用多线程构建,所以如果你还在用 4.0、4.1 或 4.2,请仔细阅读响应头部分,或者升级编辑器。

{/* IMAGE: The Godot Export dialog open with a Web preset selected, the Export Project button highlighted. 1200x675 editor screenshot. */}

「网页导出」实际生成了什么

导出时,Godot 不会只生成一个文件,而是写出一个包含静态文件的小文件夹。

  • index.html 是加载所有内容的页面,也是浏览器打开的文件。
  • 一个 .wasm 文件 是编译成 WebAssembly 的 Godot 引擎本体,也是体积最大的部分。
  • 一个 .pck 文件 是你的游戏数据,也就是打包在一起的场景、脚本和资源。
  • 一个 .js 文件 是把引擎连接到页面的加载器胶水代码。
  • 有时还有一个 .audio.worklet.js,多线程构建还会带有额外的 worker 文件。

这些文件必须放在一起,并通过 HTTP 提供服务。你不能双击 index.html 就指望它运行,这是很多人踩到的第一个坑。

第 1 步,安装导出模板

Godot 的编辑器和导出模板是分开发布的。导出模板是各平台预编译好的引擎二进制文件,其中包括供浏览器使用的 WebAssembly 构建。全新安装的 Godot 不包含这些模板。

进入 Editor 再选 Manage Export Templates(管理导出模板),然后点击 Download and Install。这会下载与你的引擎版本完全对应的模板。

导出模板必须与编辑器版本完全一致。4.4 的编辑器不能用 4.3 的模板导出,反过来也不行。版本不一致是网页构建出问题最常见的原因之一。每次升级编辑器后,都要重新安装模板。

第 2 步,添加 Web 导出预设

打开 Project 再选 Export。点击 Add 并选择 Web。

默认设置基本合理。对网页来说,有三组选项很重要。

  • Variant,Thread Support。 从 Godot 4.3 起默认关闭。除非你实测确认确实需要多线程,否则保持关闭。单线程构建可以在任何静态托管上运行,也能在游戏门户网站的 iframe 中运行。开启它需要第 4 步介绍的两个 Cross-Origin 响应头。
  • Variant,Extensions Support。 只有项目使用 GDExtension 时才需要。它同样需要 Cross-Origin 响应头,而且每个原生扩展都需要自己的网页构建。
  • VRAM Texture Compression。 默认开启「For Desktop」,关闭「For Mobile」。两者都开启会让导出体积更大,但兼容性更好。如果你预计会有手机玩家,这一点很重要,因为手机通常不支持桌面端的贴图格式。

除非有理由修改,否则 Head Include 和自定义 HTML 外壳保持为空即可。默认外壳会处理加载过程和进度条。

第 3 步,导出项目

选择一个目标文件夹。新建一个名为 web-build 之类的空文件夹,这样输出文件就不会和其他东西混在一起。

把主文件命名为 index.html,而不是你的游戏名称。包括 itch.io 在内的大多数托管平台都会把 index.html 当作入口文件。如果你把它命名为 mygame.html,托管平台就找不到它。

点击 Export Project。几秒钟后,文件夹里就会出现前面列出的那些文件。

{/* IMAGE: A file explorer showing the exported web-build folder contents: index.html, .wasm, .pck, .js files. 1000x500. */}

第 4 步,什么时候需要 Cross-Origin 响应头

大多数旧教程都说,每个 Godot 4 网页构建都需要特殊响应头。这在 4.3 之前是对的。现在取决于两个复选框。

开启了 Thread Support 或 Extensions Support 的构建会使用 SharedArrayBuffer,而浏览器只有在页面带着下面这两个响应头提供时才允许使用它。

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

没有这两个响应头,引擎就无法启动,控制台会显示提到 SharedArrayBuffer 或 crossOriginIsolated 的报错。这些响应头不是在 Godot 里设置的,而是在提供这些文件的服务器上设置。

两个选项都关闭的构建,也就是默认构建,两个响应头都不需要。所以单线程导出才是 itch.io、游戏门户网站和普通静态托管的正确选择。多线程可以提升大型游戏的性能,但代价是托管灵活性和嵌入兼容性。

第 5 步,上传前先在本地测试

不要靠反复上传和刷新来调试网页导出。先在自己的电脑上测试。

最快的检查方式是编辑器的 一键部署(one-click deploy)。只要存在 Web 预设,编辑器右上角就会出现一个浏览器图标。点击它会启动本地 Web 服务器,导出项目并在默认浏览器中打开。这个服务器会发送 Cross-Origin 响应头,所以多线程构建也能运行。

对于已经导出的构建,只要 Thread Support 和 Extensions Support 都是关闭的,任何本地服务器都可以。如果装了 Python,在 web-build 文件夹里运行 python -m http.server 8000,然后打开 http://localhost:8000。

对于多线程构建,需要带上两个响应头来提供服务。把下面的内容保存为文件夹里的 serve.py。

import http.server, socketserver

class Handler(http.server.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header("Cross-Origin-Opener-Policy", "same-origin")
        self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
        super().end_headers()

with socketserver.TCPServer(("", 8000), Handler) as httpd:
    print("Serving on http://localhost:8000")
    httpd.serve_forever()

运行 python serve.py 并打开 http://localhost:8000。如果游戏在这里能加载,说明导出没问题,剩下的问题都出在托管配置上。

第 6 步,托管游戏

itch.io(最简单,免费)

这是分享游戏和参加 game jam 的推荐方式。

  1. 打包 web-build 文件夹里的内容,而不是它的上级文件夹,确保 index.html 位于 zip 的最顶层。
  2. 在 itch.io 上新建项目,把 Kind of project(项目类型)设为 HTML。
  3. 上传 zip 并勾选 This file will be played in the browser(此文件将在浏览器中游玩)。
  4. 在嵌入选项中,设置与游戏分辨率一致的视口尺寸。

itch.io 允许解压后的内容总计不超过 500 MB,单个文件不超过 200 MB,文件数量不超过 1000 个。单线程构建不需要其他任何设置。对于多线程构建,itch.io 在嵌入框架选项中提供了 SharedArrayBuffer support 复选框,但它被标注为可能导致页面部分功能失效的实验性功能,所以请在多个浏览器中测试发布后的页面。

Netlify、Vercel、GitHub Pages 或自己的服务器

单线程构建可以原样在任何静态托管上运行,包括普通的 GitHub Pages。请确认服务器以 application/wasm 内容类型发送 .wasm 文件并进行压缩,因为 WebAssembly 用 gzip 压缩后大约只剩原来的四分之一。

对于多线程构建,托管服务必须发送这两个响应头。在 Netlify 上,在部署根目录添加一个 _headers 文件。

/*
  Cross-Origin-Opener-Policy: same-origin
  Cross-Origin-Embedder-Policy: require-corp

在 Vercel 上,在 vercel.json 的 headers 规则中设置同样的两个响应头。在 nginx 或 Apache 上,把它们加到 location 块中。GitHub Pages 无法发送自定义响应头,所以在那里运行多线程构建需要借助 coi-serviceworker 这类 service worker 变通方案,而并不是每个浏览器都认可这种做法。如果你不需要多线程,更简单的办法是关闭 Thread Support。

修复黑屏的检查清单

如果看到黑色画布,打开浏览器的开发者控制台(按 F12,再切到 Console 标签页),看第一条红色报错。按顺序逐项排查。

  1. 你是不是直接打开了文件? 如果网址以 file:// 开头,请改为通过 HTTP 提供服务。
  2. 报错里有没有 SharedArrayBuffer 或 crossOriginIsolated? 说明开启了 Thread Support 或 Extensions Support,而托管服务没有发送响应头。关闭这两个选项后重新导出,或者在托管服务上添加响应头。
  3. 报错是否提到版本号或模板加载失败? 说明导出模板与编辑器版本不一致。在 Manage Export Templates 中重新安装。
  4. 这是 C# 项目吗? Godot 4 无法把 C# 项目导出到网页。网页构建需要 GDScript 项目。
  5. .wasm 文件的内容类型是否不对? 有些托管服务会把它当作普通下载文件发送。请设置 application/wasm 内容类型。

大多数网页导出失败都属于这五种情况之一。

哪些东西在浏览器里不一样

网页构建并不是加了网址的桌面版。有几件事的表现不同。

  • 存档数据 会保存到浏览器的 IndexedDB,而不是硬盘上的文件夹,并且玩家必须允许网站存储才能保留存档。在门户网站的 iframe 中,这可能需要第三方存储权限,所以请在你实际使用的托管平台上测试存档功能。
  • 音频 只有在玩家点击、触摸或按键之后才会开始播放,因为浏览器会阻止自动播放。加一个「点击开始」界面就能解决。
  • 原生插件(为桌面编译的 GDExtension 库)无法加载,除非它们提供了网页构建,并且开启了 Extensions Support。
  • C# 在 Godot 4 中无法导出到网页。
  • 渲染 在网页上使用 Compatibility 渲染器(WebGL 2),所以用 Forward+ 或 Mobile 制作的项目看起来会不一样。SDFGI、体积雾和屏幕空间反射等效果不会被渲染。面向网页的游戏从一开始就用 Compatibility 来做,这样你在编辑器里看到的就是最终发布的效果。Summer 自己的网页模板则不同,它使用 WebGPU 和 Forward+ 或 Mobile。
  • 加载体积比任何其他平台都更重要。 游戏开始前,玩家要先下载引擎、数据包和所有资源。Poki 的开发者指南指出,如果加载时间超过十秒,玩家通常就会离开,所以请让首次下载尽量小。

Summer Engine 与网页导出

Summer Engine 是一款适用于 macOS 和 Windows 的桌面引擎,沿用 Godot 4 的工作流程,并配有一个能根据自然语言创建场景、脚本和资源的 AI。它可以为你的游戏生成桌面版本,你可以在 Steam 上销售,或者作为下载版上传到 itch.io,它也能导出网页版本。

从引擎 0.7 起,编辑器自带 Summer 自己的网页导出模板,使用 WebGPU 和 Forward+ 或 Mobile 渲染器。网页导出适用于 GDScript 项目。使用 C# 的项目不能导出到网页,这和 Godot 4 的限制相同。网页版本是一个标准的静态 .zip,根目录下有 index.html。你可以把它发布到 Summer Games,大家就能在浏览器中游玩。Summer Games 也接受上文介绍的、使用 Compatibility 渲染器的标准 Godot 网页导出。智能体可以用 MCP 工具 summer_export_game(目标为 web)再加 summer_publish_build 完成这两步。

如果你今天就想在 Summer 中开始做游戏,可以从一个已经配置好移动和镜头的 模板 开始,描述你想在此基础上添加的玩法机制,等游戏玩起来顺手了,再导出版本。

Frequently asked questions

Godot 游戏可以导出到网页吗?

可以。Godot 4 使用 WebAssembly 导出为 HTML5,游戏可以在现代浏览器中运行,无需插件,也无需安装。你只需添加一个 Web 导出预设,安装对应的导出模板,Godot 就会生成一个可以托管在任何地方的静态文件夹。用 C# 编写的项目在 Godot 4 中无法导出到网页,原生 GDExtension 插件也需要单独的网页构建。

为什么我的 Godot 网页导出是黑屏?

打开浏览器控制台,看第一条红色报错。原因通常是以下三种之一。你直接从文件系统打开了 index.html,而没有通过 HTTP 提供服务。你开启了 Thread Support 或 Extensions Support,它们需要 Cross-Origin-Opener-Policy 和 Cross-Origin-Embedder-Policy 响应头,而你的托管服务没有发送。或者你的导出模板与编辑器版本不一致。关闭 Thread Support(Godot 4.3 起的默认设置)就能彻底消除响应头问题。

Godot 网页导出需要 SharedArrayBuffer 或特殊响应头吗?

默认导出不需要。从 Godot 4.3 起,Web 预设导出的是单线程构建,不依赖 SharedArrayBuffer,也不需要任何特殊响应头。只有开启了 Thread Support 或 Extensions Support 的构建,才需要把 Cross-Origin-Opener-Policy 设为 same-origin,并把 Cross-Origin-Embedder-Policy 设为 require-corp。

如何免费托管 Godot 网页游戏?

itch.io 是最简单的免费托管平台。把导出的文件夹打包成 zip,让 index.html 位于最顶层,然后创建一个 HTML 项目,上传 zip 并勾选在浏览器中游玩的选项。itch.io 允许解压后的文件总计不超过 500 MB,单个文件不超过 200 MB,文件数量不超过 1000 个。单线程构建不需要自定义响应头,所以 GitHub Pages 和 Netlify 也同样可用。

Godot 网页导出比桌面版构建更小吗?

很少会更小。游戏开始前,玩家要先下载 WebAssembly 引擎、数据包和所有资源。仅引擎文件未压缩时就有几十 MB,经托管服务压缩后也还有好几 MB,而带有大尺寸贴图的 3D 游戏还会增加更多体积。如果网页是你的主要目标平台,请压缩贴图,删除未使用的资源,并控制好项目规模。

Summer Engine 能导出到网页吗?

可以。Summer Engine 可以为 GDScript 项目导出网页版本。从引擎 0.7 起,桌面编辑器自带 Summer 自己的网页导出模板,使用 WebGPU 和 Forward+ 或 Mobile 渲染器。网页版本是一个标准的静态 .zip,根目录下有 index.html,你可以把它发布到 Summer Games(summer.games),大家就能在浏览器中游玩。使用 C# 的项目不能导出到网页,这和 Godot 4 的限制相同。本指南中的步骤介绍的是标准 Godot 4 的网页导出。

  • Godot
  • Web Export
  • HTML5
  • Tutorial