在互联网上,我有一块 48 米见方的地。地上有一栋两层的房子,北边有一条马路,门口一条石子路穿过草坪通到正门,院子里有四片花坛和七棵树。它挂在 house.wtfareudoing.com,跑在我桌上那台树莓派上,任何人任何时候都可以走进去逛——现在是上海时间几点,房子里就是几点;上海在下雨,院子里的石子路就是湿的。

这个项目叫「我的一块地」。想法很简单:游戏里的家园系统我玩过不少,但它们都住在别人的服务器里,游戏凉了房子就没了。我想要一栋长期存在的数字房子——自己的域名、自己的硬件、自己的数据,可以慢慢装修,慢慢添东西,十年后还在。

两天,31 个功能块

这栋房子从空地到现在的样子只用了两天,但不是"生成一栋房子"那种两天。它是 31 个功能块一块块垒起来的,每一块都有文档、有测试、有验收记录:

技术栈刻意保守:前端 three.js 直用(审计后决定不加 R3F),整栋房子是程序化建模+实例化批渲染;后端是不到 500 行的纯 Python 标准库 HTTP 服务,零 pip 依赖,跑在 systemd 的重沙箱里,内存限制 180MB——树莓派上一个 Docker 都没用。

一个值得记下来的 bug

上线当晚我在真机上验收,发现两个问题:夜里灯太暗,以及"地板上有很多白色的横条,二楼特别多"。

横条这个问题修了三轮。第一轮以为是窗台太宽,把它从 18cm 收窄到 6cm;第二轮以为是颜色太浅,把踢脚线窗台整体加深了 42%——都没用,横条还在。第三轮不猜了,写了个脚本把场景里每一条踢脚线的包围盒和每一面墙逐一对照,要求"每条踢脚线 90% 以上长度必须贴着某面墙"。一跑,二楼几十条全部脱墙:6 米长的东西向踢脚线横穿在房间正中央,窗台戳出墙外 2 米。

根因特别典型:生成踢脚线和生成墙脚阴影的代码共用了同一个可复用的旋转四元数,而阴影代码会就地改写它。一楼先生成,四元数还是单位值,一切正常;一楼的阴影跑完,四元数停在 90° 旋转上——二楼整批收口件就带着这个残留旋转落了位。修复本身只有三行,但那个"逐实例对照"的脚本留下来变成了回归测试:以后任何人再让踢脚线离开墙面,测试会直接报出是哪一条。

现在的状态

房子公开版本还是 revision 0——一栋带真实昼夜的空房子。装修工作台、三套样板间模板、真实的 CC0 家具模型(沙发和电竞椅已经接进来了)都已就绪,就差我登录进去摆第一套家具、按下"发布"。

等第一版装修上线,你走进去看到的就不再是空房子了。这块地会一直在这里慢慢长,就像这个站上其他项目一样。