十月到现在,我一直没有更新博客,一方面是这段时间事情确实比较多,另一方面是国庆假期开的新坑,挖了一个大窟窿,不填上的话浑身难受,所以半个多月有时间就在填坑,折腾代码和调试。而这个大坑,正是——NekoMote
至于开坑并把自己折腾得筋疲力尽的缘由,其实有好几个方面:
- 第一点,也是最主要的:之前的猫娘壁纸是用 KDE 的 HTML Wallpaper 插件,本质上就是套了个 Qt WebEngine 这玩意约等于一个 Chromium ,也就是,浏览器套壳。而我个人对于 Electron 这种狗屎套壳浏览器应用本身就非常的反感:占用资源一大坨。另外这玩意的资源占用确实也不小,所以,我打算原生开发一个 Linux 的动态壁纸插件。
- 第二点,是直接推动力:ChatGPT 6 出来了,而且能力非常的炸裂,我个人感觉进行从零开发和适配已经成熟。
- 第三点,坚实后盾:华为云的 CodeArts 有无限量的 GLM-5.2 可以用,基本上是 Token 自由,可以让 ChatGPT 负责攻坚,难度不高的工作丢给 GLM-5.2。
还是那句话:
天下词元谁最多,大家都说是华为。词元耐用速度快,国产模型不限量。华为好呀华为美,华为给我增Token。

另外,华为云还在积极送钱,前段时间一天可以白嫖 87 块钱呢!华为云恩情还不完!
你说的对,但是华为云是由华为公司自主研发的一款全新全栈云计算服务平台。平台运行在一个被称作「数据中心」的云端环境,在这里,被平台选中的人将被授予「代金券」,导引算力之力。你将扮演一位名为「开发者」的神秘角色,在自由的云端使用中邂逅规格各异、能力独特的云服务产品,使用它们构建应用,攻克Bug,部署上线——同时,逐步发掘「华为云」的真相。
当时想了想开发就开发吧,国庆这么长的假期,怎么也开发完了吧,然而事实却非常打脸:加上假期结束后开始上课的碎片时间,开发了差不多半个月。
其实当时开发的时候,因为 OpenAI 的服务器被挤爆了,速度非常慢,以至于我在另一台电脑给 Codex 开了 Full Access 模式,留了RustDesk远程控制,就和朋友跑去 CICF 看漫展了:
反正开发就这个速度也要跑好几天才能开发完成,直接去玩了。
这一次的开发经历,让我深刻体会到了 AI 时代的生产力革命:一个人,单枪匹马,甚至之前从未接触过 C++ 编程,靠 AI 编程,不到两周时间做出来了当年要投资四五百万组织一个小型开发团队才能开发出来的 C++ 2D 动画引擎!
我个人现在有这样的感觉:随着AI的发展,再过几年,当AI的能力强大到可以完全自主测试和开发大型软件项目后,很多专有软件垄断的日子就应该到头了,全民开发的时代将会到来。
废话了这么多,接下来,请让我介绍—— NekoMote
想利用 FreeMote 快速实现动态壁纸:失败
之前我尝试搞的 NekoWebShow ,其实对于动态立绘的驱动我用的是 FreeMote 的 WebGL SDK ,当时看到这个项目是开源在 GitHub 上面的,想着干脆利用源代码,快速构建一版桌面背景。原项目是 C# 写的,虽然在 Linux 用不了,但是有代码的话让 AI 参考开发至少能快一点。但是让 ChatGPT 帮我分析了源代码后,事实狠狠打脸了——FreeMote 的核心解算器闭源!
FreeMote 并不是一个仓库,而是一套"全家桶":主仓库 FreeMote 、接口仓库 FreeMote-SDK 和封装仓库 FreeMote.NET 。挨个扒开看:
- 主仓库 FreeMote 是 C# 写的 PSB 工具链:解包、打包、格式转换、纹理处理,这部分是真材实料, NekoWebShow 的素材就是靠它从
.psb解成 JSON + PNG 图集的。但是仓库里唯一带"绘制"字样的源码StaticMotionPainterCore.cs只是个静态绘制器:在 CPU 上画某个时刻的代表帧,连变换继承都是拿仿射近似糊弄的——这玩意是个截图工具,不是动画引擎。 - FreeMote-SDK 呢?打开一看就一个
iemote.h接口头文件,外加一个 Windows DX9 示例工程。示例链接的是emotedriver.lib,一个闭源静态库。更有意思的是,头文件里的平台分支有 Apple 、Android 、Windows 和 Emscripten ,唯独没有 Linux 。发布页我也翻了个遍,公开列表里最新的 v3.8-beta.1 挂的是FreeMote_DX9_Lib_Res_v3.8.rar,清一色 Windows 库,Linux 的.so?不存在的。 - FreeMote.NET 更绝,就是个 C++/CLI 包装层:调用 Windows 原生 DLL 的
Progress()/Render(),渲染走 D3D9 ,还有个RenderToBuffer接口靠GetRenderTargetData把画面逐帧读回系统内存。就算它能跨平台,这套架构放在壁纸这种长期低功耗的场景里也是反面教材。
那 NekoWebShow 的网页版是怎么跑起来的?WebGL SDK 的 driver 目录里躺着一个巨大的 FreeMoteDriver.js ,虽然扩展名是 .js ,但开头赫然写着 "use asm" 和 EMSCRIPTEN_START_ASM ——这是 Emscripten 编译出来的 asm.js 产物,连 WASM 都不是,是更原始的形态。也就是说我看到的从来就不是源码,而是编译产物,相当于下载了一个没有符号表的 exe ,然后指望照着它重写程序。
至于 E-mote 本尊,那是日本 Mtwo 公司的商业中间件,官方 SDK 是要掏钱买的,而且 E-mote 的 SDK 根本没有 Linux 的支持选项。FreeMote 能放出工具链和编译产物,但核心源码显然不在放行清单里。
ChatGPT 最后的总结相当精准:FreeMote 的准确描述是"公开源码的资产工具与接口封装,配合未公开完整源码的播放核心"。而雪上加霜的是,主仓库的许可证还是 CC BY-NC-SA 4.0 ,带非商业限制,按 OSI 的开源定义(不得限制任何使用领域),这项目严格来说连"开源"都算不上,只能叫"源码可见"。合着这个项目叫 FreeMote ,这里面的 Free 是免费不是自由是吧()
中间我也想过一些歪门邪道:既然网页核心是 asm.js ,那走 asm.js → WASM → wasm2c → 原生 C 的转换链,理论上能把黑盒翻译成机器码塞进 Linux 程序里,工具链都是现成的( Binaryen 的 asm2wasm 和 WABT 的 wasm2c )。但转出来维护性稀烂:线性内存、Embind 绑定、一大堆 _gl* 导入全得自己写宿主实现;而且 CC BY-NC-SA 的许可不会因为你把编译产物翻译成 C 就凭空消失,后续的代码也要用这个许可证,没办法变成自由软件。这样子做的话,等于抱着一坨看不懂的祖传代码过日子,果断放弃。
顺便把类似的项目 Live2D 也调查了。 Cubism 这边就厚道多了:Cubism Native Framework 把 GPU 绘制、遮罩、动作混合、物理实现全部公开,连 Vulkan 后端都有,参考价值拉满。但是——决定"参数怎么变成顶点"的 Cubism Core 照样闭源,只发二进制;而且 Live2D 的模型主体是 .moc3 格式,和 E-mote 的解包 JSON 完全不通用,想用就得从头重新建模。参考它的架构设计没问题,指望直接拿它播放 E-mote 模型?门都没有。
调查到这里,结论已经非常清楚了:市面上根本不存在能直接使用的开源 E-mote 运行时。想要原生,只有一条路——自己写一个。
创建路线图和项目文档
因为之前开发比较大型的项目来玩的时候,吃过项目没有文档规范和组织,Agent 开发给我乱来的亏,给我开发出“高耦合,低内聚”的奇葩玩意——项目就是屎山,一个中小改动项目全部塌完。所以在前面和 ChatGPT 讨论和对相关项目进行挖掘后,制定了大概的工作方向:
- 项目需要使用 C/C++ 进行开发,实现低占用,高性能。
- 素材直接复用 NekoWebShow 的解包成果:模型 JSON + PNG 图集 + 展示/反应配置一应俱全,不从 PSB 层重新折腾。
- 壁纸本体和桌面接入必须解耦:核心只有一套,Plasma 也好 GNOME 也好,都只是外面包的薄适配层。
- 先做独立窗口播放器把模型跑通,再接桌面,不一口气铺开所有桌面。
- 技术栈定 C++20 + CMake ,图形从 OpenGL 起步。
- 第一个验证模型选 chocola-date-a :非空网格、参数化、遮罩字段全齐的最难啃的硬骨头,它能对了,其他型号才有戏。
但是光有方向,不等于能开工。
之前的项目吃过亏:AI 这东西,单次对话里聪明得不行,跨了会话就是失忆。今天聊得明明白白的架构决策,明天新开一个会话,它两眼一抹黑从头问你;你要是懒得再解释一遍,它就自由发挥——反正它对你项目的理解全靠上下文里那点东西。更糟的是它还嘴硬,特别擅长"宣布完成":建了个空目录敢说"模块已搭建",跑通一个 hello world 敢说"基础架构可用"。等你在几千行代码里发现它第二遍造轮子的时候,重来的成本已经高到肉疼。
所以这次反着来:先不写代码,先立规矩:让 ChatGPT 把项目的开发规范和文档定好。
10 月 3 日下午,新仓库的第一次提交诞生了,四份文件,没有一行引擎代码:3 行的 .gitignore ——顺手把 AI 工具目录和调查用的参考仓库排除在外;12 行的 README.md ;然后是两份真正的大头:210 行的 AGENTS.md 和 416 行的 ROADMAP.md 。
AGENTS.md ,名字直白,就是写给 Agent 看的项目宪法。最有含金量的是一张模块边界表:model 、runtime 、asset_io 、importer 、render_gl 、application 、preview 、adapters 八个模块,每个都写清"主要职责、允许依赖、禁止依赖"三件事。比如 model 只准碰 C++ 标准库和数学基础,禁止依赖 JSON 库、图形 API、窗口和桌面;runtime 负责参数、动画、变形、物理的求值,禁止 OpenGL 和 Qt;渲染协议里只许有顶点、索引、纹理 ID、遮罩和混合,不许混进 JSON 节点和窗口句柄。构建目标之间的依赖必须无环,核心模块在没有显示服务器的环境下也要能构建和测试。
往后是成套的 C++ 编码约定:类型 PascalCase 、函数和变量 snake_case 、4 空格缩进、RAII、强类型 ID 防止各种 ID 混用……细到发指,但 AI 就吃这套——规则越明确,它自由发挥的空间越小。
还有专门针对壁纸场景的性能规范:壁纸是 7×24 小时挂在桌面上的,稳态帧路径不许有堆分配,不许每帧重建场景、上传纹理,禁止 GPU → CPU 像素读回,热路径不许写字符串日志。以及错误处理的底线:不支持的资产版本、缺失的必需字段必须明确报错,禁止捕获之后返回成功、空图或默认值来掩盖缺陷。
而整份规范里最有先见之明的一条,藏在 Agent 执行规则里:
"禁止仅因目录/类已创建就宣布阶段完成。"
这条就是给 AI 的老毛病量身定做的,不得不说还是 AI 了解 AI。配合"依据真实文件更新阶段状态"、"不能把近似效果当作原素材还原成功",等于把丑话全部写在了最前面。
ROADMAP.md 则是把"怎么走到终点"算清楚:P0 到 P10 十一个阶段,每个阶段都有工作项、交付物和退出条件,外加 M1 到 M5 五个里程碑。P0 工程骨架,P1 素材审计,P2 静态绘制,P3 参数和网格变形,P4 遮罩合成,P5 时间线动画,P6 物理和音频,一路到 P8 的 Plasma 适配、P9 的全素材长期运行、P10 发布。里程碑 M1 定为"一个真实复杂模型的原生静态求值与绘制闭合",路线图自己都标注:这是"决定后续大规模投入的第一道主要门槛"——翻译一下就是,这关过不去,后面全白搭,趁早止损。
退出条件也写得毫不含糊。比如 P3 的门槛:"未支持的变形必需语义仍明确失败,不用静态/线性近似绕过阶段门槛"——变形差一点、轮廓歪一点,截两张图不仔细对比根本看不出来,这种地方宁可当场报错,不许拿近似效果糊弄过关。
最难得的是这份文档的诚实。阶段状态表清一色"未开始";开头自我声明"完成源码调查和开发规划,尚无引擎实现";风险表把项目最大的几个未知直接摆上台面:mesh.bp/cc 字段的语义没人说得清、继承和遮罩位可能理解错、长期运行资源会不会涨。没有画饼,没有"预计三天完成",甚至没有一句乐观的废话。
为什么要在没有一行代码的时候先花一个下午让 ChatGPT 写这个?因为 AI 编程真正的坑从来不是"写不出代码",而是失忆和嘴硬。文档进了仓库,就变成了项目的外部硬盘:任何一个 Agent 进来,读完两份文档就知道项目是什么、边界在哪、走到哪一步、下一步干什么,不用我从零口述,它也赌不了"这个上下文里你没说过"。说白了,这一下午相当于把项目经理的活也外包了——规矩 AI 起草,计划 AI 排期,我只负责拍板和验收。
后面的事实证明,这刀磨得血赚:文档提交 38 分钟后,P0 工程骨架落地;当天之内,P0 到 P3 四个阶段接连通过;第二天凌晨,P4 的遮罩合成已经在跑测试了。
AI 推进开发:从单干到团队协作
因为那段时间恰好 OpenAI 准备要重置额度,而我(朋友)的额度当时剩余非常多,所以前期我基本上是靠 Codex 的 ChatGPT-6.1-Sol 推进的。但是,由于项目文档足够清晰,项目骨架的搭建交给 CodeArts 的 GLM-5.2 也没什么问题,可以节省 Codex 的额度用于后面高难度的项目攻坚战。因为有明确的文档指引,P0阶段的骨架搭建很快就完成了,后面就是交给 ChatGPT 了,毕竟两天后重置,不用白不用。
ChatGPT 单飞
把项目复制到独立的一台电脑上面,然后,Codex 启动!/permissions>Full Access。接下来就是一句话:
请你参考项目相关的文档和技术路线图,进行壁纸引擎的开发,最后需要交付完整可用的动态立绘引擎,每次完成一个功能,请进行代码提交。
回车执行后,配置好 RustDesk 远程控制,收拾好东西,直接和我朋友去 CICF 玩上几天。在我外出游玩的那几天,ChatGPT-6.1-Sol 如同黑奴一般,日夜不停地进行代码的测试和迭代工作:
- 10 月 3 日下午,接手审查:进场第一件事不是闷头写代码,而是把已有的 P0/P1 成果翻了个底朝天,当场揪出一串问题:P0 明明关了预览测试,构建还是强行拉一套 GLFW 依赖;P1 导入器更严重——motion 级参数、图层类型、遮罩组合引用等字段在导入时直接丢失,null 被悄悄变成 0 ,畸形 bp 被当作无 bp ,解析错误还会直接抛到宿主进程。全部修掉之后,把 195 条型号目录重新审计了一遍:193 条结构导入通过,剩下的 milk-winter 缺 JSON 、vanilla-lolita 图集 icon 越界——这俩是素材本身的坑,不是代码的锅。顺手把原 WebGL 的参考截图捕获归档,作为后续一切画面对照的基准。
- 10 月 3 日傍晚,P2 静态绘制:图集上传、透明合成跑通。主模型口部按 1×/2×/0.5× 缩放加半透明,和原网页逐像素对照,alpha 和 RGB 最大差都只有 1/255 。GPU 生命周期、resize、稳态零堆分配全部实测通过。
- 10 月 3 日晚上,P3 变形语义:第一场硬仗。30 组固定姿态输入与原 PSB 顶点对照,阈值 0.001px ,实测最大误差不到 0.0003px 。meshCombine 是同域控制点位移叠加、clampControl type=0 是保持方向的三角函数半径映射——这些文档里根本不存在的语义,是它靠只改 6 个字节的内存 fixture 做隔离实验逆推出来的。原生场景跑通后,CPU 单帧求值 P50 只要 0.63ms 。
- 10 月 4 日凌晨,P4 遮罩合成:又抓到一个阴间细节:原 WebGL 声称上传 type=4444 纹理,实际显存里躺的是 5/5/5/1 的 RGB5_A1 ,实际查询显卡才确认。改正后,1200×2000 的完整身体 0.65 倍缩放对照,alpha 零差、RGB 最大 1/255 。没过的 7 张图老老实实记 FAIL ,不放宽门槛。
- 10 月 4 日凌晨,P5 动画:原版缓动轨迹冻结成回归用例(容差 5e-7 ),60Hz 作者时钟接入,主动作和待机差分动画跑通。
- 10 月 4 日上午,P6 物理内核:弹簧、弯曲、两粒子链条三个物理内核逐个逆向验证,弹簧单粒子一步只要 16.8 纳秒;胸部 (60,15) 的圆形限幅语义,靠数学观察加几何排除把错误候选一个个毙掉。
- 10 月 4 日白天,统一播放会话:动画和物理合并到同一个 60Hz 作者时钟驱动,30/60/144Hz 显示频率下参数逐帧一致。跳跃动作的物理误差从 0.00025 修到 0.0000038 ——为了定位这个舍入差,它读了 576 条不截断的 Float32 存储观察,最后确认是关键帧权重要先分别乘再相加。
- 10 月 4 日晚上,眨眼与差分:自动眨眼的随机数调度被整个逆向出来——Unix 秒做种子、xorshift 生成随机间隔,固定种子后 400 步逐帧一致。眼睛跨区间过渡、差分权重、淡出重播这些细碎语义也逐个对齐原版。期间还有一次漂亮的自我纠错:发现 PSB 字典里 blinkEnabled 和 eye enabled 共用一个存储地址,此前 17 组"关闭眨眼"的对照实验其实关掉的是整个 Eye 控制器——它没有将错就错,重构全部 54 组 fixture 逐一复核,更正了结论。
- 10 月 4 日深夜,播放器成型:nekomote_player 独立窗口跑起来了:视线跟随、触摸反应、拖动缩放、PNG 背景,接上 PulseAudio 用真实 PCM 的 RMS 驱动口型,800×1080 实机 CPU 单帧 P50 只要 0.267ms 。
- 10 月 5 日凌晨,精度收尾与全目录大审计:Float32 边界修正把一批历史遗留的失败像素逐个消灭;又写出独立审计工具,把 195 条型号全部实跑一遍——193 条导入、192 条编译、170 条全时间线通过,21931 条时间线里 19427 条 CPU 采样通过,每一条失败都留了具体原因。期间还出了个乌龙:测窗口生命周期时往系统注入键盘事件,把 Codex 自己的终端打得一团糟,我在外地远程发现后,它作废了那组记录,改成只调用应用自身回调的安全检查——这个教训后来直接写进了 AGENTS.md 。
到最后一个提交(10 月 5 日凌晨 2 点 29 分),这趟外包的最终账单:39 个提交、212 个文件、14.6 万行代码,测试入口从 23 项滚到 123 项——全部由它在那台 Ryzen 5800H + RTX 3060 的笔记本上,一天两夜干完。更难得的是账目干净:没通过的测试全部留档,冻结的阈值一分没松,阶段该标"进行中"就标"进行中",谁也别想糊弄验收——毕竟验收标准就是它自己起草的。
然后,不出意外地出意外了:ChatGPT 的额度用完了,然后我朋友忘记点重置卡重置,重置卡过期了。。。我算是半个急性子,有一些东西一旦开工,我是不想有任何拖延的,这下就轮到华为云无限 Token 的 CodeArts 来救场了。但是,GLM-5.2 和 ChatGPT 的性能差距还是相当大的,切换过去后,我感觉到了明显的阻力。
CodeArts GLM-5.2 艰难推进
换成 CodeArts GLM-5.2 后,给我最大的感受是自动化能力和代码能力有了明显的下降,特别是图形编程这一块,差距更大。而且有时候我还要时不时上去看一眼:是不是 GLM-5.2 又说工作已经完成,然后直接停止了,实际上运行测试还是啥也不是。但是项目我还是想推进的,为了让 ChatGPT 回归后能快速确定项目情况,我规定了 CodeArts GLM-5.2 的提交必须带上提交署名,来区分代码提交的记录。
后面就是艰难地推进:
- 10 月 5 日中午,接手第一战:親変形無視:GLM-5.2 的第一个提交就撞上硬骨头。全目录审计里有 22 个型号 CPU 求值直接失败,缺口最大的 15 个全卡在同一个东西上:親変形無視(无视父变形)节点。它跑到 FreeMote 的
MmoBuilder.cs里挖 inheritMask 的位映射,确认 bit 25 就是 inheritShape 位——这种节点相比正常节点恰好关掉了这个位,字面语义和位映射完美对上。按这个语义修完,15 个型号一次全过。随后两天又是连场突击:bm=19的追加パーツ节点报错,查明 bm 只是混合模式参数、和几何求值无关,白名单放行;嵌套 shirome 眼白遮罩报错,查明add_mask根本不是节点名而是 stencil 组合操作标记,之前是拿着操作符当节点名查表。三场下来,22 个语义失败修掉 20 个,剩下的要么纹理数据缺失要么素材本身就是坏的,不是代码的锅。 - 10 月 5 日下午,全目录大审计:194 个唯一型号全部实跑 120 步求值,192 个通过。对比 ChatGPT 走时 170 个型号全时间线通过,型号级通过率基本拉满。测试从 123 项滚到 127 项。
- 10 月 5 日下午,反应恢复:修错了再修:反应播放结束后角色不回待机状态的 bug 。第一次修复后 20 个反应全部正确回 idle ,测试全过,看着挺完美——结果转头发现修岔了:它提前停掉了本该自然播完 31 帧的"平常"时间线。翻原项目源码确认 E-mote 引擎的做法是让时间线自己播完自己停,二次修正才算真正对齐。一个 bug 修两轮,这就是和顶配模型的差距。
- 10 月 5 日傍晚,给 ChatGPT 攒求助信:接下来要碰 KDE Plasma 桌面插件了,这块 GLM-5.2 自己心里也没底,老老实实整理了一份 Plasma 壁纸插件调查问卷,准备 ChatGPT 回归后咨询。搞不定的先攒着问题而不是瞎逞强,这点倒是很懂事。
- 10 月 6 日上午,架构归位:背景渲染逻辑原本长在 player 里,其他宿主没法复用,抽到 application 层统一管理,接口、渐变、缓存边界一次理清。
- 10 月 6 日中午,player 产品化:加上资产目录模式,扫描
assets/自动列出全部角色和背景,Tab 切角色带 0.4 秒交叉淡化,B/N 切背景带 0.8 秒渐变,配置自动保存。播放器总算从一个诊断工具开始像个正经应用了。 - 10 月 6 日下午,fit 调了又调:一个"角色在窗口里怎么摆"的问题前后折腾了四五轮:先是拿顶点包围盒算适配,尾巴一伸出来就把角色缩成大头贴;改成用 cutoffY 腿部裁切位做底部基准;50px 下沉不对,改成贴窗口底边;缩放比例再微调。图形这块确实没有 Codex 一把准,但最后还是磨对了。
- 10 月 6 日傍晚,自绘 UI 和镜像模型:二次元咖啡厅风格的控制面板上线——白色半透明底、咖啡色文字、粉色描边、圆角 18px、ease_out_back 弹性滑入,fontconfig + stb_truetype 动态字符图集,没引任何 UI 框架,全部手绘。又补上了镜像模型支持:部分模型是水平翻转的,渲染翻转完触摸区域也得跟着翻,不然点左边反应到右边。
- 10 月 6 日深夜,P8 C ABI:桌面插件接入前最硬的一块。完整 C ABI 头文件:不透明句柄、错误码、非拥有视图,异常不许越过边界,31 个纯 C 测试覆盖到越界和空指针。然后用纯 C 写了个 abi_host 宿主做端到端验证,从只能加载渲染 300 帧,一路升级成完整壁纸验证平台:扫描 195 个模型、交叉淡化切角色、切背景、缩放、注视、触摸全流程跑通。
- 10 月 6 日深夜,音频三连修:abi_host 的音频链路连爆三个 bug ,一晚一个:先是工作线程抱着 mutex 调
pa_simple_write,PulseAudio 缓冲区一满主线程就跟着卡死,触摸直接把画面冻住;再是嘴型比声音超前一个缓冲区——写入位置不等于播放位置,得用 latency 折算出实际播放到哪了;最后 Tab 切角色整个程序卡死,根因是浅拷贝 AudioDevice 之后 memset 把活线程的 mutex 清了零。每个 bug 的根因分析倒是写得清清楚楚,就是这坑一个接一个地踩。
36 个小时,43 个提交,测试从 123 项滚到 128 项。论速度确实不如 Codex 一天两夜干穿 P2 到 P6 那么夸张,中途还把一个 bug 修反过一次;但账面是实打实的:22 个语义缺口修掉 20 个,全目录 192/194 型号跑通,P7 性能基线测完,P8 的 C ABI 从零铺到完整验证平台。最关键的是,每一笔账都端端正正署着名——ChatGPT 回归后翻开提交记录,这几天发生了什么一目了然。当初定署名制度,要的就是这个效果。
Gemini 3.8 Flash:该我救场了
后面的测试,发现部分椰子的立绘的手部拉伸存在严重画面问题,而且是会叠加拉伸导致手部严重畸形。识别错误并修复需要视觉能力,而 GLM-5.2 没有视觉能力,所以基本上无能为力。但是,我的好朋友借了他的 Google One AI Pro 账号给我,Antigravity 里面有 Gemini 3.8 Flash 可以用,虽然能力不算顶尖,但是至少也有识图能力,应该是能修复这个问题。另外,Gemini 3.8 Flash 因为单价低,所以非常耐用,于是我尝试把 Gemini 3.8 Flash 拉进了项目,让他修复手部变形的问题:
- 10 月 7 日上午,先给前任纠了个错:Gemini 进场后没有急着改代码,先把缺陷记录翻出来核对,结果第一条就发现旧账不对:known-defects.md 里记的 coconut-casual "93% 画面差异"根本不成立——是测试方法的问题:原生端自动加载了壁纸背景,WebGL 参照截的是透明通道,两边背景不一样,整图被误判成超差。同一透明受控条件下重测,单手叉腰的 coconut-casual 和原版 0 像素差异。真正有病的是另一批:coconut-maid 、coconut-maid-a 、coconut-maid-a-4yo 、coconut-santa 、coconut-wintermaid ——椰子一族的五个变体,共同点全是双手叠放在围裙前的站姿。
- 确诊:外星异形利爪:body_LR=30 让身体一转,病灶立刻现形。它的多模态视觉对比写得相当生动:原版 WebGL 里"双手温顺叠放在女仆围裙前,手指自然并拢";原生端同一姿态,右手四根手指被拉伸 2~3 倍,"化为粗细不均、尖锐外翘的外星异形利爪"。差异热力图显示超差完全集中在手部一小块区域,右手部件最大几何误差 158.91px 、超差像素 14044 个,其余全图 0 误差——病灶定位精确到像素。
- 根因:GLM 修了一半:这段代码 GLM-5.2 两天前刚碰过。親変形無視节点的 inheritShape 位,GLM 修复时阻断了 mesh_path 的父变形继承,五个型号的 CPU 求值从报错变通过;但同一个位掩码在另一条代码路径——贝塞尔变形回溯链
curve_parent——上压根没人检查。手部求值时沿着这条漏网的链一路回溯,把父级手臂/躯干的大旋转变形原样叠加了一遍,身体一转,手就被撕成怪爪。最气人的是数值回归全绿:求值不报错、不崩溃,P9 全目录审计里这五个型号也全算"通过"——这种几何叠加错误只有和原版画面对着看才能发现。没有眼睛,就是查不出来。 - 修复,顺手立了个法:对 inheritShape=0 的节点切断
curve_parent回溯、原点改走父级曲面映射,最大误差 158.91px 骤降到 8.87px ,降了 94.4% ,怪爪彻底消失,手部恢复自然叠放。补了单元测试,128 项全过,还输出了一份从视觉对比到层级骨骼架构逐层剖析的根因分析文档。最有意思的是它顺手干了件立法的活:把"提交必须带署名"从我的口头规定正式写进了AGENTS.md,GLM 时期那句自由发挥的 "CodeArts GLM-5.2 commit" 从此升级成标准的 Agent / Model 溯源字段——后面的多 Agent 协作,全靠这套制度记账。 - 顺手把配置 UI 重做了:手修完了,它接着把 player 的控制面板对着 NekoWebShow 网页版翻新了一遍:粉色描边磨砂面板、手风琴抽屉、8 大猫娘角色分类加服装变体中文精准解析,设置抽屉里帧率上限(∞/30/60/120)、人物锁定、声音开关、背景选择一应俱全。调优方式很"视觉系":先写工具把网页端 UI 截下来,闭合、展开、角色、设置 4 套视图和原生端逐一像素级比对,连 Noto Sans CJK 的 TTC 字型索引都对齐了。一小时后又追了一轮手感修复:拖拽时标题文字 1 帧脱节的滞后、关闭时停滞近半秒才瞬间隐去的迟滞,全部换成精确计时的 0.28 秒渐入 / 0.24 秒渐出。
两个多小时,三个提交,署名清一色的 Agent: Antigravity / Model: Gemini 3.8 Flash (High) 。论代码硬实力它确实不如前面两位,但这一仗恰恰说明:AI 团队不是比谁全能,而是谁擅长什么。几何和数值是 GLM 的舒适区,可画面到底对不对,得有眼睛的来。便宜、耐用、能看图——Gemini 3.8 Flash 在这个生态位上刚好补齐了最后一块拼图。至此,项目的三员大将算是凑齐了。
ChatGPT 回归,并成为工头
感谢 Tibo 发放的重置,我又有 ChatGPT 可以用的,但是,悲报:国庆最后一天重置。
因为我知道这下 ChatGPT 得省着用了,于是我计划让 ChatGPT 变成技术总监,让他给另外两个用量额度比较大的 Agent 派活,它只是负责验收,如果这两个 Agent 搞不定了,它就亲自出马。
具体组织方法是这样的:
- GLM-5.2 是主力搬砖工:无限 Token 可使劲造。批量资产和证据采集、构建工具、契约已经写清楚的实现、负例测试、ABI 错误码、格式和文档同步——一句话,凡是"需求明确、能不能过测试机器自动判定"的活全堆给它。但它有条红线:不许从"运行成功"推出"画面正确",没把握的公式和遮罩语义必须交出来复核。
- Gemini 3.8 Flash 是团队的眼睛:原生和 WebGL 并列截图对比、遮罩边缘、手部轮廓、UI 排版状态,产出可复现的视觉报告。所有需要"看"的活归它。红线同样明确:视觉改善不能放宽误差门槛,也不许看图猜公式。
- ChatGPT 6 Sol 是工头:求值语义推导、架构和线程生命周期审查、冻结门槛、最终验收。平时派活加验收,两个小弟都搞不定的才亲自出马。
分工文档里还有句很见功力的话:"资源额度决定调度优先级"——翻译一下就是:贵的省着用,便宜的可劲用,但谁也不许降低交付标准。
然后就让 GLM-5.2 和 Gemini 3.8 Flash 去干活了,其中故意给 GLM-5.2 分配尽可能多的任务——因为无限 Token
接下来,项目依然在推进,但是感觉没有特别突破性的进展,更多的是精细打磨:
- 10 月 7 日下午,工头上任先查账:ChatGPT 回归的第一个提交不是写代码,是把 GLM 和 Gemini 期间干的 44 个提交全部审了一遍。128/128 测试全绿——但工头不吃这套,自己动手重放冻结用例,当场抓出三个现行:Fraise 待机 400 步眼缘 165 个超差像素,根因是 GLM 那个"add_mask 是操作标记"的判断错了一半——Fraise 的眼睛层级里真有叫
add_mask的图层,跳过它就是遮罩缺失;Coconut 手部 Gemini 修完其实还剩 8.87px 几何误差、13111 个超差像素,"形状改善不能代替原素材还原";ABI 的非法枚举竟然返回成功。审查报告直接开出 R1-R6 问题单,随附一份带 G/V 编号的活儿清单贴在 workboard 上,一人一份,按单领活。 - 10 月 7 日晚上,开工:GLM 当天下午连吞 13 个提交,ABI 可观测失败、RAII、时钟契约、构建矩阵一路铺过去;Gemini 把
add_mask修回真实图层来源,顺手交了 UI 拖拽和 GPU 混合的视觉证据。 - 10 月 8 日,Plasma 地基:GLM 抽出共享 Qt Quick 桥、写 QML 壁纸模块、跑完 195 目录的触摸审计和图集 hash 审计;Gemini 啃镜像和遮罩的视觉对照;Codex 验证隔离 Qt Quick GPU 集成。三线并行,互不挡道。
- 10 月 9 日,视觉大扫尾与公式接管:Gemini 一口气交了 V12 到 V19 一串视觉审计;手部继承那条 8.87px 的公式 Codex 接管推导——眼睛发现问题,脑子闭合语义,各干各的。
- 10 月 10 日,我自己也下场了:看着三位干得热闹,我手痒亲自提交了一把 plasma 壁纸应用的构建测试——结论:存在大量问题,只能显示角色()。同一天 Codex 把 Plasma 迁移到高层 C ABI,修掉了切换角色卡住主循环的冻结,部署也做成了带 RPATH 的可移植包。
- 10 月 11 日,桌面真有了:Plasma 黑屏修复、共享壁纸控制面板恢复;然后是 Vulkan 后端——从零写、当天推翻重建、ABI 接入、负例测试,一天四个提交拉完。当天工头在文档里记下"用户已确认真实桌面初步接入正常"——路线图里程碑 M4,一个真实桌面上的原生动态壁纸,达成。
- 10 月 12 日,双后端与内存:Plasma 的 GL/Vulkan 双后端选择加基线 CI 包出炉;模型加载峰值内存砍了一刀。
- 10 月 13 日,打磨日:纹理裁切省显存、帧拓扑复用省 CPU、GLFW 自动选择 Wayland/X11 双平台、包重命名统一部署。我自己也删了一波过时的早期文档。
- 10 月 14 日,合成语义:用程序生成的模型补齐离散参数和嵌套 shape 排除的语义验证,不用真实素材也能回归。
- 10 月 15 日,CI 与分发:GitHub Actions 拆成三个独立工作流——Ubuntu20 本体、Plasma5、Plasma6 各管各的;release 流水线在
vX.Y.Z标签下自动汇总五份包发布;layer-shell 独立壳也顺手交付。我拉下 CI 产物实际装了一遍:本体、KDE5、KDE6 都正常,遂授权自动发布。 - 10 月 16 日,国际化:GLM 给壁纸应用层加上英/简中/繁中/日四语种 UI、独立的背景选择抽屉、首次启动默认背景。
- 10 月 17 日,v0.5.1:五份包加 sha256 校验,CI bot 自动发布。从 10 月 3 日仓库里只有四份文档算起,两周,项目从想法变成了挂在 GitHub 上的 v0.5.1。
这十天的账本:125 个提交,GLM 60 个、Codex 40 个、Gemini 14 个。工头嘴上说"只负责验收",身体倒是很诚实,Vulkan 后端、Wayland 兼容、纹理裁切全是它亲自撸的——该出手时就出手,这就是技术总监的自我修养。回头看确实没有什么"突破性进展",核心引擎早在上周就打完了;但从"一个能跑的引擎"到"每天挂在我桌面上的壁纸",中间隔着的全是这种活:修黑屏、抠显存、对像素、建 CI。产品化没有魔法,只有打磨。
至此,项目的开发也就告一段落了。为什么版本号定在了 v0.5.x 呢?因为还需要适配其他桌面环境,但是我现在确实是暂时不想再动了,目前成功适配了 KDE5 和 KDE6,给个 v0.5.x 的版本号,应该是很中肯的,后续基本上就是桌面环境的适配工作了,以及修复潜在的BUG,小幅改进。
效果展示
目前对于桌面背景的适配,已经实现了 KDE5 和 KDE6 的适配,直接安装为桌面背景插件即可使用,实际使用效果如下所示:
菜单面板可以隐藏,控制图标和菜单面板都可以进行拖动。另外,其实还利用了游戏的背景CG图组合,配置了动态壁纸,根据时间展示不同的壁纸。
安装教程
项目提供了预构建的 Release 包,不需要自己编译,全程也就四步:下载插件包 → 运行安装脚本 → 下载资产包 → 桌面里选壁纸。下面以 KDE Plasma 为例。
第一步:下载对应的插件包
去 GitHub Releases 下载对应桌面版本的包。以 KDE Plasma 6 为例,x86_64 机器选 nekomote-plasma6-x86_64.tar.gz ;还在用 Plasma 5 的老系统选 nekomote-plasma5-x86_64.tar.gz ;ARM 设备选对应的 aarch64 包。每个包旁边都附了 .sha256 校验文件,建议顺手验一下。注意插件包不带 Qt/KDE/glibc——它直接用你系统里现成的,所以要求宿主 Qt 版本不低于构建基线(Plasma 6 包基于 Qt 6.4.2,Plasma 5 包基于 Qt 5.12.8)。
第二步:解压并运行安装脚本
tar -xzf nekomote-plasma6-x86_64.tar.gz
cd nekomote-plasma
python3 tools/plasma_distribution.py check-host stage
python3 tools/plasma_deploy.py install --stage stagecheck-host 会先检查你机器的 Qt/Plasma 版本能不能用这个包,不兼容会直接告诉你,省得装完黑屏一头雾水。install 负责安装:全部装进用户目录 ~/.local/share/nekomote/ ,不碰任何系统路径和桌面配置,还会自动写入 QML_IMPORT_PATH 环境变量、刷新 KPackage 缓存,并且给每个文件记录 sha256——没错,连卸载脚本都是 AI 写的,uninstall / verify / status 一应俱全,还给我做了个全文件校验的部署器。
默认要注销重新登录才生效;嫌麻烦可以加 --restart-shell 参数,装完自动重启 plasmashell 立即可用。
第三步:下载对应版本的资产包
插件只是引擎,角色和背景在另一个仓库:NekoMoteAssets 。注意资产包也是按版本发布的,要和插件包的版本对上——插件下的 v0.5.1,资产就下 v0.5.1,别一个 v0.5.0 一个 v0.5.1 混着用。这个仓库的 Release 没有挂二进制附件,分发的是 GitHub 自动生成的源码打包:进它的 Release 页面,选好对应版本,拉到页面底部下载 Source code (zip) 或 (tar.gz),两种格式内容一样。
解压后里面有 8 个角色组、全部型号变体,还有静态背景和按时间切换的动态背景(白天/黄昏/夜晚三相,用的游戏 CG)。解包出来就是引擎格式,不用再跑什么导入工具。
第四步:选择壁纸
桌面右键 → 配置壁纸 → 壁纸类型选择 NekoMote → 在配置项里把 assets 目录指向你刚解压的资产包里的 assets 文件夹。完事,猫娘上桌面了。
之后的日常操作全在桌面上的 UI 面板里:右上角猫爪图标打开面板,切换角色、选背景、调语言(英/简中/繁中/日)、静音、锁人物位置,都是点一下的事。顺带一提,同一套资产也可以直接喂给 Release 里的独立播放器 nekomote_player,不带桌面插件单开窗口也能跑——比如你想先看看效果再设置到桌面,这就很方便。
最后
当我真正完成作品的那一刻,我感觉到的不是喜悦,而是“震惊瘫坐”——一个人,只有 Python 编程基础,了解一些计算机编程相关的知识,但是对实际代码 C++ 一窍不通,靠 AI,单枪匹马居然能做出来这样的 C++ 项目。这放在以前那可是想都不敢想。
我后面也让一个独立的 CodeArts GLM-5.3 Agent 按照业内常见的价格,估算了这个项目如果是放在 2022 年之前,AI 没有这么厉害,走传统开发,要多少资金。
Agent 翻了翻仓库的 git 历史和各阶段报告,先盘了盘家底(v0.5.1,共 212 次提交,10 月 3 日至 10 月 17 日):
- 引擎源码:
src/下 62 个 C++20 文件、约 1.9 万行——E-mote 语义的参数求值、网格变形、双三次 Bézier 曲面、遮罩合成、弹簧物理、时间线动画、差分混合,OpenGL / Vulkan 双渲染后端,外加四语种 UI; - 桌面集成:C ABI 高层接口、独立播放器
nekomote_player、KDE Plasma 5 / 6 壁纸插件、Wayland layer-shell 独立壳、音频接入; - 测试:244 个测试用例、约 1.5 万行测试代码,另有约 7.6 万行程序生成的参考对照数据(拿原版网页的输出当标准答案逐帧比对——传统开发里这套参照体系得 QA 人肉搭);
- 工具链:约 1 万行 Python(导入器、部署器、分发工具),4 条 GitHub Actions 工作流、跨三个发行版的构建矩阵、自动发布五份安装包;
- 文档:
AGENTS.md、ROADMAP.md加各阶段报告,合计约 3.3 万行。
然后它用业内常用的自下而上估算法,把项目拆成模块逐个估算人月:
| 模块 | 传统开发要干的活 | 估算人月 |
|---|---|---|
| E-mote 语义逆向 | 闭源商业中间件的行为分析、参照比对、语义验证 | 5 – 7 |
| 资产管线 | E-mote JSON 导入、规范化 schema、纹理图集处理 | 3 – 4 |
| 运行时核心 | 参数求值、网格变形、遮罩、物理、时间线、差分混合 | 10 – 14 |
| 渲染后端 | OpenGL 和 Vulkan 两套完整实现 | 6 – 9 |
| 应用层与 UI | 会话管理、多模型切换渐变、配置、四语种控制面板 | 5 – 7 |
| 桌面集成 | C ABI、播放器、Plasma 5/6 插件、layer-shell、音频 | 5 – 7 |
| 测试与 CI | 244 个用例、参照体系、三发行版矩阵、发布管线 | 6 – 8 |
| 文档与项目管理 | 开发规范、路线图、阶段报告、验收记录 | 2 – 3 |
| 合计 | 42 – 59 人月 |
它还拿 COCOMO II 模型做了交叉验证:按剔除参考数据后约 4 万行手写代码量算,工作量在 130 人月以上——这个模型默认把沟通、返工、管理开销全算进去,历来偏保守。两个口径综合,报告的结论是:核心执行约 50 人月,含完整项目管理口径约 80 人月。
再按 2022 年之前的行情折成钱:
| 开发模式 | 团队配置 | 工期 | 资金估算 |
|---|---|---|---|
| 国内自建小团队 | 1 名资深图形工程师 + 2 名 C++ + 1 名测试 | 约 12 – 14 个月 | 250 – 350 万元 |
| 国内外包 | 外包公司项目组(图形人才稀缺,人月价 7 – 9 万) | 约 12 – 15 个月 | 400 – 500 万元 |
| 欧美外包 | 同等配置(约 $2 万/人月) | 约 12 – 15 个月 | 600 – 900 万元 |
| AI 协作开发(实际) | 1 人 + ChatGPT Plus + CodeArts + Google AI Pro | 15 天 | $40 约 270 元 |
估算假设也列得明明白白:默认团队有图形引擎开发经验、不含 NEKOPARA 素材授权、不含 v0.5.x 之后其他桌面的适配。而且这还是"能找到人接活"的理想情况——闭源格式逆向这种活,大部分外包公司压根不接,接了也大概率因为做不出像素级还原而烂尾。
看着这份数字我沉默了半天。传统软件开发的账本来就是这么算的:约 50 个人月的活,一个人 15 天干完了。而这 270 块钱还只是两份订阅的月费——GLM 的 Token 走华为云 CodeArts,一分钱没花,开头那句"华为云恩情还不完"真不是白说的。时间效率 30 倍起步,资金效率直接上万倍——这已经不是降本增效了,这是降维打击!
希望你使用 NekoMote 用得开心——这可是价值约 400 - 500 万市场报价的 Linux 桌面动态壁纸插件(误)。