手把手拆解:如何使用GPT-6 Astra 打造一款大型太空探索网页游戏

以 Void Explorer 为主案例,具体拆解如何先定义玩法与视觉,再搭建可观测测试、多尺度坐标、流式地形、性能基准和 Blender 资产管线。

作者:OpenAI Developers09-14 · 约 18 分钟

如果目标只是让 AI 生成一个能运行的小型游戏原型,问题还相对简单;一旦目标扩大为一款能从星际空间连续飞到行星地表的大型浏览器游戏,美术方向、尺度表示、地形流式加载、操控、渲染、测试和性能就必须协同工作。

OpenAI 官方以 Void Explorer 为案例,展示了如何在 Codex 中使用 GPT-6 Astra 推进这套工程流程。最终成品拥有 2,048 个星系、超过 10,000 颗程序化行星,玩家可以选择可见恒星并飞往那里,也能从太空连续下降到海岸和地表。

难点不在于生成某一段代码,而在于怎样确定体验边界、让 Astra 看见并复现问题、用同一套测试比较修改前后的结果,再逐步扩大游戏规模。沿着这条制作顺序,下面的每个工程选择都能落回一个具体问题和检查方法。

Void Explorer 的 gameplay supercut

这套工作方法先设立明确约束,让 Astra 提出工程实现,再由人持续判断外观与操控手感,同时建立可复现的测试与调试闭环。


体验先行:用自然语言确立物理与视觉边界

这个项目没有从技术栈清单开始,而是先向 Astra 明确玩家应该获得的体验和不可改变的物理边界,再让这些约束反向影响工程架构。

在构建 Void Explorer 之初,最初的需求描述直接框定了整个宇宙的物理法则:

核心提示词(设计原则): “所有我能看到的东西都必须是可抵达的。保持真实的宇宙距离,然后通过尺度与航行速度来化解枯燥。我想直接从太空飞进行星的大气层并平稳降落到地面。行星可以像地球一样巨大,因此我们需要程序化地形和分块渲染器。”

这段描述给系统设定了三个明确边界:

  1. 远处的恒星不能只是背景上的光点,而要成为可选择、可飞往的目标。
  2. 接近行星时,它不能突然变成一个独立关卡;从太空到地面必须连续。
  3. 真实宇宙距离需要 pulse travel 与 hyperdrive 让旅程可行,而地球尺度的行星需要程序化地形和分块渲染。

视觉方向也在正式搭建大量游戏内容前用图像反复校准。第一批概念图太写实,下一版又太简单,于是继续用更具体的要求修正:

核心提示词(视觉校准): “现在这个版本太简单了。我们需要一个折中方案:更好的颜色、霓虹光感,以及深空的高对比度。请展示出飞船高速航行时的模样,周围带有恒星和尘埃。”

AI 生成的概念图,确立了象牙白飞船、多面体青色行星与洋红星环的视觉基调
AI 生成的概念图:最终确立了象牙白机体、青色天体与高饱和度深空照明的调色板

满意的图像被保存下来,成为轨道飞行、高速航行、大气进入和着陆的视觉参考。有了这些具体目标,后续版本是否接近预期就更容易判断。


架构演进:Three.js、WebGPU 与后台多线程解耦

前端技术选型采用了 TypeScript 与 Vite 构建工具,核心渲染层基于 Three.js。Three.js 赋予了代码对底层网格(Mesh)、材质(Material)、光照以及自定义程序化几何体的直接控制权,这正是 Void Explorer 绝大多数视觉表现的核心载体。

首个可玩渲染器使用 WebGL2。项目随后继续追问 Three.js 是否限制了视觉表现,Astra 建议保留宇宙、导航和地形系统,只把渲染层迁移到 Three.js 的 WebGPU 架构。

关键技术与分工:

  • 节点材质与 TSL:Three.js 的节点材质和 Three.js Shading Language 让大气、水体和光照效果可以用代码定义。
  • Web Workers:地形生成在负责输入与绘制的线程之外准备几何数据,避免把所有计算都挤在同一条执行线上。
  • Vitest 与 Playwright:Vitest 检查可重复生成、坐标数学和地形契约;Playwright 则在浏览器里操作游戏,验证完整交互。
开启 Neon Phosphor 荧光滤镜后的轨道飞行实机画面
开启 Neon Phosphor 后的实机画面:加入复古显示纹理,同时保持导航可读

为了贴合概念图确立的美学方向,渲染管线加入了 Neon Phosphor 效果。它给画面增加复古显示纹理,同时保持导航信息可读。


赋予 AI 诊断工具:自动化巡检与状态透传

人负责实际试玩和判断,但 Astra 还需要一种比“我感觉这里不对”更具体的调查入口。项目因此暴露了一个小型 JavaScript 接口 window.__VOID_EXPLORER__,让浏览器测试可以读取正在接近的天体、当前飞行模式、地形是否就绪和活动摄像机。它还提供 draw calls、triangle counts、queued terrain jobs、buffered terrain data 等渲染与流式加载计数。

下一步是建立可重复返回的命名测试场景:orbit、pulse travel、atmospheric descent、coastal landing。Playwright 可以直接加载某个场景,等待地形就绪,截取画面并检查背后的状态。这样,Astra 不必每次都从宇宙另一端重新飞到问题发生的位置。

固定场景不能代替完整旅程。项目另有 journey tests,使用真实控制并记录飞行过程中的位置和状态变化,覆盖 landing、leaving the ship、walking、saving and reloading、boarding、taking off。它们能发现单张截图看不到的问题,例如碰撞面还未准备好,或飞船在状态切换时发生位置跳变。

实际试玩时,也可以让 Astra 检查正在游玩的浏览器标签页,例如在某一时刻确认 Aurelia 的云层是否仍然可见。这里的边界很重要:这是特定时刻的检查,并非 Astra 在持续观看每一帧。

由此形成的调试循环是:复现问题,检查截图与状态,追踪相关代码,修改实现,再重跑同一检查。对新的游戏项目,可以尽早准备少量可重复场景、有用的状态与性能计数器,以及主要交互的浏览器测试。


天文级尺度的数学解耦:从大整数网格到四叉树球面

光年尺度的位置与站在飞船旁的位置相差极大。如果把这些巨大的坐标直接发给 GPU,靠近地面时会失去所需精度。因此,系统把“物体在宇宙中的地址”和“这一帧用于绘制的位置”分开处理。

大整数单元格与局部偏移:宇宙位置由大整数 cell 和较小的 local offset 共同表示。渲染前再减去观察者的位置,让摄像机保持在原点,附近物体继续使用较小的相对坐标。显示距离和相对大小因此能保持一致。

解析轨道与统一时间:恒星、行星与卫星按 analytic orbits 运行,渲染器用与观察者相同的 simulation time 计算它们的位置。停放的飞船会随旋转的行星一起移动;恒星的位置与颜色也会进入光照系统,所以地面看到的双恒星落日与轨道上看到的是同一组恒星。

从太空飞向月球表面

拥有上万颗行星不等于加载上万个高细节网格。每颗行星先是一份描述:半径、轨道、大气和 seed。seed 使同一片地形可以被重复生成;游戏只在玩家接近时生成附近几何,再在返回时重建相同景观。

立方体球面与四叉树 LOD:远处的行星先用廉价的多面体 proxy 表示。随着它在屏幕中变大,系统启用由 6 个 cube faces 投影到球面上的地形;每个面可以反复分成 4 个更小方块。这样只需细化可见区域和飞行方向附近的地形,靠近地面时再由 local patches 提供更细的几何。

共享高度场函数:粗细不同的网格都采样同一个行星生成函数。它组合 continents、mountain ridges、craters 和 smaller relief,并提供 elevation、water、biome 等信号;共享的颜色规则则帮助不同精度的表面保持外观一致。

这种高度场架构虽然在生成大规模地貌时极为稳定高效,但也存在天然的工程局限:每个地表法线方向只能容纳一个有效高度值。这意味着该系统无法原生支持垂直悬空的岩壁、多层重叠的溶洞或可被自由开凿爆破的地下隧道。


大气层平滑穿透:速度包线、互补遮罩与刚体物理

从太空接近地面时,飞行速度、地形流式加载和不同精度表面的交接必须一起处理。一次浅角接近行星的试玩暴露了这样的问题:

核心提示词(穿越优化): “当我以近乎贴着行星边缘的浅角切入时,速度依旧过快,地形来不及加载导致整颗星球几乎凭空消失。我们需要协同修正飞船的降速曲线与地形流式加载管线。是否能引入大气散射层来柔化远距离低模与近景高精度地形之间的突变?在接近地表的过程中,绝不能让行星出现哪怕一瞬的消失。”

针对这个问题,系统同时修改了飞行控制与网格切换逻辑:

浅角接近的独立速度上限:飞控根据高度,以及由行星半径与引力估算出的 orbital-speed,为浅角接近设置单独的速度上限。更靠近地面时,系统还会采样前方地形来调整制动。

旧表面等到新表面完整接班:远景行星继续显示,直到 6 个粗地形面全部就绪;一个 terrain tile 也继续保留,直到它的 4 个 children 全部就绪。交接期间,complementary pixel masks 把每个像素分配给旧表面或新表面,避免替代网格加载时整颗行星一起透明。

地表触地与离舰行走则引入了专门的物理管线处理:

Rapier 局部物理世界:角色在地表步行时,使用 Rapier 驱动的小型局部物理世界。

落地所需数据一起就绪:一个 contact patch 的可见地面、碰撞三角形和液体危险信息来自同一次生成,并且必须一起准备好。飞船的着陆逻辑还会分别检查脚部接触、坡度和净空。


掉帧背后的工程归因:受控基准下的数据治理

一帧变慢时,只看“卡不卡”无法判断浪费来自几何数量、数据传输还是被反复丢弃的任务。项目因此把玩家观察到的画面问题,转成可重复测量的浏览器测试。

在具体测试中,Astra 使用 Three.js renderer counters 检查 draw calls、triangles、geometries、textures;Playwright 采集 90 个 frame intervals,并报告 average 与 percentile timings。针对视觉故障,还可以比较某个效果启用和关闭时的 rendered pixels,例如对照地形开启与关闭 overlap-hiding mask 的结果,定位地面为什么消失,而不只是盯着一张故障截图猜原因。

在评估飞船资产替换时,Astra 在 WebGPU 后端,用 headless Chromium 和 SwiftShader 对前后版本运行同一个 90-frame orbital test:

评测维度 早期程序化生成机体 首版 Blender AURORA 机体
总场景绘制调用(Draw Calls) 119 次 77 次
总场景三角形面数 48,809 面 61,092 面
平均帧间隔耗时(SwiftShader) 251.48 ms 199.26 ms

如何读这组数字:新船的三角形更多,但这个特定测试里的 draw calls 和平均帧间隔都下降了。测试早于下文所示的四翼飞船,并且只反映该测试环境的变化,不是实际硬件上的游戏帧率;这些工具也没有测量单个 GPU 命令或 shader 执行时间。

围绕加载和下降过程,Astra 继续测量生成了多少几何、worker 与渲染器之间传了多少数据,以及多少地形任务尚未发挥作用就被丢弃。

按屏幕大小分配远景细节:填满视野的行星需要立刻有足够好的轮廓;小于一个像素的行星不需要相同几何。在受控起始场景对比中,两种策略使用同一个 geometry producer,新策略用了 7,040 个 proxy triangles,旧策略是 51,200 个。

用索引网格减少重复传输:相邻三角形可以复用顶点,不必重复传位置、颜色和法线。在 High 地形质量、6 个 ground layers、保持 241,952 个 triangles 不变的测试中,传输缓冲从约 35 MB 降到 15 MB。ground 与 scenery 也被拆成不同任务,让地面几何不必等待场景装饰。

稳定细分决策:旧 selector 会请求 chunks、改变决定、丢弃它们,再请求替代任务。改进后只有预算允许生成全部 4 个 children 时才细分一个 tile,减少尚未有用就被废弃的工作。

受控模拟环境下 9 秒测试中被丢弃的地形调度任务对比曲线图
6 秒下降、3 秒停稳、2 个 workers、100 ms 模拟延迟的受控测试中,废弃任务由 6,074 个降至 13 个;它测的是地形调度,不是帧率

Web Workers 仍不能解决所有停顿。主线程上的地形 fallback 也被拆成可恢复步骤,每帧使用约 4 ms 的预算,避免一项大型地形任务必须一次跑完。系统还把 world resolution 与 interface resolution 分开限制,让降低世界画质时导航文字依然清晰。即便如此,这些结果也不覆盖 shader 编译、GPU 上传、运动观感等问题,浏览器试玩仍然必要。


混合资产管线:从 2D 概念图到轻量化 3D 资产

Void Explorer 的宇宙环境主要由纯代码与数学算法生成,但作为视觉聚焦焦点的飞船,则需要依赖经典的美术资产管线进行精细化刻画。

在这个环节,工作流从“用生图探索造型”进入“把选中的二维参考变成可运行资产”:先由人锁定核心特征,再让 Astra 在 Blender 中推进建模并把结果加入游戏。

针对早期机体机翼黏连、造型扁平的问题,开发者给出了明确的局部修正指令:

核心提示词(机型重构): “请从多个视角生成该飞船的干净视图,重点突出前翼与后翼的分离结构。我们将根据这些图像重新制作 3D 模型。我不喜欢当前模型上那种连在一起的圆弧形机翼。”

生成的俯视概念图,展现分离式四翼结构与粉色翼尖灯
经确认选定的飞船概念图:包含四个独立的机翼面板、对称轮廓、翼尖粉色信号灯与象牙白陶瓷外壳

最终选中的是四片分离机翼、对称轮廓和粉色翼尖灯的参考图。接下来要求 Astra 在 Blender 中建立新模型、保持游戏的美术风格,并把它加入游戏。这个过程包括把参考图转成几何、检查轮廓与材质,以及准备运行时资产。Blender 源文件包含 193 个 editable meshes。

Blender 中渲染的飞船最终模型,带有陶瓷质感外壳与双发青色引擎
游戏中使用的飞船模型的 Blender 渲染图

最终导出的船体包含 14,968 个 triangles,并分成 8 个 opaque material batches。人可以继续要求模型细化外观,同时让 Astra 关注导出资产的渲染成本。


水体模拟的延伸:Sunwake 与 Hollowflux 的跨形态实践

“让同一套模拟同时服务画面和玩法”的做法,也出现在另外两款游戏中:

Sunwake:Astra 在 Three.js 中构建 custom water renderer,同一个 wave model 同时驱动可见海面与船体浮力。船体随波浪升降、俯仰和横滚;局部模拟负责 ripples 与 foam,船后留下 wakes 与 spray。随后再让 Astra 在 Blender 中制作更详细的船并加入游戏,形成“程序化环境 + 人工设计载具”的组合。

Sunwake 游戏实机截图:橙色小船在波光粼粼的蓝色多面体波浪中划出白色泡沫航迹
Sunwake:程序化海洋与 Blender 制作的船体结合

Hollowflux:这款 2D action RPG 的洞穴、角色和装备都由代码绘制,没有导入 sprite sheets。一个 grid cells 系统跟踪 water height、currents、foam 与 electrical charge。

Hollowflux 游戏实机截图:像素角色涉过发光的青色地下河,激起层层涟漪
Hollowflux:水体会响应移动与战斗,并参与电荷传播

这里的水不只是视觉效果。脚步会留下涟漪,长矛划出狭窄尾迹,锤击发出环状波纹;水流会沿河岸卷动、把泡沫带向下游,也会推动玩家和敌人。电鳗的放电沿连通水域传播,站上干燥石面则能避开这次放电。


一键部署与独立开发者的起步建议

游戏准备好分享时,可以使用 Codex 的 @Sites 插件要求部署并取得链接:

Use @Sites to deploy this game and give me a link.

将站点设为公开访问后,其他人就能直接在浏览器里游玩。

如果想用 Astra 尝试游戏开发,可以从一套具体的方法起步:

  1. 只选一个首先要“感觉对”的东西:一艘船、一个房间或一个交互就足够。先做出可玩的最小版本,不必从完整宇宙开始。
  2. 给出少量视觉参考,再靠实际试玩反馈:先让 Astra 看清你期待的外观;拿到版本后亲自操作,明确说出哪里太快、哪里消失、哪种颜色不一致,而不是只说“感觉不好”。
  3. 尽早建立可重复检查:为主要阶段准备 repeatable scenes、state and performance counters 与 browser tests。人类继续判断外观与操控手感,Astra 则可以追踪代码、建立可重复测量、实施修改并复测。把这套循环跑起来,再逐步扩大游戏范围。
来源
Building games with Astra查看主材料
本站说明
OpenAI Developers