一个不完美架构的三重身份
AstroTown 的代码库里同时住着三个不同的项目,这是一个被严重低估的复杂度。
第一重身份:AI 小游戏聚合展示平台。 这是面向玩家的那一面——游戏库、卡片网格、播放页。逻辑简单,数据量小,静态 HTML 足以支撑。
第二重身份:XMP 生态的展示窗口。 XMP(XMPlay Protocol)是一套让 AI 生成的小游戏能够跨平台播放、注入参数、与宿主页面双向通信的协议规范。AstroTown 是这套协议的甲方实现,是给第三方开发者看的参考示例。
第三重身份:创作者经济平台的雏形。 GameJam、收益分成、创作者等级——这些商业化承诺都写在代码和数据结构里,虽然一项都没有接通。
这三种身份叠加在一起,让这个静态展示站的工程复杂度远超表面。
为什么是静态 MPA,而不是 SPA
技术选型是审计报告里被质疑最多的点之一。技术选型是审计报告里被质疑最多的点之一。审计员的标准是:游戏库规模增长到 100+ 款时,现有架构将面临可维护性瓶颈。
这个判断是对的。
但它忽略了一个前提:AstroTown 目前只有 21 款游戏。
静态 MPA 在 21 款游戏的规模下,有三个无可替代的优势:
冷启动速度接近零。 没有任何构建步骤,没有任何运行时依赖,一个 git push 直接上线。对一个资源有限的初创项目来说,这个运维复杂度几乎为零。
天然 SSR 友好。 每个 HTML 文件都是服务端渲染好的,爬虫看到的和用户看到的一致。不需要额外的 SEO 配置,sitemap 手动维护即可。
故障域隔离。 一个页面崩溃不会影响另一个。ATPlayer 播放器在某个游戏上出错,首页依然完好。
但审计报告也诚实地点出了天花板:当游戏数量到 50+ 时,全局状态管理、动态路由和增量数据同步会成为真实的工程负担。这不是技术选型错误,而是技术选型和业务阶段的不匹配。
XSP v2 Bridge 协议:整个项目里最硬的部分
如果要给 AstroTown 找一个不可替代的技术壁垒,答案不在 CSS 动画或游戏库筛选逻辑,而在 bridge.js——XSP v2 Bridge 协议的实现。
协议的核心逻辑:
宿主页面(ATPlayer) ←→ bridge.js ←→ 游戏 iframe
游戏本身是一段纯 HTML+JS+CSS 的小游戏,运行在 iframe 里。宿主页面需要向游戏注入参数(难度、音量、玩法变体),游戏需要在游戏结束时通知宿主页面(触发评分弹窗、推荐下一款、更新播放量)。
这个双向通信通过 Bridge 完成,时序设计得相当严密:
activate(宿主就绪)→ _resolveParams(解析参数)→ iframe.load(游戏加载)
→ _injectParams(参数注入)→ bridge.js 建立连接 → __XMP_READY__(游戏就绪)
审计报告对这个时序的评价是设计合理,状态机明确,这是工程师对工程质量的最高赞美。
但有一个值得注意的漏洞:
rainy-night-letters-v2 和 echoes-of-the-atelier 等 xmp-advanced 格式游戏的参数源有两套——xmplay-library.json 里的 params 数组为空,但游戏目录下各自有 params/schema.json。两套参数来源之间没有同步机制,播放器注入的可能不是游戏实际需要的参数。这需要在实际接入了游戏内容后重点验证。
CSS 设计令牌体系:整个项目里最成熟的部分
如果 Bridge 是最硬的部分,那 tokens.css 就是整个项目里完成度最高的工程资产。
设计令牌(Design Tokens)这个词在大型团队里常见,但在独立项目中很少看到有人认真做。AstroTown 做到了:
:root {
--color-primary: #6366f1; /* Indigo */
--color-secondary: #8b5cf6; /* Violet */
--color-bg: #0a0a1a; /* Deep space */
--space-unit: 4px;
--radius-sm: 6px;
--radius-md: 12px;
--radius-lg: 20px;
}
这套令牌体系不只是变量声明——它是整个产品线的视觉宪法。只要所有页面都引用 tokens.css,设计师和开发者就永远在一个一致的色彩和间距系统里工作。
审计报告特别提到两个问题值得重视:
第一:骨架屏覆盖率不完整。 游戏卡片区域在数据加载时存在布局跳动(CLS),这会直接影响 Google 的 Core Web Vitals 评分,进而影响搜索排名。骨架屏的实现在 base.css 里已经有了,但只覆盖了部分组件,需要查漏。
第二:星空 Canvas 背景(starfield.js)持续渲染,没有可见性检测。 当用户在游戏播放页时,星空动画依然在后台运行,浪费 GPU。这只需要加一个 IntersectionObserver 或者监听 document.hidden 状态就能解决。
Supabase 后端:设计完整,接入为零
init_db.sql 是整个 _DOC 目录里最被低估的文件。它的设计质量远超项目整体平均水平——GIN 索引、Row Level Security、触发器自动维护、RLS 策略分离,这些是生产级数据库才会认真考虑的东西。
但现实是:所有后端功能都只是设计完成,接入待定。
xmplay-library.json → games 数据来源(本地 JSON)
Supabase → 从未真实连接
游戏播放量 → 全部显示 0
用户评分 → 全部显示 0
用户认证 → 按钮 UI 存在,OAuth 未接通
这个状态是创业项目最常见的设计过度陷阱——把数据库结构设计得很完整,但没资源去做实际的接入。更务实的做法是先用 JSON 文件跑通核心路径,等后端资源到位再切换,而不是设计完 RLS 再等着。
资产缓存策略:一个 P0 级工程的致命错误
审计报告里最严重的问题不是后端未接入,而是这个:
# _headers 文件
Cache-Control: public, max-age=31536000, immutable
这个声明的意思是:CSS 和 JS 文件缓存一年,且永不过期(immutable)。浏览器的 immutable 缓存意味着:即使 HTML 更新了引用了新版本,旧的缓存文件也不会被更新。
这是现代前端的标准做法,前提是文件名包含内容哈希:tokens.a3f2b1.css。
而 AstroTown 当前的 CSS/JS 文件名是纯静态的:tokens.css、player.js。这意味着每次发布新版本,所有已经缓存了旧文件的用户将在整整一年内看到破碎的页面。
这不只是一个性能问题,这是一个生产事故。
评分 62 分,到底意味着什么
审计报告给了 AstroTown 62 分,综合基线是 80 分。
这个 18 分的差距,主要来自三个结构性缺失:
数据层(后端未接入):-30分 所有用户行为数据为零,评分系统形同虚设,收藏功能无法使用。这是平台属性的根本性缺陷。
内容层(游戏品类失衡):-25分 21 款游戏里叙事类占比约 85%,平台的内容多样性严重不足,玩家没有理由把 AstroTown 当成游戏发现的入口。
商业化(所有机制停留在概念):-20分 80% 分成、区块链可查——这些承诺没有一行代码支撑,招募创作者时会造成严重的信任危机。
剩下 57 分,是 AstroTown 真正做对了的部分:
- XSP v2 Bridge 协议设计扎实,播放参数时序逻辑严密
- CSS 设计令牌体系完整,维护良好
- Logger 系统成熟,事件分类清晰,有本地缓冲和批量上报
- 数据库设计具备生产级意识,RLS 策略分离清晰
- 文档体系在
_DOC/里完整保存了研发过程
62 分不是一个失败。这是一个技术愿景清晰、但工程资源严重不足的项目的真实写照。
写在最后
AstroTown 是一个设计过度、接入不足的典型案例——把架构想得很清楚,把数据库设计得很完整,但当这些设计不能转化为用户可感知的价值时,它们就只是代码仓库里的资产损耗。
但反过来说:能在 21 款游戏、零后端接入的阶段就设计好 RLS 策略、触发器、事件日志和内容分级体系,这个项目的技术判断力不差。
它需要的不是更好的架构,是更快的接入速度——先把 Supabase 接通,让游戏数据真实流动起来,再谈下一步。
技术架构系列文章 · 第一篇。下一期:《AstroTown 升级路线图:从 62 分到 80 分的优先级博弈》