我用 GPT-5.6 Sol 做了一个 3D 治愈星球
《球的另一边》从粗糙的第一版、方向键反了、角色失败,到原创 GLB、球形小城、三段故事和双域名上线的完整复盘与 Master Prompt。

我最早想做的不是一个射门小游戏,而是一座可以走进去的世界杯小城。
整座城建在一颗很小的球形星球上。玩家一直往前,会回到同一个路口。路还是那条路,但遇到的人、听见的声音和最后留下的东西,会因为选择发生变化。
这就是 《球的另一边 / The Other Half》。它现在是一段 5–8 分钟的 3D 网页故事,手机和电脑都能直接玩,不用登录,运行时也不调用 AI。
先看正式演示
这次对话的正式演示已经发布在 B 站。下面嵌入的是原视频,不是后来补做的假素材。
在 B 站打开《GPT-5.6 编程实测二:3D 治愈星球》
真实起点:想做一个球形星球上的世界杯故事
最初需求已经很具体,甚至把情绪、世界结构和交互方式都写了进去。
制作并部署一个可直接游玩的 3D 网页故事《球的另一边 / The Other Half》,域名为 otherhalf.01mvp.com,部署到 Cloudflare Workers。
背景是世界杯期间的一座治愈 cel-shaded 小城,整座城建在一颗小小的球形星球上:玩家一直往前走,最终会回到同一个路口,但人物与世界会因选择而变化。玩家是临时信使,首版包含 3 个短故事:丢失票根的老人、不敢进场的小孩、想匿名散步的 10 号球员。没有任务箭头,用靠近、对话、交付物品推进;结局生成可分享的“比赛日明信片”。
我们参考的是:Messenger(by Abeto)是一款在小小球形星球上扮演送信员的休闲浏览器游戏。你往任何方向走,最终都会回到原点,就像界王星一样。画风是治愈的 cel-shaded 卡通风格,配 lo-fi 音乐,没有教程、没有指引,就是自由探索和对话。
优先做 5–8 分钟完整体验,视觉和情绪优先于复杂玩法;适配手机与桌面,支持键盘/触屏移动。配乐用浏览器内生成的 lo-fi 环境声,提供静音按钮。不要使用 FIFA、真实球星姓名、肖像或官方标识。完成后执行构建、测试、部署,并给出线上链接。这份需求里有两个容易冲突的目标。
一边是「没有任务箭头,自由探索」;另一边是「用户打开就知道该做什么」。一边想要接近获奖网页的视觉完成度;另一边只有浏览器、Three.js 和一段很短的开发周期。
真正的工作不是把需求逐条变成按钮,而是找到两边都能成立的取舍。
第一版为什么不够好
第一版能打开,也能走,但它没有形成一个可信的世界。
用户的反馈很直接:画面不够精致,之前生成的小女孩图片还留在首页,场景里随便贴了几张图,人物模型很奇怪,足球和世界杯气氛也不够。更严重的是,方向键映射反了,按左边角色会往画面右边走。
这不是「再加一点阴影」能解决的问题。它同时暴露了四件事:
- 参考变成了模仿压力。 如果只是追着 Messenger 的构图走,最后只会得到一个更粗糙的复刻。
- 角色是视觉中心。 第三人称游戏里,玩家一直盯着角色背影。角色不可信,整座城也会显得像临时 Demo。
- 操作错误会毁掉所有美术。 左右方向反了以后,再漂亮的世界也不值得探索。
- 世界没有目的感。 没有开场介绍、热身引导、当前线索和镜头说明,玩家进来只会懵。
当时最关键的一条纠正是:
我们不是要直接复刻他的 App,我们是要做一个自己的版本。角色得改,画面也要更精致。可以换成足球主题,一个小男孩不断踢足球,逛完整个世界杯现场。人物走动时应该是真正的 3D,他能够看到这个世界,交互要好玩,音乐要舒缓。这条反馈把项目从「模仿一个参考」拉回了「做自己的足球故事」。
七轮迭代,修的不是同一个问题
| 阶段 | 当时的问题 | 真正完成的变化 |
|---|---|---|
| 初版 | 粗糙角色、无关图片、足球氛围弱、方向相反 | 承认不是视觉小修,重新定义原创方向 |
| 角色轮 | 只有解决男孩,没有解决整个游戏 | Meshy 生成原创男孩,Blender 清骨骼、合并动作、导出 GLB |
| 世界轮 | 场景仍像拼贴,故事没有第一眼获得感 | 重建比赛日街区、看台、人群、彩旗、灯光和首次踢球反馈 |
| 引导轮 | 进来不知道做什么,Shift 不明显,动作找不到 | 加入开场介绍、四步热身、跑动、动作面板和实时线索 |
| 镜头轮 | 只能移动,不能自由看世界 | 加入拖拽环视、跟随/近景/广角、上下左右和复位控制 |
| 本地化轮 | 首页只有中文,英文页面仍混入中文 | 浏览器自动选中英文、纯单语 UI、URL 覆盖和持久切换 |
| 发布轮 | 只能用一个域名访问 | 一个 Worker 同时服务两个自定义域名,不做跳转 |
项目最后没有偏离最早的三个故事。闻伯在找旧票根,小满不敢进场,匿名的十号只想在没人认出的街上散步。变化在于,它们从三段文案变成了可以沿着一整圈星球逐步触发的关系。
不做复刻,保留的是「走一圈回来」
参考作品最打动人的,不是某一栋楼或某一个角色,而是空间结构:玩家沿着一个小世界走,迟早会回到原点。
《球的另一边》保留了这个感受,但换掉了主题和体验目标。
- 参考里的送信,变成了比赛日前替人传递物件和心意。
- 自由漫游,变成了有一条主街、但没有悬浮任务箭头的轻叙事。
- 安静星球,变成了会被第一脚球逐步叫醒的世界杯小城。
- 回到原点,不只是空间循环,也是结局条件:三段故事完成后,白色路口才会生成明信片。

球形世界不是用视觉假象伪装的。地面是一颗真正的球,街道、建筑、人物和交互物都沿球面法线放置。玩家移动时,代码会重新计算脚下的局部「上方」、前进方向和画面右侧方向,再更新角色姿态与镜头。
这也解释了最早的左右错误。第三人称镜头下,世界坐标的左和玩家看到的左不是一回事。最后把移动拆成两个可以单测的向量函数:
screenRight = normal × forward
heading = routeHeading around normal by cameraYaw输入永远相对当前画面计算。按右就是屏幕右,不会因为角色走到星球背面或镜头转过角度再次反向。
原创男孩 GLB 是怎么解决的
角色一开始是项目最大的短板。用户后来主动配合:登录 Meshy、安装 Blender,并提供了 Meshy 导出的带骨骼角色和多个动作文件。
真正可用的 Web 角色不是「下载一个 GLB」就结束。不同动作文件各自带着一整套网格、骨骼和蒙皮,直接全部加载会重复模型,也容易让动画找不到同一套骨骼。
最后的处理流程是:
- 在 Meshy 生成原创男孩并自动绑定骨骼。
- 下载 Walk、Running、Casual Walk、Agree Gesture、Dance、Attack 等带蒙皮动作。
- 用 Blender 脚本保留一套网格和骨骼,把动作复制到同一份角色上。
- 清理空对象、无用材质槽和重复数据,统一角色高度与脚底原点。
- 因为 Meshy 的 Idle 多次添加失败,在 Blender 里生成一个轻微呼吸和重心变化的循环 Idle。
- 导出一份约 6.7 MB 的 GLB,并逐个预览动作、检查骨骼和包围盒。
正式角色只有一套骨骼,包含八个可用动作:Idle、Walk、Jog、Stroll、Kick、Trick、Celebrate、Agree。
游戏会根据速度在 Idle、Walk 和 Jog 之间过渡。踢球、点头、花活和庆祝是一次性动作,播放后再平滑回到移动状态。角色不再是一张面向镜头的图片,而是一个真正站在球面上、能被自由镜头从不同方向看到的 3D 人物。
模型由 Meshy 为本项目生成并在 Blender 整理,仓库按 CC BY 4.0 提供并明确署名。代码使用 MIT License。这里没有使用 FIFA 标识、真实球星姓名、肖像、球队徽章或官方赛事视觉。
没有任务箭头,不等于没有引导
这个项目中间有一次很重要的产品纠偏。
最初坚持「没有教程、没有指引」,结果用户进入后根本不知道怎么跑、怎么转镜头、怎么找动作,也不知道剧情从哪里开始。完全自由只对已经理解规则的人自由,对第一次打开的人只是信息缺失。
最后保留了「没有悬浮箭头」,但增加三层轻引导:
- 开场页先讲清角色和目标。 你是临时信使,要带着球绕世界一圈,完成三次传递,再回到路口。
- 四步热身只教身体操作。 走两步、跑起来、转动镜头、亲自踢出第一脚。每一步都必须由玩家完成,不自动代打。
- 当前线索只说人物和地标。 比如「沿主街去找路口的闻伯」,不在 3D 世界上画一条导航线。
这让玩家知道下一步做什么,又没有把探索变成跟着箭头上班。
三段故事用一个很小的状态机串起来
故事没有任务系统、数据库和后端。src/story.ts 只维护几个明确状态:闻伯是否开口、票根是否找到、三个故事分别选了什么。
人物的反应由当前状态决定:
- 没问过闻伯时,风铃只是街边物件。
- 闻伯说出票根后,轻轻踢中风铃才会让半张票落下来。
- 把票交回去以后,小满才愿意谈自己为什么不敢进场。
- 小满做出选择后,匿名十号才会接住你的传球。
- 三段故事完成、重新回到白色路口,才进入结局。

每段故事都有两个选择,但不判对错。你可以替旧票根补上缺角,也可以让它保留原来的缺口;可以陪小满慢慢进门,也可以和他坐在门外听完上半场;可以给十号建议,也可以什么都不问,只在长椅旁留一个位置。
选择只改变人物的回应和最后明信片上的句子。这比积分和成就更适合这座安静的小城。
声音不是找来一首歌循环播放
项目最早就要求 lo-fi 音乐,但最终没有下载一首「无版权 BGM」放进仓库。
src/audio.ts 用 Web Audio API 在浏览器里实时生成完整声音:
- 74 BPM、32 小节的和声结构,主调在 D 大调和 B 小调之间移动。
- 和弦、贝斯、鼓、旋律和磁带噪声分别走独立音量通道。
- 完成故事以后,编曲逐步增加层次,让小城真的像慢慢醒来。
- 踢球、风铃、首次唤醒和对话确认都有短促的合成反馈。
- 静音按钮直接控制总线,不依赖系统播放器。
浏览器只会在用户点击「进入比赛日」以后创建 AudioContext。这是为了符合 iOS 和 Safari 的自动播放限制。标签页恢复或用户再次点击静音按钮时,代码也会唤醒被浏览器暂停的声音上下文。
这种做法的好处是许可清楚、没有音频请求,也能让音乐跟故事进度变化。缺点是合成音色没有真人录音自然,而且不同设备的扬声器表现会有差异。这个项目选择的是可控、轻量和与互动同步,而不是追求一首独立发行的成品音乐。
手机端不是把桌面缩小

桌面使用键盘、拖拽镜头和右上角控制面板。手机使用左侧摇杆、跑动和踢球按钮,拖动画面仍然可以自由环视。
性能上做了几项很实际的限制:
- 桌面设备像素比最高 1.6,手机最高 1.25,避免高分屏把渲染量翻几倍。
- 手机关闭动态阴影,并允许移除装饰性墨线轮廓。
- 城市主体由低面数几何体和共享
MeshToonMaterial组成,重复颜色复用材质。 - 天空、店面和人物肖像统一转成 WebP。
prefers-reduced-motion会减少界面动画。- 角色只加载一份合并 GLB,不为每个动作重复下载模型。
当前最大的加载成本仍然是约 6.7 MB 的角色 GLB,主 JavaScript 构建后约 685 KB、gzip 后约 186 KB。这个版本已经能在手机完成全流程,但如果继续做下一版,最值得先优化的是 Draco/Meshopt 压缩角色和拆分 Three.js 主包,而不是继续往场景里堆小物件。
中英文和两个域名最后才真正收口
有一版首页加了中英文按钮,但英文模式仍然会看到中文标题、中文对话或中文无障碍标签。这不算完整本地化。
正式版本的规则是:
- 第一次访问读取
navigator.languages[0],zh-*使用中文,其余语言使用英文。 ?lang=zh和?lang=en可以为分享链接指定语言。- 用户手动切换后,偏好写入
localStorage。 - 英文模式的可见 UI、对话、线索、元数据、标题和无障碍标签全部是英文。
- 首次本地化完成前隐藏页面,避免先闪出错误语言。
部署也没有复制两份网站。wrangler.jsonc 把两个自定义域名同时绑定到同一个 Cloudflare Worker:
两边都直接返回同一份静态资源,不做 301 跳转,所以用户从哪个域名进入,地址栏就保留哪个域名。
结局为什么一定要有明信片
走回原点如果只显示「任务完成」,前面五分钟的情绪会突然变成打卡。
结局用 Canvas 把当前 3D 画面、三次选择和日期合成一张比赛日明信片。它不是一个固定结果图,同一座城会因为玩家如何对待三个人,留下不同的三句话。

支持系统分享的设备会尝试分享图片;其他环境仍能保存或再次走一圈。分享发生在浏览器本地,不上传玩家数据。
构建、测试和 Cloudflare 部署
技术栈很克制。
| 模块 | 技术 | 负责什么 |
|---|---|---|
| 3D 世界 | Three.js | 球形星球、城市、灯光、角色、镜头和动画 |
| 页面与规则 | TypeScript、原生 DOM | 引导、语言、故事状态、交互和明信片 |
| 音乐与音效 | Web Audio API | lo-fi 编曲、磁带质感、踢球和提示音 |
| 构建 | Vite | TypeScript 与静态资源生产构建 |
| 单元测试 | Vitest | 故事状态、左右移动和镜头角度 |
| 旅程测试 | Playwright | 中英文、桌面、手机、三个故事和结局 |
| 部署 | Cloudflare Workers Static Assets | 一个 Worker、两个自定义域名 |
本地运行:
git clone https://github.com/makerjackie/the-other-half.git
cd the-other-half
npm install
npm run dev发布前验证:
npm test
npm run build
npm run deploy:dry
npm run deploy单元测试目前是 2 个文件、7 个测试。浏览器冒烟测试会真实完成浏览器语言识别、镜头旋转、跑动、四步热身、三段故事、重新绕回原点和明信片,并再跑一遍手机视口。
部署后的两个域名都返回 HTTP 200,没有重定向,并且加载同一份构建资源。
这次真正踩过的坑
1. 左右方向不能靠肉眼改一个负号
早期按左往右,最诱人的修法是把 x 乘以 -1。但镜头转动、玩家走到星球背面后,它还会再次错。
正确做法是定义局部球面坐标,再用测试覆盖「画面右侧」和「镜头绕本地上轴旋转」两个函数。这样修的是坐标模型,不是某一帧的现象。
2. 一个好看的角色截图,不代表角色能进游戏
Meshy 能快速给出轮廓和骨骼,但 Web 项目还需要统一蒙皮、动作命名、根节点、脚底原点、尺度、循环方式和文件体积。Blender 的清理与验证脚本和生成本身同样重要。
3. 「没有教程」很容易变成「没有体验」
不显示任务箭头可以保留探索感,但移动、镜头和核心动作必须在第一分钟教会。热身步骤是操作教学,故事线索是叙事提示,两者不需要变成传统任务列表。
4. 英文按钮不等于英文适配
要检查 HTML 初始内容、运行时对话、aria-label、页面标题、弹窗、明信片和语言切换中途的状态。最后用真实 zh-CN 与 en-US 浏览器上下文分别跑完整流程,才能发现漏网的中文。
5. 自动录制不一定比手动录制可靠
项目里曾经有浏览器自动录屏脚本,但最终发布视频由用户自己录制并上传 B 站。公开仓库排除了录屏脚本、临时输出、设计审查图和内部笔记,只保留产品代码、可复现测试和角色处理脚本。
GPT-5.6 Sol 真正发挥了什么作用
它没有在运行时扮演 NPC,也没有为玩家临时写剧情。游戏上线后不接任何 AI API。
AI 真正参与的是开发过程:
- 把口语需求整理成可以实现的体验边界。
- 在参考图和用户否定之间重新判断原创视觉方向。
- 编写 Three.js 球面坐标、镜头、动画混合、故事状态和 Web Audio。
- 为角色、天空、店面和人物肖像探索素材方向。
- 编写 Blender 脚本,把多个动作整理成一份可用 GLB。
- 根据「方向反了」「看不了左右」「不知道下一步」「英文里还有中文」这些反馈持续改代码。
- 用 Vitest 与 Playwright 把用户反馈变成以后不会回归的验收项。
- 完成构建、Cloudflare 部署、双域名和线上验证。
用户也不是只写一句 Prompt 等结果。角色素材需要用户登录 Meshy、处理下载失败并把导出包交回来;视觉、操作和引导是否成立,也需要用户一次次明确说「不对」。
这次最能体现 GPT-5.6 Sol 能力的,不是第一版写得多快,而是它能不能在一段很长的协作里保留最初目标,接受多轮否定,把审美反馈翻译成坐标、骨骼、镜头、声音、状态和测试。
真正改变项目的关键迭代指令
下面保留原话中的核心段落,只去掉了口头重复,没有把它们改写成事后才有的专业 PRD。
这个截图就是这个游戏原始的模样,它会精致很多。现在这个方向不太对,而且方向键也走错,我按左边是往右边走的。人物模型也有很大的问题。把你作为一个非常极其优秀的产品经理,再度考虑一下怎么优化。
我们不是要直接复刻他的 App,我们是要做一个自己的版本。角色什么的也得改一改。可以换一个大家感兴趣的主题,比如足球。人物在走动的时候应该是 3D 的,他能够看到这个世界,交互要好玩,音乐也比较舒缓。
需要一套轮廓优秀、骨骼干净、包含基本动作的原创男孩 GLB。这个怎么解决?你能生成吗,或者我怎么配合你?
你现在只是解决了原创男孩的问题,整个游戏还是没有按前面的方向优化。现在的画面跟世界杯和足球没什么关系。还是基于当前基础,想想怎么让用户第一眼惊艳,交互起来马上有获得感。
网页打开的时候,之前那张小女孩图片还在,把它删掉。用户进来有点懵,不知道下一步干嘛。没有地方切换视角,Shift 好像也跑不起来,动作也找不到。应该有游戏介绍页面和新手介绍。
首页只有中文,要加英文。全局视角无法左右和上下转换。你自己判断还有哪些可以优化,再做一轮。
首页没有根据浏览器自动选择中英文,英文页面里为什么会出现中文?另外希望 otherhalf.oneapps.studio 也正常显示这个网站,不是重定向,地址栏还保留这个域名,而且只使用一个 Worker。这些反馈的共同点是描述体感和验收结果,而不是替 AI 写实现。它们给了足够明确的「哪里不对」,同时保留了技术方案的空间。
可复制的 Master Prompt
如果今天从零重做,我会直接使用下面这份 Prompt。它不会保证一次生成最终成品,但会把这次最贵的坑提前变成约束和验收标准。
请设计、实现、测试并部署一个 5–8 分钟可完整玩完的 3D 浏览器故事,项目名为《球的另一边 / The Other Half》。不要只给计划,要直接完成可以上线的作品。
一、产品目标
故事发生在世界杯期间的一座治愈小城。整座城建在一颗很小的球形星球上。玩家沿主街一直前进,最终会回到同一个白色路口,但人物、灯光、声音和结局会记录玩家的选择。
玩家是临时信使,也是街上唯一带着足球的人。体验重点是视觉、情绪、探索和人与人之间的小事,不是竞技、积分或开放世界规模。第一眼要让人愿意截图,第一分钟要让人知道如何移动、看世界和踢出第一脚。
二、原创边界
- 可以参考小型球形星球、自由漫游和 cel-shaded 浏览器作品的空间感,但不得复刻任何现有游戏的角色、建筑、界面、剧情、Logo 或素材。
- 使用原创虚构人物和原创赛事氛围。
- 不使用 FIFA、世界杯官方标识、真实球星姓名、肖像、球队徽章、球衣或转播包装。
- 不要把 AI 生成的一张角色图片当成第三人称玩家。主角必须是真正有骨骼和动作的原创 3D GLB。
三、完整体验
- 开场页用一屏讲清楚:你是谁、要做什么、预计 5–8 分钟、支持键盘和触屏、结局会生成明信片。
- 点击开始后,用四个就地热身步骤教会移动、跑动、自由镜头和第一次踢球。每一步必须由玩家亲自完成。
- 世界里不显示悬浮任务箭头。右下角只提供当前人物或地标线索。
- 三段故事按一圈街道依次展开:找回老人丢失的半张票根;帮助不敢进场的小孩;让想匿名散步的十号球员短暂做回普通人。
- 推进方式只使用靠近、逐句对话、踢球、接球和交付物品。
- 每段故事给两个没有标准答案的选择。选择改变人物回应和结局文字,不使用好坏积分。
- 完成三段故事后,玩家必须继续走回最初路口。浏览器用当前 3D 画面和三次选择生成可分享的比赛日明信片。
四、3D 世界和视觉
- 使用 Three.js 和 TypeScript,世界必须是一颗真实球体,不是循环平面或远景贴图假装的弧度。
- 玩家、NPC、建筑和道具根据球面法线放置。移动到星球背面时,角色仍保持脚朝地面、头朝外。
- 使用温暖、治愈、手绘感的 cel-shaded 风格:toon gradient、深色墨线、奶油墙面、青绿色天空、比赛日彩旗、灯光、人群、看台和街边摊。
- 主角是原创男孩,轮廓从背面也要清楚,骨骼干净。至少包含 Idle、Walk、Jog、Kick、Celebrate 和一个手势动作。
- 如果 3D 生成平台为每个动作导出一整套角色,使用 Blender 只保留一套网格与骨骼,合并动作、清理材质与空对象、统一尺度和脚底原点,导出单一 GLB。
- NPC 可以用低多边形 3D 身体配合原创肖像,但不能在首页留下与主角不一致的 2D 替代角色。
五、操作和镜头
- 桌面支持 WASD 与方向键移动,Shift 跑动,Space 踢球,E/Enter 对话。
- 手机支持左侧摇杆、跑动和踢球按钮。
- 移动必须相对当前屏幕方向计算。无论镜头朝向或玩家在球体哪个位置,按左永远向屏幕左移动,按右永远向屏幕右移动。
- 支持在场景上拖拽进行自由环视,包括左右和有限范围的上下视角。
- 提供跟随、近景、广角三种景别,以及回到角色身后的复位按钮。桌面支持 C 切换、R 复位,手机和桌面都有可发现的 VIEW 面板。
- 镜头不能翻转到地面下,也不能因为环绕角度改变移动方向。
- 动作面板提供踢球、点头、足球花活和庆祝。跑动与动作要有清楚的视觉反馈。
六、声音
- 不下载来源不清楚的背景音乐。
- 优先用 Web Audio API 在浏览器内生成 70–80 BPM 的 lo-fi 环境音乐,包括和弦、贝斯、轻鼓、旋律和磁带质感。
- 音乐编排随故事进度逐步增加层次,踢球、风铃、交互确认和城镇唤醒要有不同音效。
- AudioContext 只能在用户首次点击后创建,兼容 iOS/Safari 自动播放限制。
- 永久提供静音按钮。切到后台再回来时,要能恢复被暂停的 AudioContext。
七、中英文
- 第一次访问读取 navigator.languages[0]:zh-* 显示中文,其他语言显示英文。
- 支持 ?lang=zh 与 ?lang=en 覆盖,并用 localStorage 保存用户手动选择。
- 英文模式不能出现中文可见文案,包括首页、对话、线索、按钮、标题、明信片、加载状态和 aria-label。
- 初次本地化完成前隐藏页面,避免错误语言闪烁。
- 切换语言时关闭当前对话和临时提示,并重新渲染当前故事状态与明信片。
八、性能和移动端
- 390 × 844 手机视口与 1440 × 810 桌面视口都要完整可用,不横向溢出。
- 手机设备像素比上限约 1.25,桌面约 1.6。
- 手机关闭高成本动态阴影,装饰性轮廓允许降级。
- 重复颜色共享材质,纹理统一使用 WebP。
- 只加载一个合并后的角色 GLB,不为每个动作重复角色数据。
- 支持 prefers-reduced-motion。
- 构建输出如果主包超过 500 KB,要明确报告,并给出下一步的拆包与模型压缩建议,不要假装没有性能问题。
九、状态、明信片和隐私
- 故事状态使用可测试的纯 TypeScript 状态机,不需要数据库。
- 明信片在本地 Canvas 生成,包含当前游戏画面、三次选择和项目网址。
- 支持时使用 Web Share API 分享图片;不支持时提供保存或复制链接的退路。
- 不上传玩家选择,不要求登录,不接入分析以外的运行时服务。
十、运行边界和许可
- 游戏运行时不得调用 OpenAI、GPT、图像生成、3D 生成或任何 AI API。
- AI 只在开发阶段参与创意、代码、素材探索、Blender 脚本、测试和部署。
- 代码使用 MIT License。
- README 必须列出所有视觉、3D 和音频素材来源与许可。
- 原创生成素材也要写清生成工具、后期处理和再分发条款。
十一、测试与验收
- 为故事状态写单元测试,覆盖前置条件、三段选择和结局文案。
- 为球面移动写单元测试,明确验证屏幕左、屏幕右、镜头 yaw 和 pitch 限制。
- 用真实 Chromium 完成一遍桌面全流程:语言识别、开场、四步热身、跑动、拖拽镜头、VIEW 面板、三个故事、回到原点和明信片。
- 再用 390 × 844 触屏视口验证摇杆、跑动、踢球、对话和镜头。
- 分别使用 zh-CN 与 en-US 浏览器上下文,检查英文可见文本不含中文字符。
- 运行 npm test、npm run build 和 Cloudflare dry run。
- 部署后检查 HTML、JS、CSS、GLB、五张案例图和两个自定义域名都返回 200。
- 两个域名必须绑定同一个 Cloudflare Worker,不做重定向,地址栏保留访问时的域名。
十二、工作方式
先检查现有代码、素材和 Git 状态,再实现。每轮只解决当前最大的体验问题,并用真实浏览器截图验证。不要把“代码能运行”当成“产品已经成立”。
看到用户说“画面不对”“角色很怪”“方向反了”“不知道做什么”“镜头不能转”“英文里还有中文”时,把反馈翻译成可以复现的测试、视觉差异或交互验收,再修改实现。
完成后输出公开 GitHub 仓库、MIT License、README、素材许可、Cloudflare 线上链接、构建与测试结果。排除密钥、录屏脚本、临时输出、设计审查图和内部笔记。最后留下来的产品判断
这个项目不是一次生成的。第一版失败、角色单独重做、世界重新搭建、引导补回去、镜头重新设计、本地化返工、双域名收口,每一轮都来自一个真实的不满意。
如果只看最终代码,很容易把它总结成「Three.js 做了一个球形世界」。但真正让它成立的是几条更朴素的判断:
- 参考作品应该拆出体验原理,不能照着画面复刻。
- 第三人称角色值得单独做完整资产管线。
- 操作手感比场景细节更优先,方向错了必须先修坐标模型。
- 没有箭头可以,但不能没有开场、热身和线索。
- 音乐、灯光和故事应该一起随进度变化。
- 英文适配要以真实英文浏览器验收,不以「有切换按钮」验收。
- AI 开发的价值在持续协作和收口,不在运行时硬塞一个聊天框。
《球的另一边》可以直接在线玩,完整源码在 GitHub。代码、案例和上面的 Master Prompt 全部免费,没有会员墙。
想交流 GPT、Codex 和 AI Coding 的真实使用体验,也可以扫码加入 01MVP 交流群。

这篇文档有问题?