这篇日志讲心路历程。想试试游戏成品,可以直接点击:在线游玩。
去年12月初,和家属去了趟日本玩。在东京代官山的茑屋书店看到在卖这么一款桌游:

游戏的名字叫「Nego」,用石膏做成各式猫形的棋子,按围棋的原生规则玩。名字取的是「Neco」(日语的猫)+「Go」(日语的围棋)的合体。
最后并没有买,但我还挺喜欢这种简简单单地稍微衍生一下耳熟能详的规则,从而带来短暂新鲜感的小游戏。桌游亦是此类游戏的最佳载体。继续逛书店时,我的脑子就有一半默默地切换到游戏设计者模式了。
棋类游戏里面,我能算是「下得可以」的,只有中国象棋。我已过世的爷爷在我很小时,就开始教我「马走斜日,象飞田」。那时,我与家里亲戚下棋,只会输给他一个人。在我离开老家前,他对我的让子也逐渐减少到了一个马(倘若我有通感,那「马」一定是「老辣」的)。之后的小学兴趣班也一直上的象棋课,会买一堆残局棋谱自己摆着玩。虽然小学五年级之后基本没再下过(那又是另一个故事了),但象棋在心里保留了一个独特的位置。

被「Nego」的几何形状拓展启发,我最初萌生的想法是,把两个象棋棋子组合成一个占据两个棋盘格子的「组合棋」,然后绽放新的能力。例如,「马」+「车」=「马车」。这是只有中国象棋才能玩的文字游戏。但我马上抛弃了这个「棋子结块」的想法,因为「Nego」的棋子衍生形状会与围棋的核心规则「围」产生直接互动,却很难助益象棋的特色——善用不同能力的棋子联立攻防。但沿着「文字游戏」的启示,我有了更有趣的联想:
- 「火」+「车」=「火车」
- 「水」+「车」=「水车」
- 「风」+「车」=「风车」
- 「电」+「车」=「电车」
火车、水车、风车、电车,这四对名词所指代的物体,和火水风电四元素,以及象棋里的「車」(指的是战车),有些妙趣联系。这为组合后的棋子能力提供了自然的灵感材料。在这一刻,「元灵象棋」以汉字成词作为灵感的「元」素组合机制,便已成型。
而游戏的流程机制,我第一时间圈定在了「残局」/「排局」的范围。可以采用残局常见的「连将」方式,即红棋的每一步都需要将黑方的军,来释放棋子新能力的作用,又让游戏节奏紧实有趣。毕竟,这也是象棋残局系统经过数百年锤炼过的玩法。我当时在笔记本上随手记下的游戏项目代号,就是很土的「将个不停」。后来,出于种种考虑,游戏没有使用「连将」作为牵引线索,而是放宽为了「3-5步内取胜」的类似限制,将一局的游玩时间和复杂度,框在了休闲手游的小体量里。
想归想,当时只是作为好玩的头脑体操,并没有打算要真正做出来。毕竟,我做完上一个游戏可是花了一年半。非常杯弓蛇影PTSD。
12月底的一天,我闲着,就下载了谷歌的AI代码编辑器 Antigravity, 想试试现在 Browser Use Agent 的能力。作为试验项目,我描述了这个游戏的想法。这是它第一版代码的结果:

简陋归简陋,能让我在视觉上感受这个游戏,善莫大焉。几轮速测之后,我很快意识到,这游戏没我之前想得那么好玩。因为,我忽略了一个显而易见的关键因素:黑棋的AI。
象棋残局之所以好玩,不管是「连将」(每一步都将军)还是「冷着」(看似闲棋,但对方无论如何应对都将落于下风),是建立在敌棋的「理性应对」之上。儿时的我摆弄象棋残局,自己也同时在扮演敌方棋手的角色,切换立场思考。这样能保证双方的每一步,在某种意义下有理性张力。而仅仅依赖元素融合机制和大致的游玩框架,这个未实现AI的原型游戏,无法提供令人满意的张力。
接入AI引擎这件事,单在概念上来讲不困难。传统的象棋AI都有开源版本(国象的 Stockfish,中象的 Pikafish)。现代的 AlphaZero 也有很多开源实现。实在不行,就算用 PyTorch 自己从头手搓一个,也不是不会啊。
但很花时间。毕竟,我做完上一个游戏可是花了一年半。非常杯弓蛇影PTSD。
况且,我并不是真正想复制整个象棋游戏的博弈复杂性。在我脑海里,这应是一个可以在闲暇时提供半个钟头的新鲜感、博数人莞尔一笑的小游戏,和桌游 Nego 一样,仅此而已。它和真正的象棋不一样。它是一个提纯了象棋残局式的箱庭思考乐趣的小体量游戏。
于是,在花了一天鼓捣出最小可行原型后,这个象棋小游戏的想法再次被搁置积灰。
但本次使用 Antigravity 的体验让我相当舒心。之前用过 Claude Code,额度经常被瞬间用完,没法真正专注于完成一件事。而谷歌的额度给的那是极为慷慨:同样的20刀订阅,它不仅 Claude Opus 的模型额度比 Claude 自家都要高不少,而且 Gemini 3 Pro 基本是无限额使用。更能产生对比的是,由于上一次是第一次做游戏,绝大多数的工作都是抱着学习的心态在 Godot 界面里手搓。Godot 是为开发者直观操作而设计的引擎,有许多只能在界面里手调才显得合理的功能。这意味着 LLM 很难操作它。而这次原型开发使用了网页前端的原生态(Javascript/HTML/CSS),钢筋、混凝土、砖头,全都在代码里,而且是 LLM 训练材料里最普遍的数据之一。

所以,我没写一行代码,甚至没读任何一行代码——我根本不会Javascript。这是我第一次在完全不懂相关技术栈、未审核任何代码的前提下,用自然语言——中文——指导LLM完成了原型的实现。感觉很奇妙。
今年1月11日,我又把这个原型项目捡了起来。原因之一是,我灵光一闪想到了个低成本解决黑棋AI的妙招:非对称规则。这游戏,本来就是解谜过关,敌棋AI存在的目的,纯粹是为了阻拦玩家在限定步数内将死黑方,同时又能激励玩家思考出对策。完成这个目的,不需要AI做全然理性的多步思考。AI可以很蠢。事实上,愚蠢的AI,更方便玩家在这样一个休闲类游戏里揣摩其动向、并制定策略的。可游戏的张力怎么办呢?我的解决方案就是:给每个敌棋赋予一个独立行动的AI。独立行动的意思是,在同一回合,黑方可能有多个棋子按自身规则行动。而玩家依然只能走一步棋。
这是违背对弈类游戏的直觉的。要么一方走一子,要么和战棋游戏一样,双方的每个子,在一回合中都可以分别行动。但「我一动、敌多动」适合本游戏的闯关解谜机制:红方需要在N步之内获胜,这本来就不是一个机制对称的游戏——在大部分关卡中,红方甚至都没有帅/将,全是进攻子力。只要想通了这点,我便可以为敌棋设计简单、容易被玩家掌握的行动规则,同时灵活调整AI棋子的多少来打磨单个回合的压迫感和思考量。而「以少胜多」、「智胜蛮力」,也非常符合游戏主题。
就这样,「元灵象棋」的「灵」的部分,也确定下来。小游戏的脉络已经非常清晰,可以实现了。
于是吭哧吭哧指挥AI干活。1月16日夜里,我忍不住发了条朋友圈:
满打满算用了六天做了个原创机制的纯js网页小游戏。除了改改css调色,没读、写一行代码。也写不了读不懂,因为对js/前端我是一窍不通。截图上看不出来,其实有四天花在了动画、粒子、音效、UI适配的打磨和微调之上,真正的核心机制两天就原型验证完毕了。现在的手感我很满意。从头到尾都是claude/gemini在antigravity里面写,我的工作就是测试并指指点点、网上找了几个音效做了处理、以及用它们写出来的关卡编辑器设计谜题(AI的谜题设计真的烂到发指)。就这么说吧,做不出东西来或者学不会东西现在是真的没有借口……
当时配的图,已经和最后的正式版区别不大。能够单凭一张嘴,让AI把动画流畅度、视听手感打磨到我本以为只有 Godot 里面手调才能达到的程度,非常出乎意料。有感而发。

开发工作持续到了1月31日。又陆续加入:
- 自制关卡编辑器
- 社区关卡云端数据库
- 从40关扩展到了100关谜题
- (未使用)程序生成关卡、AI生成关卡的流水线测试。就算给了100关的示例,依然很烂。
- 支持八国语言、可切换棋子图标/汉字(国象风格图示)
- 多次代码重构、整理
- 安卓App封装和适配(包括激励广告。就……体验一把)
- Play Store 和 TapTap 平台上线准备工作和宣传物料
关卡谜题是我设计的,音效、图标、字体是我选的公共领域资产,少量CSS样式代码我手调过。除此之外,都是AI干活,我验收。

Google Play 的版本正在封测中,将于近期上架。上平台是我想做通全套流程体验,但你已经读到了本文——最开头的链接,就是《元灵象棋》的全部。免费无广告,可离线游玩。
20天,做出一个上架而不会心虚的小游戏,在没有前端/App开发经验的前提下,算是相当麻利了。这次没有杯弓蛇影PTSD。感谢AI时代。
