用10个AI角色协作开发3D大逃杀游戏原型全流程 如果你一直好奇“AI 能不能真的参与一款游戏从零到能玩的全过程”那这篇内容正好适合你。今天我会用“10 个 AI 角色”的协作方式来拆解一个类似《堡垒之夜》玩法的大逃杀游戏原型从需求拆分、代码生成、美术资源到测试部署每一步都用不同定位的 AI 工具来完成。先说清楚一点我们不会真的复刻《堡垒之夜》。它是 Epic Games 的版权产品直接搬美术资源、角色设定和商标都是不合适的。这篇文章的目标是做一个“玩法参考、技术原创”的 3D 大逃杀 Demo用 AI 辅助整个制作流程。这样一来新手能学到 AI 协作的套路有经验的开发者也可以把这套流程迁移到自己的游戏项目里。1. 为什么用 10 个 AI 协作而不是 1 个 AI很多人对 AI 开发的理解还停留在“打开一个对话框让它写一段代码”的阶段。真实项目里这种方式很快就会失控因为一段代码并不等于一个游戏。游戏是一个复杂系统包含玩法设计、数值平衡、3D 场景、角色控制、音效反馈、碰撞检测、判胜逻辑、性能优化等多个方面。如果只用一个 AI 从头写到尾它很难同时兼顾所有层面的上下文。更合理的方式是“一个 AI 团队”每个 AI 负责一个专业方向人类开发者担任架构师和最终决策者。这种模式的优点是上下文更聚焦。每个 AI 只处理自己领域的输入输出不容易“忘了前面说了什么”。产出物更规范。比如 AI 美术生成的图片、模型、音频可以按目录结构组织。便于并行开发。代码 AI 在写交互逻辑时美术 AI 可以同步生成贴图资源。便于排查问题。哪个环节出错了直接找对应角色的输出做检查而不是在一大段混合内容里翻找。下面我会把 10 个 AI 角色按真实团队结构分配好再逐步进入实战。2. 10 个 AI 角色分工与协作模型2.1 十角色清单这里说的“AI 角色”不是十个不同的软件而是十个明确的职责。实际落地时同一个软件可以切换不同 Prompt 来扮演不同角色也可以分别用编程助手、生图模型、音频模型等专业工具。表格中的角色可以作为你项目的模板直接复制使用。编号角色主要负责典型产出01产品经理 AI需求梳理、功能优先级、验收标准PRD 文档、功能清单02游戏策划 AI玩法规则、数值公式、缩圈节奏玩法规则表、数值配置03技术架构 AI技术选型、工程结构、接口设计架构方案、目录结构04前端逻辑 AI游戏主循环、交互、渲染逻辑可运行代码053D 美术 AI模型资产、场景物件、角色建模GLB/GLTF 或几何体方案06贴图/UI AI贴图、UI 图标、技能图标图片素材、按钮设计07音频 AI音效、背景音乐、语音播报WAV/MP3 文件08测试 AI用例生成、边界条件、回归测试测试计划、测试脚本09技术文档 AIREADME、开发日志、提示词记录文档、操作手册10部署运维 AI构建配置、静态托管、性能基线部署脚本、构建流程2.2 协作流程示意十角色不是各写各的而是数据流式的配合。下面这段 ASCII 图展示了最核心的传递关系。产品/策划需求 ↓ 技术架构设计 ↓ 前端逻辑代码 → 集成目录 3D 美术资产 → assets/ 目录 贴图/UI 资产 → assets/ 目录 音频资产 → assets/ 目录 ↓ 集成测试 → 修复 → 文档 → 构建部署实际上每次迭代都会回到需求层确认并不会一次性全部完成。建议先用“垂直切片”方式跑通最小玩法再加入更多系统。2.3 人类与 AI 协作的边界在这个流程里人类不是旁观者。AI 的产出需要经过你的检查、测试和决策。尤其涉及版权、安全、性能和生产环境部署时必须由人类把关AI 不能直接获得上线权限。合理的协作方式是AI 负责“草案生成”人类负责“决策和修正”。每次给 AI 下达任务时带上足够上下文当前项目结构、技术栈版本、已完成内容、期望输出格式。所有 AI 生成的代码先放到分支中跑过测试再合并。美术资源需要人工检查授权信息避免使用可能侵权的生成素材。3. 环境准备与项目目标3.1 演示项目目标我们这个实战项目使用 Web 技术实现不依赖重型游戏引擎方便所有人复现。技术栈选择如下Node.js 18Vite 作为前端构建工具Three.js 作为 3D 渲染库JavaScript 实现游戏逻辑最终效果是一个浏览器中运行的 3D 竞技场玩家用 WASD 移动鼠标点击射击敌人地图中有建筑遮挡毒圈会不断收缩站在圈外会持续掉血。这个原型已经覆盖大逃杀玩法的核心循环探索、对抗、缩圈、淘汰。3.2 初始化项目先创建一个空项目并安装依赖。命令如下npm create vitelatest fortnite-ai-demo -- --template vanilla cd fortnite-ai-demo npm install npm install three npm run dev执行后项目目录会包含以下关键内容fortnite-ai-demo/ ├── index.html ├── package.json └── src/ └── main.js如果你的网络环境无法访问 npm 官方源可以换成国内镜像后重试。注意不同 Vite 版本的初始化交互可能略有差异选择 Vanilla JavaScript 模板即可。版本提示Three.js 版本迭代较快部分 API 在不同版本可能有细微差异。本文代码在编写时基于较新的 r16x 系列版本你安装到的版本可能更高如果遇到弃用警告可以按浏览器控制台提示调整。4. 用 AI 完成需求拆分与玩法设计4.1 给产品经理 AI 的提示词很多人给 AI 写需求时只写一句“做一个大逃杀游戏”这种指令出来的东西基本没法落地。正确的做法是给出背景、范围、角色、输出格式。下面是一段可直接使用的提示词你是一名有 10 年经验的游戏产品经理。我们要做一个类似《堡垒之夜》玩法的大逃杀游戏原型目标是验证核心循环。请输出以下内容 1. 功能清单按“必须开发/建议开发/暂不开发”分类。 2. 每项功能的验收标准。 3. 第一轮迭代的最小可玩版本MVP范围。 4. 需要规避的常见风险。 限制 - 平台为桌面浏览器。 - 技术方案暂定 Three.js。 - 不要使用任何受版权保护的角色、地图名称和音乐素材。产品经理 AI 的输出通常会包含“移动、收集、对战、缩圈、胜利判定”等功能。你不需要全部实现先抓住最核心的玩法闭环。4.2 把需求拆成开发任务接下来让“游戏策划 AI”把 MVP 拆成更细的开发任务你是游戏策划。请把大逃杀 MVP 拆成任务清单每个任务要包含 1. 任务编号。 2. 任务名称。 3. 具体描述。 4. 依赖的前置任务。 5. 建议耗时小时。 输出为 Markdown 表格技术实现层面不要写死留给开发人员决定。这一步的意义在于AI 会生成一张类似“任务看板”的表格。你可以再把它交给“技术架构 AI”去生成项目目录和模块划分。5. 用 AI 编写核心游戏逻辑5.1 生成页面骨架我们先写最基础的index.html。这段代码由 AI 生成但人需要检查是否包含正确的标签和脚本引入方式。!DOCTYPE html html langzh-CN head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / titleAI 协作大逃杀 Demo/title style body { margin: 0; overflow: hidden; font-family: system-ui, sans-serif; } #hud { position: fixed; top: 12px; left: 12px; color: #fff; background: rgba(0, 0, 0, 0.5); padding: 8px 12px; border-radius: 6px; z-index: 10; pointer-events: none; } /style /head body div idhud生命值: 100 / 剩余敌人: 6/div script typemodule src/src/main.js/script /body /html页面中的#hud是游戏 HUD用于显示生命值、剩余敌人和安全圈半径。真正的 3D 场景会由src/main.js动态创建。5.2 生成 3D 场景与玩家控制接下来是核心逻辑。把下面这段代码保存为src/main.js它将覆盖 Vite 模板默认内容。import * as THREE from three; const scene new THREE.Scene(); scene.background new THREE.Color(0x87ceeb); const camera new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 200); camera.position.set(0, 14, 16); camera.lookAt(0, 0, 0); const renderer new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(innerWidth, innerHeight); document.body.appendChild(renderer.domElement); scene.add(new THREE.AmbientLight(0xffffff, 0.6)); const dirLight new THREE.DirectionalLight(0xffffff, 1.2); dirLight.position.set(10, 20, 10); scene.add(dirLight); const ground new THREE.Mesh( new THREE.BoxGeometry(50, 1, 50), new THREE.MeshLambertMaterial({ color: 0x7ec850 }) ); ground.position.y -0.5; scene.add(ground); const grid new THREE.GridHelper(50, 10, 0xffffff, 0xaaaaaa); grid.position.y 0.01; scene.add(grid); function createBox(x, z, w, h, d, color) { const mesh new THREE.Mesh( new THREE.BoxGeometry(w, h, d), new THREE.MeshLambertMaterial({ color }) ); mesh.position.set(x, h / 2, z); scene.add(mesh); return mesh; } for (let i 0; i 10; i) { const x (Math.random() - 0.5) * 35; const z (Math.random() - 0.5) * 35; const w 1 Math.random() * 2; const h 1 Math.random() * 3; const d 1 Math.random() * 2; createBox(x, z, w, h, d, 0xd9a066); } const player new THREE.Mesh( new THREE.ConeGeometry(0.5, 1.4, 8), new THREE.MeshLambertMaterial({ color: 0x2979ff }) ); player.position.set(0, 0.7, 0); scene.add(player); const enemies []; const enemyMat new THREE.MeshLambertMaterial({ color: 0xe53935 }); for (let i 0; i 6; i) { const enemy new THREE.Mesh(new THREE.BoxGeometry(0.8, 0.8, 0.8), enemyMat); const angle (i / 6) * Math.PI * 2; enemy.position.set(Math.cos(angle) * 10, 0.4, Math.sin(angle) * 10); scene.add(enemy); enemies.push({ mesh: enemy, speed: 0.8 Math.random() * 0.6, vx: 0, vz: 0 }); } const raycaster new THREE.Raycaster(); const pointer new THREE.Vector2(); const hud document.getElementById(hud); let health 100; let killCount 0; let isOver false; const keys { w: false, a: false, s: false, d: false }; addEventListener(keydown, (e) { if ([w, a, s, d].includes(e.key)) keys[e.key] true; }); addEventListener(keyup, (e) { if ([w, a, s, d].includes(e.key)) keys[e.key] false; }); addEventListener(click, () { if (isOver) return; pointer.x 0; pointer.y 0; raycaster.setFromCamera(pointer, camera); const hit raycaster.intersectObjects(enemies.map((e) e.mesh)); if (hit.length 0) { const index enemies.findIndex((e) e.mesh hit[0].object); if (index -1) { scene.remove(enemies[index].mesh); enemies.splice(index, 1); killCount 1; } } }); let safeRadius 20; const clock new THREE.Clock(); function animate() { requestAnimationFrame(animate); const delta Math.min(clock.getDelta(), 0.1); const elapsed clock.elapsedTime; const speed 6; const moveVec new THREE.Vector3(); if (keys.w) moveVec.z - 1; if (keys.s) moveVec.z 1; if (keys.a) moveVec.x - 1; if (keys.d) moveVec.x 1; if (moveVec.lengthSq() 0) { moveVec.normalize().multiplyScalar(speed * delta); player.position.add(moveVec); } player.position.x THREE.MathUtils.clamp(player.position.x, -24, 24); player.position.z THREE.MathUtils.clamp(player.position.z, -24, 24); enemies.forEach((enemy) { if (Math.random() 0.01) { const angle Math.random() * Math.PI * 2; enemy.vx Math.cos(angle) * enemy.speed; enemy.vz Math.sin(angle) * enemy.speed; } enemy.mesh.position.x enemy.vx * delta; enemy.mesh.position.z enemy.vz * delta; enemy.mesh.position.x THREE.MathUtils.clamp(enemy.mesh.position.x, -24, 24); enemy.mesh.position.z THREE.MathUtils.clamp(enemy.mesh.position.z, -24, 24); if (enemy.mesh.position.distanceTo(player.position) 1.2 !isOver) { health - delta * 12; if (health 0) health 0; } }); safeRadius Math.max(6, 20 - elapsed * 0.4); const distToCenter player.position.length(); if (distToCenter safeRadius !isOver) { health - delta * 10; if (health 0) health 0; } if (health 0) { isOver true; hud.textContent 游戏结束你被淘汰了点击刷新重试; } else if (enemies.length 0) { isOver true; hud.textContent 胜利你清空了这个区域的敌人。; } else { hud.textContent 生命值: ${Math.floor(health)} / 剩余敌人: ${enemies.length} / 安全半径: ${Math.floor(safeRadius)}; } camera.position.x player.position.x; camera.position.z player.position.z 14; camera.position.y player.position.y 12; camera.lookAt(player.position); renderer.render(scene, camera); } animate();这段代码并不复杂但已经包含了几个重要模块场景与相机创建 3D 世界并设置第三人称视角。地面与建筑用随机几何体生成低多边形地图。玩家控制通过 WASD 控制角色移动并限制在场地范围内。敌人 AI敌人会随机改变方向靠近玩家时造成伤害。射击判定鼠标点击时使用 Raycaster 做射线检测。毒圈安全半径随时间缩小圈外玩家持续掉血。胜负判定血量归零失败清空敌人胜利。5.3 运行与验证在终端执行npm run dev浏览器会打开一个本地地址。你应该看到的画面是蓝色天空、绿色地面、若干黄色方块建筑以及一个蓝色锥体玩家和六个红色敌人。用 WASD 移动角色让敌人保持在屏幕中心点击鼠标即可射击。如果敌人被击中它会从场景中移除HUD 中的剩余敌人数量会变化。这里有一个需要注意的点演示代码中的射线检测把pointer固定在了(0, 0)等价于向屏幕中心发射射线所以准确点击命中需要后续优化为鼠标坐标映射。为了让 Demo 更接近真实体验你可以让“代码 AI”补充鼠标位置转换逻辑。6. 用 AI 制作美术素材与音频6.1 生成贴图和 UI 图标美术素材是很多程序员最头疼的部分但 AI 生图工具可以把门槛降得很低。以“游戏技能图标”为例提示词可以这样写生成一张游戏技能图标风格为低多边形三维渲染主体是一把蓝色科幻步枪背景透明无文字无徽标适合放在游戏界面底部技能栏中。注意不要让 AI 模仿某个游戏的原始角色或商标。你只需要描述“低多边形”“科幻”“蓝色步枪”等通用特征这样生成结果属于原创素材版权风险更小。6.2 用几何体代替重量级 3D 模型对于本 Demo最优先的 3D 资产方案不是找模型网站而是通过代码生成几何体。我们在main.js中已经用BoxGeometry、ConeGeometry搭建了玩家和敌人这种做法的好处是零外部资源、加载快、不依赖网络。如果你希望角色更精致可以让 3D 美术 AI 生成 GLTF/GLB 模型再用 Three.js 的GLTFLoader加载。文件结构大致如下src/ └── assets/ └── characters/ └── player.glb加载代码示例import { GLTFLoader } from three/examples/jsm/loaders/GLTFLoader.js; const loader new GLTFLoader(); loader.load(/assets/characters/player.glb, (gltf) { scene.add(gltf.scene); });这种方案适合需要更复杂动画的项目但也会带来模型大小、动画播放、碰撞体适配等问题。先跑通几何体版本再逐步替换资源是更稳的迭代路径。6.3 音频与音效生成音效不一定要现成录音。你可以使用在线音频生成工具或 TTS 语音合成。比如射击音效可以通过 AI 生成一段短脉冲信号也可以用 Web Audio API 在代码里实时合成const audioCtx new AudioContext(); function shootSound() { const osc audioCtx.createOscillator(); const gain audioCtx.createGain(); osc.connect(gain); gain.connect(audioCtx.destination); osc.frequency.setValueAtTime(880, audioCtx.currentTime); osc.frequency.exponentialRampToValueAtTime(220, audioCtx.currentTime 0.1); gain.gain.setValueAtTime(0.3, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime 0.1); osc.start(); osc.stop(audioCtx.currentTime 0.1); }这个函数可以在点击鼠标时调用。相比外部音频文件代码合成更轻量也不会遇到跨域加载问题。7. 用 AI 做测试与代码审查7.1 让测试 AI 生成测试用例游戏逻辑里最容易出问题的是边界条件比如角色越界、毒圈收缩到最小后的行为、敌人列表清空后的胜负判断。让测试 AI 输出测试用例时可以直接给它代码上下文。请阅读以下游戏逻辑代码给出 10 个测试用例重点覆盖 1. 玩家坐标边界。 2. 毒圈半径最小值。 3. 敌人全部被清除时的胜利判定。 4. 血量归零后的游戏结束状态。 5. 点击射击时射线命中和未命中的分支。 输出格式用例编号、输入条件、预期结果。有了测试用例你可以手动在浏览器中验证也可以后续接入自动化测试框架。要注意 AI 生成的测试往往“过于理想”它不会知道代码里所有隐藏状态所以人工回归依然重要。7.2 代码审查建议请 AI 做代码审查时不要问“这段代码有问题吗”而要指定审查维度请以资深 Three.js 开发者的身份审查代码。重点检查 - 性能每帧是否创建了不必要的新对象。 - 内存事件监听器是否可能泄漏。 - 可维护性函数是否过长职责是否单一。 - 健壮性delta 过大或窗口 resize 时是否存在异常。 输出具体问题、影响、建议修改方式。注意AI 审查不是权威结论。它可能忽略上下文相关的 bug甚至提出不合理的重构建议。每次修改后都应该重新跑一次游戏确认功能没有退化。7.3 规模小也要纳入版本管理哪怕是一个人开发也应该使用 Git 管理代码。建议把 AI 生成的提示词也保存在仓库中例如ai-prompts/目录。这样做的好处是当你需要复现某个生成结果或排查问题时可以直接查看当时的 Prompt。ai-prompts/ ├── product-manager.md ├── game-designer.md ├── code-developer.md ├── ui-artist.md └── tester.md把提示词和代码一起提交本质上是在给 AI 协作留“操作记录”这是团队协作里最容易忽略的一步。8. 常见问题与排查思路在实际按文中步骤操作时你可能会遇到下面这些常见问题。问题现象常见原因解决思路npm run dev报错Node.js 版本过低或依赖安装不全升级 Node.js删除node_modules后重装页面白屏控制台报 Three.js 相关错误Three.js 版本 API 不一致检查控制台具体报错按版本调整 API贴图或模型加载不出路径错误、跨域或资源未启动服务确认文件路径使用相对路径或本地静态目录游戏运行卡顿每帧创建大量对象或敌人数量过多复用已有对象减少每帧计算必要时减少敌人点击射击不生效射线没有对准目标或目标层级过深调试 Raycaster 的 near/far或遍历场景子节点毒圈收缩异常计时器或半径计算逻辑有误打印elapsed和safeRadius逐步定位排查这类问题时最有效的方法是“二分定位”先确认基础环境能否运行再确认单个功能模块最后检查集成问题。不要同时修改十几个文件。9. AI 协作最佳实践与工程建议9.1 给每个 AI 固定上下文模板不要让同一个 AI 对话无限延伸。更好的做法是为每个角色建立一份独立文档每次对话前把“项目背景 已完成内容 本次目标 输出格式”四要素写完整。推荐模板项目背景这是一个基于 Three.js 的 3D 大逃杀 Demo。 技术栈Vite、JavaScript、Three.js。 当前目录结构index.html、src/main.js。 本次任务给敌人增加巡逻路径可视化。 输出要求只输出需要新增或修改的代码说明文件路径。9.2 强调安全与合规AI 生成代码可以帮你省时间但不要盲信。尤其是以下场景必须人工确认涉及登录、支付、权限等生产功能时不能直接采用 AI 生成的认证代码。涉及数据库更新或删除操作时需要先备份数据并在测试环境验证。涉及美术素材时要避免使用 AI 生成的知名角色、品牌标志、受版权保护的地图。对于游戏开发而言尽量让美术用“低多边形机器人”“蓝色科幻角色”等原创描述而不是原样复刻某个现实产品。9.3 把架构决策留给人类AI 可以写出很漂亮的模块但“整个系统如何组织”这个问题最好由人类先想清楚。比如目录如何划分、网络通信采用什么协议、是否引入物理引擎、未来是否需要服务端等这些决策会影响后续所有代码生成。一个比较实用的决策顺序是先由人类确定技术范围和 MVP 范围。AI 负责把功能拆成任务。人类审查任务清单删除超出范围的内容。AI 按任务逐个生成代码和资源。人类做集成测试把问题反馈给 AI 针对性修改。9.4 不要害怕重构时重新问 AI很多开发者不愿意把已有代码发给 AI担心泄露或上下文太长。但在游戏 Demo 阶段让 AI 基于现有代码做“增量修改”比“重写全部”更安全。你可以在对话里贴出关键文件的核心函数并告诉它“只修改 handleEnemyMove 函数不要改动其他部分。”如果 AI 给出的重构方案改动范围很大可以先保存当前版本到 Git再合并。永远确保有一个可以回滚的干净版本。9.5 性能关注点G 游戏开发中60 FPS 是常见目标。AI 生成的代码往往不考虑性能你需要提醒它关注“每帧分配”。比如update()中不要频繁创建Vector3尽量复用临时变量。本 Demo 中敌人数量少、地图简单性能压力不大。但后续如果加入大量子弹特效、阴影贴图、动态敌人就必须引入对象池、模型合批、LOD 等优化手段。你可以把这个需求单独交给“架构 AI”设计避免在开发过程中反复推翻结构。10. 下一步学习路线与实战建议如果你已经跑通了上面的 Demo说明你基本掌握了 AI 协作开发游戏的最小闭环。接下来可以按顺序挑战更高难度的功能先给玩家添加真正的鼠标视角控制和瞄准再加入跳跃与重力接着尝试用 GLTF 模型替换几何体最后引入网络联机能力。每一步都可以把前一步的经验复用到新任务里。如果目标是做出类《堡垒之夜》的完整大逃杀体验你还需要考虑多玩家同步与延迟补偿。掉落物系统与背包逻辑。建筑搭建功能。赛季化内容和商城系统。反作弊与账号体系。这些功能不适合让 AI 一次性生成而是应该继续沿用“拆分角色、单点突破、人工集成”的方式逐步推进。每次迭代后把你和 AI 协作时积累的提示词文档更新一次这会成为你个人开发流程里最宝贵的资产。先把项目跑起来再让 10 个 AI 各就各位。你会发现真正限制项目进度的不再是“从零写代码”的恐惧而是你自己对玩法设计、架构边界和质量标准的判断力。AI 协作的意义就是把这些判断力集中到更有价值的环节上。