一句话能生成一个能玩的农场游戏吗?Spawn Point 这个项目给出的答案是:能,但过程里踩的坑比想象中多。它把一句话变成可玩的 Godot 4 游戏,小模型负责把游戏设计写成 JSON,剩下的全交给普通 Python 和经过测试的 Godot 组件。
![]()
作者这个月把生成器对准了一个品类,想把它做好:温馨农场。输入一句“冬天的农场,种卷心菜,有只狐狸”,就能得到对应的场景。画面里没有任何图片文件,每一块地砖、每棵树、每只鸡和每棵卷心菜,都是 Python 在构建时画出来的。
地面是一整张图,不是一块块拼的
作者最初的想法是做一套带自动拼接规则的图块集。实际做法是:整张地图的地面被画成一整张图。关卡是一个字符网格,点代表草地、冒号代表小路、波浪号代表水。每种地形先变成像素掩码,放大 16 倍再模糊,然后用带一点噪声的阈值处理。这一步就免费换来了圆角和手绘感的毛边。
轮廓线就是“掩码外、但挨着掩码的像素”,用更深的颜色画。悬崖的定义是“陆地下方 6 像素内的水像素”,岛屿南侧会自动带上棕色悬崖。草丛、花、睡莲和芦苇按格子用带种子的随机数撒上去,所以同一个农场每次看起来都一样。同一套代码换一张颜色表和树列表,就能画出四季。
这里出过问题:模糊和距离变换用了 scipy.ndimage,在作者机器上正常,到了 CI 就失败,因为 scipy 从来不是依赖项。改用 numpy 重写后,numpy 的腐蚀给地图加了一圈细细的亮边,原因是它把“图片外面”当成了陆地。修法是用边缘模式做填充。
走到树后面,需要两个小引擎特性
俯视角农场本来很平,直到农夫能走到树后面。这需要两件事:一是 Y 轴排序,屏幕上位置更靠下的实体画在前面;二是脚印碰撞,每个物体以画面底部为立足点,只有脚下一小块盒子参与碰撞。碰撞以前是按整张精灵图描出来的,结果树冠会把路挡住。这两项最后都变成了游戏图里的一行选项。
做成一个季节,而不是一个关卡
农场变成了由几天组成的一个季节:早上 6 点到晚上 10 点,傍晚是金色光,夜里变暗。你在农舍的床上睡觉(或者在田里倒下),过夜后浇过水的作物会长大。有些日子下雨,所有作物都保持湿润;冬天的农场则下雪。种子要花钱,动物得先喂饱才会下蛋或产奶,工作台出售工具升级。
农场还会把自己存到 user://(浏览器里是 IndexedDB):第几天、多少钱、每块地、动物、砍过哪些树。关掉标签页再回来,接着玩。这里有两个细节各花了一个 bug:GIF 录制器和试玩机器人绝不能碰存档,否则下一次录制会从上一个机器人离开的地方开始;R 键(重开)必须清掉存档,否则“重开”只是重新加载同一天。
让农夫倒着走的 bug
录完演示 GIF 后,有人指出农夫在走太空步:向左走,脸却朝右。精灵翻转本身没问题。是 GIF 自动驾驶把每个玩家的朝向设成了“最近的敌人”,这在射击游戏里是对的。在农场里,最近的敌人是一只乌鸦,于是农夫一边走开一边盯着乌鸦。拿剑的农夫在实际游玩里也有同样的 bug,因为剑的朝向跟着鼠标走。修法只有两行:农夫永远面朝自己走的方向。
模型一直忽略那只狐狸
模型把“有吃庄稼的乌鸦的农场”做对了,却漏掉顺带提到的害虫:“有只狐狸”“旁边有只浣熊”。作者在训练之前就写好了一组封存的 16 条提示词,发布版模型答对了 12 条。
第一个训练补丁修好了狐狸,然后开始给和平农场塞害虫,还开始忽略有名字的农夫(“一只猫农夫”变回了“农夫”)。原因在合成数据里:每个新样本都用默认农夫,而且几乎都带害虫,模型就精确地学到了这一点。
第二个补丁用了一半有名字的农夫,加入更多明确的“无害虫/和平”农场,并增加对上一个补丁的回放。发布之后,“养鸡和钓鱼”有一次把鱼当成了害虫返回,于是归一化器现在会把农场动物和鱼从农场的害虫列表里剔除。有些修复属于代码,不属于权重。
没有手机,也能测手机
作者用手机尺寸的无头 Chrome 检查触控。第一版脚本向屏幕按钮派发合成的 PointerEvent,什么也没发生。游戏本身没问题:触控代码调用了 setPointerCapture(),而浏览器从没见过的指针 id 会抛异常。通过 DevTools 协议注入真实输入就正常了:摇杆把农夫走到门口,ACT 键让他进了屋。手机测试确实发现了一个真问题:种子按钮挡住了屏幕中间。现在种子改成点快捷栏来选。
想试的话,可以安装 spawnpoint-studio,启动本地模型服务(需要 12 GB 的 NVIDIA 显卡加 Docker,或者用 Ollama),然后输入一句“一个温馨的秋天农场,有南瓜,小心乌鸦”。演示农场也能在浏览器里玩,手机同样支持。
作者最后留了一个问题:如果你程序化生成过美术,是什么技巧让它不再看起来像生成的?对他自己来说,答案是模糊一张掩码,再用噪声做阈值。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.