AI编程不是代写代码,而是省决策时间——Godot 4独游开发实战
1. 一个人做游戏的第8周AI 不是帮你写代码是帮你省“决策时间”做这个系列写到现在已经有两个月了。项目从最初脑子里的一个模糊概念到上周总算有了一个可以玩10分钟左右的Gameplay原型进度比我预想中快了不少。熟悉独立游戏开发的朋友应该知道这个行业里绝大多数项目都死在从“原型”到“内容填充”这段路上而不是死在起点。我能撑到第8周还在持续迭代说实话AI编程工具占了很大功劳。很多人一听到“用AI做游戏”第一反应是“AI替我把代码全写了我负责摸鱼”。实际用下来完全不是这么回事。AI不管是Cursor还是别家现阶段更像一个反应极快但偶尔会胡说的初级程序员它真正帮我省掉的不是“敲键盘的时间”而是“反复查文档、试错、切换上下文”的时间。这个差别很关键。举一个真实的例子。这周我给背包系统加了一个拖拽交换功能。放在以前我的流程是翻Godot官方文档看Drag-and-drop的API、去论坛搜别人踩过的坑、自己写一遍信号回调、跑起来发现位置算不对、再回来调坐标。这一套下来两个小时起步。这次我只花了十五分钟我把我脑子里理想的交互流程写成一个提示词发给编辑器里的AI它给我生成了一份包含了get_viewport().gui_get_drag_data()、set_drag_preview()、_can_drop_data()、_drop_data()四个关键方法的脚本我核对了一遍逻辑就直接跑通了。你说AI比我更懂Godot吗未必。但它能把“我知道有这回事但记不清准确API”和“我知道标准写法但不想从零敲”的时间压缩到几乎为零。在一个人既要写代码、又要画素材、还要设计关卡的状态下这种压缩直接决定了我晚上能不能按时睡觉。当然AI也不是万能的。这个系列做到第8期我对AI编程的态度已经从早期的“震撼”变成了“谨慎使用”。它写的代码能跑但未必能长期跑它解决一个问题有时候会顺手给你制造两个隐患。这也正是我今天想重点聊的东西在一个人开发一款游戏的语境下AI到底该怎么用才能既提效又不翻车。如果你也在用Cursor、Copilot之类的工具做个人项目或者你正犹豫要不要在独立游戏开发里引入AI编程这篇文章值得花点时间看完。我会把这一周踩过的坑、验证过的方法、以及我对“一个人AI”这个组合的理解尽量讲透。2. Godot 还是 Unity我为什么在这轮迭代里锁死 Godot 4这周有好几个读者问我同一个问题你都用AI编程了为什么还选Godot这种相对小众的引擎直接上Unity不香吗说实话我在项目立项的时候确实认真纠结过这个问题也查了不少社区里关于“unity3d游戏开发”和“godot游戏开发”的对比讨论。最终锁死Godot 4不是因为它比Unity强而是因为“一个人AI”的工作模式更适合它。先看一组我当时的对比维度对比项Godot 4Unity 3D脚本语言GDScriptPython风格C#安装体积几十MB启动秒开数GB每次打开都要等场景/节点模型场景树内嵌脚本直接挂节点GameObjectComponentAI生成的代码风格简洁、可读性强、错误率低模板代码多但上限更高资源商店/生态相对薄弱但2D工具链够用成熟完善商用授权完全免费无抽成收入超过阈值后收费单看“脚本语言”这一行你就明白我为什么会倾向Godot了。GDScript的语法非常接近Python缩进即块结构没有花括号和分号类型标注可写可不写。这意味着AI生成的代码天生就“短、平、直”——没有一堆public class XXX : MonoBehaviour的壳子逻辑一眼能看完。代码越短AI出错的概率就越低我审查起来也越快。这是实打实的效率优势。C#本身当然不复杂但Unity的组件生命周期、序列化规则、协程机制再加上编辑器和IDE之间的频繁切换会让AI在生成代码时不时“想当然”。举个例子AI在Unity里生成一个读取玩家输入的脚本经常忘了处理Time.deltaTime或者FixedUpdate与Update的区别。这类错误不是致命伤但会消耗你的审查精力。GDScript里大部分情况下只需要关心_process()和_physics_process()的区分心智负担小很多。我的判断标准其实很朴素一个人开发小型到中型的2D游戏引擎选型的核心不是“谁上限更高”而是“谁能在你看代码的时候让你少死几个脑细胞”。Godot 4尤其适合2D游戏开发内置的TileMap、AnimationPlayer、Parallax2D这些节点开箱即用配合AI编程从“我有想法”到“能在屏幕上看到效果”的路径极短。当然我不能说统一推荐Godot。如果你要做的是重度3D项目、需要大世界渲染、或者你本来就熟练掌握C#和Unity的组件体系那Unity仍然是合理的选项。AI编程工具能放大你的能力但它不会帮你自动补上“你对引擎不熟”这个短板。反过来如果你对引擎足够熟选哪个都能出活。关于引擎选型我还有一个个人观点在“一个人AI”的语境下开源引擎的好处不止是免费更是“AI训练数据更足”。Godot的社区文档和示例代码是公开且规范的AI模型对它的理解往往比那些闭源引擎的内部细节更深。这带来的直接结果是AI给的Godot代码通常更接近标准实践而不会自己发明API。这事儿听着玄学实际用下来差别非常明显。3. AI 提示词把需求讲成“验收单”而不是“作文题”如果你看过网上那些“AI编程提示词大全”大概率会发现里面全是各种花哨的模板什么“你是一名资深架构师”“请从鲁棒性角度分析”“输出格式请使用JSON”。这些模板不能说没用但用在游戏开发里最大的问题是不接地气。我给AI写游戏代码需求时遵循的是一条核心原则把需求讲成验收单而不是作文题。什么叫验收单就是告诉AI“我要什么效果、在什么条件下触发、边界情况怎么处理、哪些东西不要碰”。什么叫作文题就是“帮我写一个背包系统”这种话。你把作文题丢给AI它大概率会发挥想象力给你写出一坨结构华丽但完全不匹配你项目的代码——因为你的项目里节点叫什么、数据放哪、信号怎么组织它完全不知道。我在第4周的时候吃过一次大亏。当时我对AI说“帮我写一个敌人巡逻的AI”AI倒是很勤快用CharacterBody2D写了一个带状态机的巡逻脚本看起来非常专业。结果一运行敌人压根不会动。折腾了很久才发现AI默认用的节点路径是get_node(../NavigationRegion2D)而我的场景结构里根本没有这个节点。问题出在哪出在我没告诉它我的场景树长什么样。从那以后我养成了一个习惯凡是涉及到场景交互的AI请求我都会先把关键节点结构贴进去并明确写出约束条件。下面是一份我自己整理的、在游戏开发场景下用了大半个月的提示词模板你可以直接抄角色你是一名熟悉Godot 4的资深游戏程序员。 任务在现有的2D横版动作游戏项目中添加一个功能。 功能描述【用一两句话说清你想要的行为】 场景结构【粘贴相关节点树只保留关键节点】 数据来源【说明这个功能依赖哪些变量/信号/外部数据】 约束 - 只修改指定的脚本文件不要动其他文件的逻辑 - 不要新增外部插件 - 所有魔法数字写成常量 - 需要处理玩家离开范围后的重置逻辑 验收标准 - 当【触发条件】时执行【动作】 - 边界情况当【异常场景】时程序不报错看到区别了吗这个模板的本质是在模仿一个正常的项目负责人给初级程序员派活时的沟通方式。你把场景结构、数据来源、边界条件都讲清楚AI生成代码的命中率会从“碰运气”直接跳到“八九不离十”。再往前一步提示词里最容易被忽视的是“不要做什么”。AI有一个很让人头疼的习惯——过度设计。你让它修复一个bug它可能顺手帮你“重构”了附近的代码你让它写一个简单函数它可能给你扩展出三个工具方法。在AI编程提示词里明确写上“不要重构无关代码”“不要新增不必要的抽象”能帮你省掉大量审查和返工的时间。本质上这不光是提示词技巧也是和AI协作时的工作纪律。最后分享一个关于“ai编程提示词”的经验不要在一次对话里塞太多需求。我早期喜欢把三四个相关的功能改进一次性发给AI结果它经常只实现了第一个后几个忘了或者混在一起逻辑混乱。现在我每次只提一个需求跑通了再提下一个。虽然来回对话的次数多了但每次输出的质量都稳定综合算下来反而更快。4. AI 生成的代码我为什么坚持逐行审查接下来聊一个不那么“酷”但极其重要的话题审查AI生成的代码。这周我踩了一个很典型的坑值得拿出来当反面教材。当时我在做敌人的掉落物系统让AI写了一个“敌人死亡后有概率掉落道具”的脚本。AI生成的逻辑大致是敌人queue_free()之前实例化一个掉落物场景然后把这个掉落物加到父节点下。表面看没什么问题道具也确实掉出来了。结果玩了几分钟之后报错出现了有一段代码在尝试访问一个已经被释放的实例。我沿着报错信息查回去发现AI在敌人被击退的脚本里加了一个knockback_timer.timeout信号连接而敌人的死亡逻辑是直接queue_free()没有等待这个计时器结束。敌人死了计时器回调里还在访问敌人身上的变量于是直接nil报错。这要是放在以前写代码我大概率会注意到这个生命周期问题。但AI生成的代码有一个特点它总是“看起来对”。语法没错逻辑似乎严谨又没有明显的性能问题——于是人就会不自觉地降低警惕性。这是AI编程最大的隐藏成本审查代码的认知负担并不会因为代码不是自己写的而降低反而会升高。我的应对方案是给自己立了一条规矩AI生成的代码我坚持逐行审查不让任何一行未经确认的代码合入我不熟悉的模块。审查的时候重点盯这么几个地方节点生命周期有没有在_ready()里连接信号但没有在_exit_tree()里断开对象是否可能被提前释放边界条件数组越界、空引用、除零、玩家快速进出触发区域导致的状态错乱。硬编码路径get_node()用的是绝对路径还是相对路径场景结构调整后会不会失效隐式全局状态是否在函数内部偷偷改了别的节点的属性而没有通过信号或显式方法调用还有一个我强烈推荐的技巧让AI自己review自己生成的代码。在Cursor或类似工具里选中刚生成的代码块直接发一句“请你以严格代码审查员的身份检查这段代码找出潜在的空指针、生命周期和边界条件问题并给出修复建议”。AI对自己生成的代码做二次检查时往往会暴露一些第一遍生成时忽略的细节。虽然它的“自查”不能完全替代人的判断但相当于免费请了一个初级同事帮你做一轮peer review这个性价比相当可观。再补充一个经验不要信任AI对“数学”的处理。不管是伤害计算公式、掉落概率、还是敌人追踪的向量运算AI都容易在小数点精度、角度换算、坐标系转换上出问题。在代码里涉及这些部分时我建议自己手动算一遍或者写单元测试去验证。游戏逻辑里很多bug不报错只是数值不对这种bug最难查而AI恰恰是这类bug的高发区。5. 性能调到 60Hz 之后我意识到 Godot 的优化点不在渲染最近知乎上有个热搜词叫“游戏开发多少hz合适”评论区一堆人争论60、120、144谁才标准。作为一个做2D小型游戏的独游开发者我的态度很明确先把60Hz稳定做到再谈别的。先解释一下60Hz在游戏开发里的含义。大多数显示器的刷新率是60Hz意味着屏幕每秒最多刷新60次画面。游戏逻辑如果能稳定在60FPS玩家就能获得流畅的视觉体验。而物理更新频率_physics_process()在Godot 4里默认是每秒60次也就是每帧执行一次物理逻辑。当你的实际运行帧率高于物理更新频率时Godot会自动将物理步进保持在固定间隔避免物理表现不稳定。就独立游戏的体量而言2D游戏的渲染压力通常没那么大。真正吃性能的是你在_process()和_physics_process()里干了多少活。这周我就是被这个坑折磨了一整天。起因是玩家在某个场景里打开背包界面后会间歇性卡顿帧率从60瞬间掉到40出头。我第一反应是背包界面里的图标太多渲染爆了。于是改了一下午的纹理图集和绘制顺序结果毫无改善。实在没辙了我打开Godot自带的性能监控面板Debug Monitors一列一列看数据。发现渲染相关的指标都正常反而是Physics Process的时间异常偏高。问题不在这帧绘制了什么东西而在于物理帧里执行了一个开销很大的操作。顺着这个线索查下去最终锁定在AI写的“背包物品ToolTip实时刷新”逻辑上——它每帧都在遍历背包里全部物品的数据去重新构造字符串和更新UI标签。物品一多字符串拼接的开销就被放大了帧率自然就掉。这个案例给我的教训很直接优化性能之前先确定瓶颈在哪不要凭感觉动手。尤其是在跟AI协作的场景下AI生成代码时不会主动考虑“某个函数会被高频调用”所以你要格外关注所有写在_process()和_physics_process()里的内容。判断标准就一条这段逻辑是每帧都需要执行的吗如果不需要就应该挪到信号回调或事件里或者加上缓存、节流。给一个我在Godot 4里做性能优化的自查清单都是实战总结节点数量场景树里如果同时存在几百个活动节点优先考虑用CanvasItem或者对象池控制总数。高频调用检查_process()里有没有做字符串拼接、字典/数组遍历、动态实例化。信号连接多个物体之间的信号连接是否在移除时正确清理避免泄漏导致每次发送都多一份开销。碰撞检测碰撞层的Layer/Mask是否设置准确没必要参与检测的物体不要打开monitorable。资源加载不要在运行时反复load()同一张纹理或场景用preload或缓存。老实说这些经验对任何一个做过一段时间游戏开发的人都不陌生但结合AI编程的场景它们的优先级被显著抬高了。AI擅长堆功能不擅长做减法。它会非常自然地在你没有明确要求的情况下到处添加逻辑而这些逻辑单独看都没问题放在一起就会把性能拖垮。你得自己在游戏跑起来之后盯住监控面板把那些“看起来合理但实际多余”的调用揪出来。这活儿没法外包给AI只能靠经验。顺便回应一下“多少hz合适”的话题。对个人开发者来说最现实的目标不是追逐高帧率而是保证体验的下限不低于60。比起偶尔冲到200FPS然后瞬间卡顿到30玩家更愿意接受全程稳定在60FPS。至少我项目现在所有场景都按这个标准在调。6. Cursor 之外的 AI 工具矩阵我目前的工作流聊了这么多AI编程和游戏开发的事最后简单聊聊工具。你问“编程ai哪个好用”我只能说好用不好用取决于你的使用场景和个人习惯。我自己目前的完整工作流是这样的主编辑器Cursor。这应该是目前最火的AI编程工具了。它最大的优势是能直接读你项目里的多个文件理解代码库的上下文然后在这个上下文基础上生成代码。我自己做游戏时很多跨脚本的改动都在Cursor里完成因为它的Tab补全和CmdK内联编辑功能用起来非常顺手。架构讨论和疑难问题Claude。我说的“AI编程提示词”更多是在这个环节用。遇到不确定的系统设计或算法选择我会把问题描述清楚发给它让它给出几个方案并说明优缺点。它在这种开放式问题上的推理能力明显更好而且它的长上下文窗口可以完整读入我的数个核心脚本帮我找跨文件的逻辑漏洞。网上关于编程AI的对比讨论很多但就“理解意图”这个维度Claude的确有优势。快速查文档和调试ChatGPT。这个更像我随身的文档搜索引擎。不过在最新的Godot版本里很多API细节它也有幻觉。我的原则是拿它做初步了解可以最后还是要以官方文档的准确API为准。另外如果你写的是C#比如用UnityGitHub Copilot在多语言和IDE集成方面依然是稳的。国内团队如果用国产工具像通义灵码在中文理解上有天然优势。工具没有绝对的高下关键是找到跟你的开发习惯匹配的那一个。在AI工具的使用上我还有一个体会不要频繁切换模型尽量固定一个主模型。不同模型对代码库的“记忆”风格不一样换来换去容易出现上下文断档AI一会儿记得你的变量命名规则一会儿又忘了导致生成代码风格混乱。我现在基本锁死“Cursor Claude模型”这个组合稳定用了几周代码风格一致性明显比早期频繁切换模型时好。最后哪怕你用的是AI编程工具基础的代码能力依然不能被替代。AI能帮你把功能写得飞快但它不会帮你判断这个功能该不该存在、场景结构是不是合理、代码是否符合长期维护的标准。前者是“怎么写”的问题后者是“该不该这么写”的问题。工具越好用对使用者判断力的要求反而越高。这一点在你用AI做游戏的第一周可能还感觉不到做到第八周、第八个月你会越来越有体会。