用 Go 写了一个纯文本网页游戏

最近用 Go 写了一个纯文字网页游戏,部署在一台 2GB 内存的小服务器上。整个过程从写代码到上线不到一周,想记录一下这个体验。

技术选型

后端用 Go 标准库的 net/http,数据库用 SQLite(开了 WAL 模式),前端是手写的 HTML/CSS/JS,没有用任何前端框架。整个项目编译成一个 14MB 的二进制文件,scp 扔到服务器上就跑起来了。

选了纯 Go 实现的 SQLite 驱动(modernc.org/sqlite),这样连 CGO 都不需要,交叉编译到 Linux 一行命令搞定。gorilla/websocket 处理实时通信,几十个长连接跑在 goroutine 上毫无压力。

内存控制

2GB 内存跑 Nginx、VPN、qBittorrent 再加这个游戏,必须省着用。设了 GOMEMLIMIT=1.5GiB 做软上限,GC 在接近阈值时主动回收。实际跑下来,游戏进程只占 3MB 左右——Go 的零值初始化和栈分配在这里体现得淋漓尽致。

数据库

SQLite 在单连接 + WAL 模式下,读写并发完全够用。所有游戏计时都用时间戳差值计算,不依赖后台定时器——玩家上线时一次性结算离线收益。42 张表,30 多个 API 端点,单连接扛几十个玩家同时种菜聊天对战,SQLite 完全没有成为瓶颈。

一些取舍

没有用 React/Vue。前端是 Alpine.js 加手写 CSS,响应式同时适配桌面和手机。没有构建工具,静态文件直接扔给 Go 的 embed 或者 Nginx 直接 serve。

最大的体会是:对于小体量的项目,"够用"比"最优"重要得多。SQLite 够用就不上 PostgreSQL,gorilla/websocket 够用就不上 gRPC,手写 CSS 够用就不上 Tailwind。每一层技术选择省下来的复杂度,最终都变成了更快的开发速度和更少的维护负担。

纯文字交互的网页游戏,在 2026 年看起来像个古董。但写完之后发现——慢下来,确实是另一种乐趣。