尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用AI在终端做游戏:Shove背后的设计、构建与试玩闭环

用AI在终端做游戏:Shove背后的设计、构建与试玩闭环 把 Shove 跑起来的时候旁边的同事凑过来看了一眼终端说“这都什么年代了怎么游戏还做在命令行里”我没急着反驳因为那个瞬间我自己也在想同一个问题。但等我把键盘输入、纯文本渲染的状态面板以及 Claude Fable 5 前一晚生成的那套规则文档摆在面前我忽然意识到Shove 这个 CLI 战术游戏真正值钱的不是游戏本身而是它把“设计、构建、试玩”三个环节压缩到了同一条命令行工作流里。这个项目让我重新理解了 AI 辅助开发这件事。过去我们习惯让模型“写一段代码”然后再去手动修修补补。但在 Shove 这个项目里Claude Fable 5 不仅生成了代码还参与了玩法设计甚至自己跑了几轮对局来验证规则。整个链路走完以后我最大的感受是真正值得复用的不是代码而是一套让模型参与创作全过程的方法。如果你也想在终端里做一个带策略性的小游戏或者好奇一个 AI 模型能不能不只是“写函数”而是真的把一个项目从想法推到最后可玩的形态这篇文章会给你一条完整路径。1. 先搞清楚 Shove 这类 CLI 战术游戏到底在解决什么问题1.1 为什么我把游戏放进了命令行先回答开头那个问题为什么不做成网页因为 Shove 的核心交互根本不需要网页。命令行天然适合这类游戏原因有几个。第一终端是程序员最熟悉的环境不需要额外打开浏览器、等待资源加载、处理前端布局。第二战术游戏的操作模式通常很简单方向键移动空格确认R 重开。这些操作映射成键盘事件比点击按钮更直接。第三文本界面可以把所有注意力放在“机制”而不是“美术”上这对一个由 AI 参与设计的游戏尤其重要。Shove 这个游戏名的关键词是“推挤”。玩家不是在射击也不是在收集资源而是通过移动自己把场景中的物体或对手推到特定位置。这类玩法在图形界面上反而容易被花哨特效干扰用字符界面表达反而更干净。你只需要一个地图边界、一组坐标、一两个单位就能把战术空间撑起来。终端窗口天然就是一个网格每一行每一个字符都可以是地图上的一个单元格。这种表达方式对 CLI 游戏来说不是妥协而是恰到好处。从开发角度看CLI 也大幅降低了项目的复杂度。不需要处理跨端浏览器兼容、不需要设计响应式布局、不需要考虑图片资源打包。核心逻辑就是一套状态机加一套渲染函数非常适合用来验证“AI 能否从头到尾负责一个完整项目”。1.2 战术游戏的核心是规则可推理不是画面可炫耀战术游戏和动作游戏有个本质区别战术游戏里玩家做出决策时应该能推断出当前局面的利弊。如果信息完全不可见或者规则太依赖随机性玩家就会觉得“这也太看脸了”。Shove 的规则就建立在可推理的基础上。地图是有限的推挤方向是确定的每回合能做的事情是有限的。玩家可以盯着终端里的字符在心里盘算几步之后的局面然后做出选择。这种体验的关键不在于画面多精致而在于规则是否一致。为了让模型也能参与设计我把规则拆成了这样几个要素地图一个矩形网格边缘有墙部分格子有障碍物。单位玩家控制的角色和对手控制的角色都被认为是有体积的方块。行动每回合可以选择移动一步或者朝一个方向用力推挤。胜负通过推挤把对方单位推出边界或者推到障碍物上困住就算赢。这些规则听起来很简单但当两个单位都能推挤而且地图里还有第三方的箱子时局面就会迅速变得有策略性。你推一个箱子过去正好挡住对手的退路这个过程在终端字符里完全可以表达清楚。我让 Claude Fable 5 按照这套核心规则去补充细节很快拿到了一份一致且可运行的玩法描述。这让我意识到AI 做设计的前提是你能把“什么才是有趣的体验”讲清楚。如果你自己都没想明白模型只会给你一堆看起来炫酷但无法落地的功能。2. 用 Claude Fable 5 做游戏设计从想法到可执行规则2.1 第一版需求不能只有一句话很多人把 AI 辅助开发的第一步理解成“提需求”但真正有效的做法是“写产品文档”。如果你只对 Claude Fable 5 说一句“帮我做一个 CLI 战术游戏”它会给你一个泛泛的骨架然后让你自己去补充细节。这不能算错但效率不高。我最初给 Claude Fable 5 的输入不是一个句子而是一小段结构化描述包含四个部分项目目标做一个能在终端里快速完成一局的推挤战术游戏。运行平台命令行跨平台优先不考虑图形界面。核心机制移动、推挤、回合交替、有限地图。交付要求先给玩法规则再给可运行代码每一步都要有可以验证的检查点。为什么要这样写因为模型生成内容的质量高度依赖上下文的确定性。你告诉它“要一个战术游戏”它可以往任何方向走但你告诉它“移动一次算一个行动点推挤一个箱子会让箱子移动一格如果箱子后面是墙就推不动”它的输出就会收敛到一套可实现的规则上。这里有一个很容易被忽略的点第一版需求不要急着要求模型“写完整代码”。我先让 Claude Fable 5 输出一份玩法规则文档内容包括地图尺寸、单位数量、胜利条件、平局判定、操作键位。拿到这份文档后我们再一起检查规则之间是否有冲突。如果有冲突比如“推挤同时允许玩家穿越箱子”模型自己通常很难发现因为它在生成文本时是一段段推理的。这时候需要人来做一致性检查然后把修正意见再喂回给模型。这个来回过程其实就是产品经理和开发之间的循环只不过这次开发由 AI 完成。2.2 让模型先写玩法文档再写代码过去我用 AI 写代码时最大的问题是“代码能跑但结构很乱”。原因很简单模型在生成代码时并没有先想清楚整体设计。所以这次我刻意调整了顺序先让 Claude Fable 5 产出两份文档然后再让它写代码。第一份是游戏机制说明。里面规定了单位如何表示、推挤的判定顺序、墙和障碍物的区别。第二份是数据结构草案。我要求它用 JSON 描述一个地图状态包含网格尺寸、障碍物位置、每个单位的坐标、行动顺序。这两份文档看起来不直接产生价值但它们在后续生成代码时起到两个作用。第一模型在写代码时可以直接参考自己刚刚生成的规则代码和设计天然一致。第二我们在试玩阶段发现问题时可以快速回溯是规则设计得不对还是代码实现没有遵守规则这也是 Shove 能在一个晚上从零跑到可玩状态的关键原因。如果直接让模型写一个大文件中间任何一个变量名不一致都可能导致程序直接崩溃。但分了模块之后模型每次只需要生成一个小函数出错范围被限制了。2.3 设计阶段最容易忽略的三个约束AI 模型的强项是“生成”但它不太擅长判断“这个设计在真实终端里好不好用”。所以在设计阶段我做人肉边界检查时特别关注三个约束。第一信息密度不能太高。终端一行最多能放 80 到 120 个字符如果一次把地图、物品栏、行动日志、提示文字都塞进画面玩家根本看不清重点。Shove 的做法是始终把地图放在画面正中央把状态栏压缩到两行以内。第二输入延迟会破坏游戏节奏。战术游戏虽然不像动作游戏那样追求毫秒级响应但如果你按方向键后要等 300 毫秒才看到移动体感就会很糟糕。这个问题在 CLI 里很容易被忽视尤其是当你用了某些“非阻塞输入”库时轮询间隔调得太长就会造成明显延迟。第三随机性会让调试变得很痛苦。AI 在设计时很喜欢加“暴击”“随机掉落”之类的东西但在命令行原型阶段随机数会让每一步都不可复现。我要求 Shove 的所有行为都基于固定种子至少第一版是这样。这样出了问题可以稳定复现模型也能根据错误日志快速定位。这三个约束本质上是在说AI 擅长给你提供可能性而你要负责砍掉那些让项目变脆弱的可能性。3. 构建阶段让 AI 生成代码变成可维护项目3.1 先跑通一个最小可运行版本任何项目跑到生产环境前都要先有一个“最小可运行版本”作为地基。Shove 也不例外。我要求 Claude Fable 5 做的第一版不是完整游戏而是一个能显示地图、移动一个单位、遇到边界就停下的小程序。这个版本不包含胜负判定不包含对手 AI也不包含推挤机制。它只验证一件事终端渲染是否正常键盘输入能否被正确读取状态循环能否运转。这一步的价值被很多人低估了。直接让模型生成完整游戏往往会产生一个很大但无法定位问题的代码块。先跑最小版本我们才能确认最底层的地基是稳的。如果连光标移动都卡顿后面加再多功能都是浪费时间。下面是一个简化后的输入循环示例结构上就是 Shove 早期版本的样子import os def clear(): os.system(cls if os.name nt else clear) def render(game_state): clear() for row in game_state[map]: print(.join(row)) print(fPlayer: {game_state[player_pos]}) while True: render(game_state) key input(Press a key: ) if key w: move_player(0, -1, game_state) elif key s: move_player(0, 1, game_state) elif key a: move_player(-1, 0, game_state) elif key d: move_player(1, 0, game_state) elif key q: break这段代码非常初级它甚至没有用按键监听而是用input()等待回车。但好处是极容易理解。等最小版本跑通之后再去替换成更顺手的输入方案风险就小很多。3.2 核心模块拆开AI 才更好配合当整个项目是一个文件时Claude Fable 5 也能工作但迭代效率会明显下降。因为模型每次重新生成整个文件都可能不小心改掉已经能跑的功能。所以我把 Shove 拆成了四个模块模块职责对应问题状态模块保存地图、单位坐标、行动顺序规则错乱渲染模块把状态转成终端字符显示不全、乱码输入模块读取方向键和功能键输入无响应、延迟流程模块连接输入、更新状态、重新渲染循环卡死、退出异常每个模块都交给 Claude Fable 5 单独实现然后在主文件里拼接。这样做有两个明显好处。第一出问题时定位快。比如渲染错位只需要检查渲染模块移动方向不对只需要检查输入模块和状态更新逻辑。第二生成结果更稳定。模型在生成单个模块时上下文更短注意力更集中代码质量通常比生成整个项目时高。实际操作中我会让 Claude Fable 5 先输出一个模块的接口定义比如“move_player(dx, dy, game_state) - bool”然后再填充实现。这样主流程可以先写好调用逻辑等所有模块到齐后直接装配。3.3 处理 CLI 的脏活累活CLI 游戏和普通脚本最大的差别在于它需要处理终端特有的细节。这些地方特别适合让 AI 代劳因为有很多现成经验。比如清屏不同操作系统命令不同。在 Windows 上可能是cls在 Linux 和 macOS 上通常是clear。又比如光标移动可以用 ANSI 转义序列也可以直接用curses库。再比如输入法某些终端会把中文输入法按键也推到程序里导致按方向键出现奇怪字符。这些问题的解法都不复杂但是很琐碎。如果全靠手写一晚上可能耗在里面。我让 Claude Fable 5 生成了一段统一的终端交互封装把清屏、隐藏光标、读取方向键、恢复终端的逻辑都收拢到一个类里。后续游戏逻辑只调用这个类的接口。这里有一个重要提醒AI 生成的终端交互代码一定要在真实终端里测一遍不能在编辑器内置终端里想当然。不同终端的 ANSI 支持程度不同Windows 旧版终端和现代终端差异很大。Shove 第一版跑出来时我在自己电脑上完全正常换到一个远程会话里就出现了输出不刷新原因是终端类型变量没有设置对。这种问题只能靠实际环境测试来发现。4. 试玩阶段用真实手感反推迭代方向4.1 让模型也参与试玩标题里的“played”在我这个项目的语境里有两层意思。一层是我自己在终端里试玩另一层是我让 Claude Fable 5 生成了一组自动对局记录模拟玩家连续输入观察每一步状态变化。很多 AI 生成的游戏代码能跑但“不好玩”。因为你只看静态代码很难想象真实操作时的手感。模型也一样。所以我在完成第一版之后先没有急着自己玩而是要求 Claude Fable 5 写一个“自动试玩”脚本在固定随机种子下连续执行一系列合法操作把每一步的地图状态打印出来。这一步非常值得做。它相当于把整个游戏逻辑跑了一遍冒烟测试。如果代码某个状态更新顺序有误自动试玩一遍就会暴露。比如说我先让角色移动然后推箱子箱子撞到墙这个动作触发了边界检测错误自动试玩日志里就能看到单位穿墙了。让模型参与试玩不是让模型真的坐在电脑前按键而是让它生成对局模拟器用逻辑去验证逻辑。这种“模型写的游戏让模型自己跑一遍”的闭环能大大缩短人在试玩阶段的排查时间。4.2 排查链路从现象到根因试玩阶段一定会遇到问题关键是别乱猜。我给自己定了一个排查顺序先看现象再看输入再看环境再看参数最后回到代码逻辑。如果现象是“按下方向键没有任何反应”优先检查输入模块是否进入了非阻塞读取模式其次是终端是否为原始模式。如果现象是“渲染画面闪烁严重”优先检查清屏和重绘顺序看是否每次渲染都先清空再逐行输出。如果现象是“某个推挤动作结果和预期不符”优先检查状态更新顺序看是不是先移动了单位再检测碰撞导致越过了障碍。如果现象是“在不同终端里表现不一致”优先检查 ANSI 转义序列和终端类型环境变量。这几个现象基本覆盖了 CLI 游戏最常见的故障。在排查时每一次修改都只动一个变量。比如先只调整渲染刷新方式跑一局确认没问题了再去调输入读取间隔。下面这个表格是我实际用过的排查链路可以直接复制到自己的项目文档里现象第一层排查第二层排查常见根因输入无响应是否进入输入循环终端原始模式输入模块被阻塞方向键变成字符是否有回显是否过滤转义序列输入库兼容问题画面闪烁刷新是否整屏重绘是否添加延时渲染策略太粗暴单位穿墙移动前后位置打印碰撞检测位置移动和碰撞顺序反了AI 生成代码跑不了官方示例能否运行依赖版本版本不匹配4.3 把试玩发现变成测试用例人脑试玩很容易漏掉边界状态。比如箱子推到边界时应该怎么处理、两个单位同时想进入同一个格子时应该判定谁先谁后、障碍物是不是可以穿过。这些问题如果只在脑子里过很难覆盖完整。所以我会把每次试玩发现的规则问题直接转化成一个单元测试。比如有一条规则是“玩家不能穿过箱子”那我就写一个测试把玩家和箱子放在相邻格子输入向右移动预期是玩家保持不变箱子也不变。如果测试失败说明代码里把碰撞检测写在移动之后了。用测试用例代替口头修改说明还有一个额外好处你可以把这些测试用例再喂回给 Claude Fable 5。它看到具体输入输出之后会更容易理解到底哪里出了问题而不是靠猜。从 Shove 的实际效果看测试驱动不一定很严格但只要覆盖了“移动”“推挤”“胜负”三个核心逻辑后续改功能时就有了一张安全网。5. 从 Shove 沉淀出的可复用框架5.1 一个三步法写文档、搭骨架、按模块迭代Shove 项目走完之后我把这套流程提炼成了一个三步法适用于大多数 CLI 小工具或小游戏第一步写产品文档。不用完整 PRD但要写清目标、平台、核心机制、交付要求。重点是把“好玩”翻译成“可验证的规则”。第二步让模型生成骨架代码。不要求骨架包含全部功能只要能渲染界面、读取输入、更新状态即可。这是整个项目的脊柱必须由人工确认稳定后才能继续。第三步按模块迭代。每次只让模型改一个模块改完立刻跑测试和试玩。有回归就撤销重新给模型更精确的上下文。这套方法的核心不是“让模型写更多代码”而是“让模型每次只需要解决一个小问题”。大量失败案例都源于一次让模型生成太多函数出现问题之后难以定位。拆小块既有利于模型生成质量也方便人类审查。5.2 常见坑点速查如果你是第一次做 CLI 游戏下面这八个坑点可以帮你少走弯路不要一开始就用复杂的 UI 库先用普通print跑通流程。不要忽略跨平台差异Windows 和 Linux 的终端行为不一样。不要使用输入框等待回车战术游戏的正常手感是靠单个按键触发的。不要把整个地图状态存储在一个二维数组里就完事要同步维护单位坐标和历史状态方便撤销和调试。不要让随机数参与核心判定至少第一版要用固定种子。不要一次性清屏并重绘大量字符容易闪烁可以改用光标定位。不要把 AI 生成的大文件直接当作最终代码先格式化、补注释、划分模块。不要相信“代码能跑”就等于“规则正确”必须完整跑几局对照规则检查状态转移。5.3 适用边界什么项目适合这么干什么不适合AI 辅助开发不是银弹。Shove 这种项目适合用这套流程是因为它天然具备几个特征逻辑闭环清晰界面表达简单依赖少规模小并且允许快速迭代。如果你想做一个大型引擎、一个需要严格数据一致性的交易系统或者一个安全敏感的 CLI 工具我建议还是把 AI 定位在“自动补全”和“生成测试用例”的角色不要让它自己设计核心规则。判断标准很简单如果这个项目出问题时你可以很快从报错信息里定位到状态或逻辑那它适合让 AI 参与。如果错误可能来自并发、外部服务、安全边界这种复杂环境那它就不适合完全交给 AI 自主设计。先跑通最小版本保持模块边界保留人工审查是任何场景都不会错的原则。回到 Shove 本身。这个项目给我最大的启发不是“以后连游戏都能让 AI 做了”而是“当设计、构建、试玩都变成可迭代的闭环时技术创作的门槛正在发生变化”。你不一定需要先精通所有终端底层细节也可以借助模型快速做出一个能玩的作品但你必须仍然理解什么是好的规则、什么是可维护的结构、什么场景下需要人工干预。如果下次你看到有人在命令行里玩游戏别急着问为什么。打开编辑器把规则写成文字让模型帮你搭出第一版然后亲手试玩一遍。你会发现一条全新的开发路径已经铺在触手可及的地方。
返回列表