我用 GPT-5.6 做了一个世界杯 3D 点球游戏
Last Kick 从一句天马行空的想法,经过无聊的第一版、玩法重做、声音与难度打磨,最后上线的完整实战复盘和提示词。

事情是这样的。
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,并复制挑战链接。

传播感不是多放一个分享按钮。它来自一件更具体的事,我有一个结果,而且我想让朋友来挑战它。
视频清晰度这块,我也翻车了
为了给横版和竖版视频自动出片,我最早让脚本连续抓取浏览器截图,再交给 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 交流群。

这篇文档有问题?