00 / 00

我用 GPT-5.6 做了一个世界杯 3D 点球游戏

Last Kick 从一句天马行空的想法,经过无聊的第一版、玩法重做、声音与难度打磨,最后上线的完整实战复盘和提示词。

Last Kick 的 120 分钟生死球开场

事情是这样的。

GPT-5.6 出来后,我最想做的不是再写一个聊天框,也不是给网站接一个 API。我想看看,它能不能做出一个真的让人有感觉、愿意录下来发抖音的网页作品。

一开始我的脑洞很散。3D 小游戏、网页版侠盗猎车手、像 Messenger 那样在球形星球上散步,甚至还想过把世界杯、球星和偶遇故事全塞进去。

后来我们把它砍成了一个很小的东西。

三脚球,一堵墙,一个会记住你的门将。

这就是 Last Kick。你可以先去玩一局,再回来读这篇复盘。完整源码也放在 GitHub,使用 MIT License,文章和提示词全部公开,没有会员墙。

最重要的约束,不接运行时 AI

我很早就补了一条要求。

做完之后不需要接入任何 API。用户打开网页,就能体验全部功能。AI 只在开发阶段参与,游戏运行时不需要用户输入语音,也不会调用模型。

这条约束反而帮了大忙。

我们不需要为了证明用了 GPT-5.6,硬塞一个聊天框进去。模型负责开发阶段的创意、代码、测试、素材判断和迭代,浏览器负责把最终作品跑起来。

页面加载后,所有 3D 场景、射门判定、门将动作、音效和分享图都在本地完成。没有服务端推理,没有按次计费,也不会因为模型接口超时,让球停在半空中。

如果你也在做 AI 产品,我觉得可以记住这件事。一个作品由 AI 做出来,不等于它运行时也必须有 AI。

第一版能跑,但真的很无聊

第一版很快就出来了。

有球门,有足球,能按住、拖动、松手。门将也会扑,技术上没什么大问题。

但我的第一反应是这样的。

哎呀,我有点难过,因为你这个很无聊,这操作起来没有任何感受啊,没有任何让人觉得很兴奋的点,这个创意也不太行。

挺直接的,但它救了这个项目。

AI 很容易把「功能存在」当成「体验成立」。按钮点得动,球也飞出去了,于是任务完成。可游戏不是表单,玩家松手的那一刻,镜头、声音、运动、等待和结果必须一起给出反馈。

能射门,不等于想再射一脚。

从这里开始,我们没有继续堆球员、比赛和地图,而是把问题改成了一句话。

一个抽象球场,一次拖拽射门,一次全场爆发,能不能在十几秒内让人紧张起来?

这个问题比「做一个世界杯游戏」小得多,也具体得多。

不做拟真人物,观众变成一台情绪机器

我很担心模型做出一批粗糙的小人。脸不像脸,动作也不自然,最后会变成那种一眼就知道是技术 Demo 的 3D 页面。

所以我们干脆不追求拟真。

门将用切面几何体拼成,观众也不是一个个人。看台由上万张折叠卡片组成,平时像一圈压住情绪的纸片,进球时一起翻成珊瑚红,再像机械波一样向外炸开。

我们还试了发光信号柱和纸鸟群两个方向。静帧都挺酷,但真正踢起来,折叠卡片最像足球场,也最能把「一万人同时起身」做出来,所以保留了它。

由程序生成的球场、门将和折叠观众

这里有个我很喜欢的取舍。做不了可信的人,不代表做不了可信的情绪。

Three.js 最有价值的地方,也不只是做出一个 3D 物体。它让镜头、灯光、雨、球网、看台和声音可以围着同一个瞬间一起工作。

Vozinha 让这三脚球有了故事

只有抽象视觉还不够。球门对面如果只是一个无名 NPC,玩家很难在意他扑不扑得到。

我当时突然想到佛得角门将 Vozinha。用户讨论里出现的这个门神梗,刚好能给小游戏一个很短、但很具体的故事。

于是开场变成了加时赛第 120 分钟,比分 1 比 1。你只有三脚,Vozinha 站在门前,而且他会记住你的上一脚。

重复同一种射法、同一侧,他就会提前读到。

这不是随机写一句「门将看穿了你」。代码里真的保存了上一脚的方向和射法。第二脚继续照抄,门将就会偏向那一侧完成扑救。换边,或者换成弧线、勺子,球门才会重新打开。

一个不到一分钟的小游戏,到这里终于有了对手,也有了可以讲给朋友听的规则。

三种射法,进球不能靠抽奖

游戏一度太容易。随手一拖就能进,第一次挺爽,第二次就没意思了。

但我也不想在后台掷骰子。玩家明明踢得一样,这次进、下次不进,只会觉得游戏在耍赖。

最后用的是确定性判定。每一种射法都有自己的力量和落点窗口。

射法进球思路常见失败
爆射力量超过 64%,压向左下或右下力量不足,或者打得太正
弧线力量超过 52%,瞄准更宽的远角弧度不够,进入门将覆盖区
勺子力量控制在 45% 到 78%,走中路太轻被没收,太重撞横梁

蓄力过程中,瞄准区和力量条会实时告诉你现在是偏轻、正好还是过量。射丢后也不只显示「未进」,而是告诉你这脚究竟是力量不够、位置不对、勺子过头,还是重复套路被看穿。

脚本里的新手输入模型,单脚进球率约为 13.9%,三脚结束只进零到一个球的概率约为 94.7%。这是用于调参的模拟模型,不是真实玩家统计,但它至少能防止我们凭感觉把球门调成海底捞甩面那么宽。

难,但能学会。

这个平衡比随机进球更重要。玩家输掉一脚,还会觉得下一脚能靠自己纠正。

紧张感不是一个滤镜

后面那轮改动,几乎都围着出脚前后的两秒钟。

按住足球后,镜头会慢慢推近,球场环境声开始往下收,心跳越来越快。蓄力进入甜区,界面颜色改变。松手的一瞬间短暂静音,镜头切到飞行路径,球撞到手套、门柱、球网时再把声音砸回来。

进球不是只有一声欢呼。球网会变形,灯光和曝光会抬起,看台翻色,镜头震动,真实球场录音叠在 Web Audio 合成的击球、风切和低频上。

没进也不能没反应。扑救有手套撞击和人群叹息,门柱有金属声和回弹,横梁会给你一个更干脆的失败节奏。

弧线球入网后的灯光、球网和看台反馈

一开始的雨声也踩过坑。合成噪声太吵,听起来不像雨,反而像收音机坏了。后来换成了本地托管的 CC0 轻雨录音,并把音量压到只剩一层空气感。进球欢呼和扑救后的失望声也使用了本地 CC0 素材,来源和处理方式都保留在仓库里。

声音不需要一直提醒你它存在。真正有用的是,它能把出脚前的安静和入网后的爆发拉开。

开场不能是一张说明书

有一版开场把三步操作写得特别大。

选择爆射、弧线或勺子,按住足球蓄力,松手射门。

信息没错,但看起来像产品说明书。放进短视频,观众第一秒看到的是教程,不是比赛。

后来我们把它改成比赛转播式开场。屏幕先出现 120 分钟、1 比 1 和剩余三脚,再给出一句很短的挑战。操作提示放回球旁边,玩家真正按下去时才出现。

这是一个挺小的改动,但它改变了用户怎么理解这个网站。不是「请先学习如何操作」,而是「比赛已经到最后一刻,现在轮到你」。

分享的不是链接,是我刚刚经历的那一脚

最早的分享按钮只会唤起系统面板。能分享,但用户不知道自己到底发出去什么。

后来每局结束,浏览器会直接生成一张 1080 × 1920 的竖版战绩图。里面有最后一脚的真实 WebGL 画面、进球数、射法、力量、称号和 lastkick.01mvp.com

支持文件分享的手机会带着图片打开系统分享面板。其他浏览器会保存 PNG,并复制挑战链接。

Last Kick 在浏览器里生成的竖版挑战战绩图

传播感不是多放一个分享按钮。它来自一件更具体的事,我有一个结果,而且我想让朋友来挑战它。

视频清晰度这块,我也翻车了

为了给横版和竖版视频自动出片,我最早让脚本连续抓取浏览器截图,再交给 FFmpeg 拼成视频。

文件信息看起来很正常,1080p、30fps、码率也不低。

真正播放起来却发糊、卡顿。

后来检查时间轴才发现,活动画面实际只抓到了大约 17 到 20 帧。编码器把它补成 30fps,只是重复已有画面。码率再高,也救不了缺掉的运动帧。更别提低分辨率 WebGL 画布被放大以后,边缘和文字都会变软。

这次视频最后由我直接录制,没有继续拿不合格的自动成片硬顶。以后要把自动录制重新做对,只有两条路。一条是用 ScreenCaptureKit 之类的原生窗口录制,直接拿连续的 4K60 画面。另一条是固定时间步逐帧渲染,生成得慢没关系,但每一帧都必须完整。

这个坑挺值钱的。检查视频不能只看分辨率和 fps 标签,还要看活动片段的重复帧、帧间隔和真实画布尺寸。

技术上其实没有神秘东西

模块使用的技术它负责什么
页面和交互React 19、TypeScript开场、射法选择、操作提示、结果页和中英文
3D 场景React Three Fiber、Three.js球场、门将、足球、雨、球网、看台和镜头
游戏状态Zustand三脚挑战、上一脚记忆、比分和阶段切换
声音Web Audio、本地 CC0 音频心跳、击球、风切、门柱、扑救、欢呼和环境声
分享Canvas把真实游戏画面合成 1080 × 1920 战绩图
部署Cloudflare Workers Static Assets托管静态站点和自定义域名

整个场景是程序化生成的,没有外部人物模型,也没有运行时 AI 调用。正式站部署在 lastkick.01mvp.com,静态资源和音频一起由 Cloudflare 提供。

想在本地运行,直接执行这些命令。

git clone https://github.com/makerjackie/lastkick.git
cd lastkick
pnpm install
pnpm dev

部署前可以先跑一次构建和 Cloudflare dry run。

pnpm build
pnpm deploy:dry-run
pnpm deploy

三层提示词,全部公开

这不是一条神奇 Prompt 一次生成的作品。

真正改变结果的是连续反馈。需求从「做个很酷的 3D 网页」变成「三脚球、一个记住你的门将、十几秒的情绪曲线」,中间经历了很多次否定和收口。

所以我把提示词分成三层。第一层是我们真正开始时说的话,第二层是让项目转向的关键反馈,第三层是今天重做一次,我会直接交给 GPT-5.6 或 Codex 的完整需求。

第一层,真实起始需求

下面不是事后包装出来的专业 PRD,只做了少量口语整理。

GPT-5.6 出来之后,我在想做什么样的 App 才会比较好玩,能特别呈现它的能力,而且有足够的传播度。传播要不就足够好玩,要不就足够共情,要不就足够好看。

3D 小游戏可以做一下,因为我很想知道它的上限。可以围绕世界杯讲故事,也可以不围绕足球。要足够天马行空、足够有创造力、足够惊艳,而且需要考虑技术可行性。

网站做完以后不需要接入任何 API。用户直接打开网页,就可以体验全部功能。AI 只在开发时生成代码、视觉、音频和素材,运行时不接 AI。

最后部署到 Cloudflare,使用 [name].01mvp.com 的域名,并做适合传播的横版和竖版演示内容。

它的问题也很明显。方向很多,情绪目标很大,但没有核心玩法,也没有可以验收的标准。

这很正常。真实项目一开始往往就长这样。

第二层,真正改变作品的迭代指令

这些话比「请继续优化」有用得多,因为每一句都指向了真实体感。

这个很无聊,操作起来没有任何感受,没有让人觉得兴奋的点。

你确定这个在能力范围内吗?观众不要太拟人,太拟真你也做不好。用抽象元素,把视觉表现力做出来。

下雨声有点奇怪,也太吵了。换成正常的雨声,或者去找可以合法使用的素材。

加入佛得角门将 Vozinha 的梗。进球时要有真正的欢呼,没进也需要有音效和反馈。

现在踢球没有弧线,可玩性不够。加入不同射法、引导和 tips,默认支持中英文。

分享不要只跳出系统面板。先生成一张用户能看到、愿意发出去的战绩图。

踢球时要渲染紧张感,进球不要太容易。控制好比例,而且失败后要让用户知道自己错在哪里。

视频开头不要像说明书,要像一场游戏真的开始了。清晰度和帧率要按真实画面验收,不能只看导出参数。

注意这些指令没有教模型具体写哪个函数。它们描述的是用户感受、产品问题和验收结果。

这也是我这次最大的感受。Prompt 的质量,不只看术语写得多专业,还看你敢不敢在看到烂版本时说清楚「到底哪里没感觉」。

第三层,如果今天重做,我会使用这份 Master Prompt

下面这份可以直接复制。它不是承诺一次生成最终成品,而是把这次踩过的坑提前变成边界和验收标准。

请为我设计并实现一个手机优先的 3D 浏览器小游戏,项目名为 Last Kick。

一、产品目标

玩家进入的是世界杯加时赛第 120 分钟,比分 1 比 1。球门前是佛得角门将 Vozinha。玩家只有三脚射门机会,要在 20 到 45 秒内完成一局,并产生紧张、释放、想再来一局和愿意分享的感觉。

这不是完整足球模拟器。不要做跑动、传球、多人比赛、开放地图和写实球员。把全部质量集中在三次射门、门将记忆和进球瞬间。

二、运行边界

- 网站运行时不得调用 OpenAI、GPT、图像生成或任何第三方 AI API。
- 用户不需要登录、输入文字、上传图片或录制语音。
- AI 只用于开发阶段的创意、编码、素材生成、测试和迭代。
- 所有游戏规则、声音编排、分享卡和 3D 画面都在浏览器本地完成。
- 音频必须是程序化生成、自己制作,或许可清楚并本地托管的 CC0 素材。

三、核心玩法

- 开场用比赛转播语言呈现 120:00、1 比 1 和剩余三脚,不要先弹出大段说明书。
- 玩家按住足球开始蓄力,拖动决定落点,松手射门。
- 提供爆射、弧线和勺子三种射法。不同射法必须有不同轨迹、声音和最佳落点。
- 爆射需要 64% 以上力量,目标是左下或右下的边网区域。
- 弧线需要 52% 以上力量,目标是更宽的远角,飞行路径要明显弯曲。
- 勺子力量控制在 45% 到 78%,目标是球门中路的受控窗口,力量过大会撞横梁。
- 判定必须确定、可解释,不使用随机概率暗中决定进球。
- 门将保存上一脚的射法和方向。如果玩家连续使用同一种射法并打同一侧,门将要提前预判并完成清晰可读的扑救。
- 蓄力时实时显示偏轻、甜区、过量和落点是否有效。失败后根据真实原因给出一句具体提示。

四、视觉方向

- 使用 stylized、cel-shaded、低多边形的转播美术,不追求写实人物。
- 门将使用抽象切面几何体,不使用照片、人脸或外部人物骨骼模型。
- 球场、湿地反光、球门、球网、雨、轨迹和冲击波尽量程序化生成。
- 观众不要做成粗糙小人。用约一万张 InstancedMesh 折叠卡片组成环形看台,把整片观众当成一个情绪装置。
- 待机时看台克制,进球后从象牙白翻成珊瑚红并形成机械波。反馈规模必须大于界面按钮。
- 主色使用深墨黑、湿草绿、灯光象牙白、钠灯金、球队珊瑚红和对手青色。

五、紧张感和游戏手感

- 按住蓄力后,镜头缓慢推近,环境声逐渐收窄,心跳随力量加速。
- 进入有效窗口时,瞄准和力量反馈改变颜色,但不要遮挡球门。
- 松手接触足球时加入很短的 hit-stop、镜头冲击和瞬间静音。
- 飞行时根据爆射、弧线、勺子提供不同的风切、镜头路径和球速感。
- 进球时表现球网变形、灯光抬升、观众翻色、镜头震动和真实球场欢呼。
- 扑救、门柱和横梁必须有不同声音、回弹、镜头和人群反应,不能只显示一行失败文字。
- 提供减少动态效果的 reduced-motion 适配,并允许用户静音。

六、界面和传播

- 根据浏览器语言默认显示中文或英文,并提供永久可见的手动切换。
- 第一脚就地教会按住、拖动、松手,后两脚不重复打断玩家。
- 明确显示三脚进度、已进球数、上一脚轨迹和门将的预判方向。
- 三脚结束后生成称号和成绩。
- 浏览器离线生成一张 1080 × 1920 PNG 战绩图,包含真实 WebGL 画面、进球数、射法、力量和 lastkick.01mvp.com。
- 支持文件分享时带图打开系统分享面板。不支持时保存 PNG,并复制挑战链接。
- 分享图只传播挑战和网址,不要做成课程广告。

七、技术栈

- React 19
- TypeScript
- React Three Fiber 和 Three.js
- Zustand
- Web Audio API
- Canvas 生成分享图
- Vite
- Cloudflare Workers Static Assets

不要接入物理 WASM、后端数据库、登录系统和运行时 AI。优先保持模块少、边界清楚、手机可流畅运行。

八、验收要求

- 390 × 844 手机视口和 1440 × 900 桌面视口都不能横向溢出。
- 开场三秒内能看懂比赛情境,第一次操作不需要阅读长教程。
- 爆射、弧线和勺子在视觉上能一眼分辨。
- 重复同一计划时,门将预判必须可见,玩家能理解为什么被扑。
- 编写纯函数脚本验证三种射法的有效窗口和重复套路判定,不依赖随机数。
- 新手模拟的单脚进球率目标在 10% 到 25% 之间,不能随手一拖就进,也不能连续失败却不知道原因。
- 对真实 Chromium WebGL 页面完成开场、蓄力、三种结果、三脚结束、分享预览和中英文检查。
- 生成的分享图必须真的是 1080 × 1920,并包含非空白的 WebGL 像素。
- 运行 TypeScript 构建、Cloudflare dry run 和线上 200 状态检查。
- 如果要制作视频,优先使用原生窗口录制或固定时间步逐帧渲染。横版至少 3840 × 2160,竖版至少 2160 × 3840,60fps。检查重复帧和真实运动连续性,不允许低清画布放大后伪装成 4K。

九、工作方式

先做一个 10 到 15 秒的 vertical slice,只有开场、一次射门和一次全场反馈。用真实浏览器截图和录屏验证它是否有感觉。没有通过前,不增加剧情、关卡、球员和地图。

每轮只解决一个最大的体感问题。主动展示当前版本,接受「无聊」「不紧张」「太容易」「听起来很假」这类反馈,再把反馈翻译成镜头、声音、规则或界面改动。

完成后部署到 lastkick.01mvp.com,并输出 README、音频来源、MIT License、可复现命令和验收证据。

如果你想做类似作品,先别急着复制所有功能

你可以先拿上面的 Master Prompt,但我更建议把第一版缩到一个可以用十几秒判断的切片。

一个场景,一次操作,一个最大的反馈。

先问自己,玩家松手那一下有没有感觉。没有的话,继续加世界观、排行榜和十个关卡都救不了它。

这次 GPT-5.6 真正展示出来的能力,也不是一次写了多少行 Three.js。它能在一段很长的协作里,接住「太无聊」「雨声很假」「门将像四个方块」「分享不知道发了什么」这些非常具体、甚至有点情绪化的反馈,再把它们落成镜头、规则、声音和代码。

Prompt 不是咒语。

它更像一串产品判断。你看见什么不对,能不能讲清楚,然后愿不愿意继续磨。

Last Kick 最早只是我想看看 GPT-5.6 上限的一次脑洞。最后留下来的,反而是很朴素的一件事。允许自己先做出一个很烂的版本,再一点点把感觉找回来。

如果你也想用 AI 做自己的小产品,可以先去 Last Kick 踢三脚,或者从 GitHub 源码 开始改。

01MVP 是 Maker Jackie 做的 AI 产品实战教程。这个案例、提示词和源码全部免费。网站里还有更多从想法、开发、上线到找用户的实战内容。

想交流 ChatGPT、Codex 和 AI Coding 的真实使用体验,也可以加入 01MVP 交流群。

加入 01MVP 交流群

这篇文档有问题?