Smallville 是一个服务端权威的 2D 共享小镇原型。居民由规则快层与 LLM 慢层共同驱动,即使玩家离线也会继续生活;玩家主要观察自己的居民,并通过私密消息间接影响其决定。
- 浏览器通过 WebSocket v2 完成访客会话握手。
- 新访客只看到三步全屏创建流程;已有居民的访客直接恢复游戏。
- 新居民统一在小镇车站门口出生,自主选择空房、逐格前往住所并在移动演出完成后入住。
- 客户端只加载和渲染本人所在场景及同场景居民,相机默认跟随本人。
- 玩家可以拖动镜头、点击“回到我”、查看本人详情,或给自己的居民留言并收到回复。
访客 token 保存在浏览器的 smallville.visitorToken.v1,SQLite 只保存 SHA-256 哈希。当前版本没有用户名密码、跨设备恢复、删除角色、手动移动或搬家功能。
client(Phaser + DOM UI) server(Node + TypeScript)
┌──────────────────────┐ WebSocket ┌─────────────────────────┐
│ 通用 WorldScene │◄───────────►│ v2 会话与场景订阅 │
│ 按需 Tiled 场景加载 │ snapshot / │ Simulation 持续世界 │
│ StateStore 场景增量 │ delta │ AgentRuntime 自主居民 │
│ 创建/HUD/详情/消息 UI │ guidance │ NpcDirector / Housing │
└──────────────────────┘ │ SQLite Store / LlmClient │
└─────────────────────────┘
shared/:公共类型、WebSocket v2 协议和 Tiled 数据契约。server/src/sim/:时钟、需求、碰撞、寻路、任意 portal 场景图与移动。server/src/agent/:居民的日程、记忆、重规划与消息回复。server/src/app/:会话、外观、住房和模块适配层。server/src/db/:SQLite 持久化与PRAGMA user_version迁移。client/src/scenes/WorldScene.ts:渲染任意场景的唯一 Phaser Scene。client/src/ui/:桌面抽屉、移动端全屏面板与创建流程。
npm install
npm run dev打开 http://localhost:5173。服务端默认监听 8765,Vite 默认监听 5173。
如果根目录没有 config.json,服务端使用 config.example.json 并强制启用确定性 mock LLM。要接真实 OpenAI 兼容接口,复制配置文件、关闭 mock,再设置配置指定的 API key 环境变量。
场景清单位于 client/public/assets/maps/manifest.json:
{
"version": 2,
"defaultSceneId": "town",
"arrivalPoi": "station_entrance",
"temporaryHomePoi": "station_entrance",
"scenes": [
{ "id": "town", "name": "小镇", "kind": "public", "file": "town.json" }
]
}每张地图必须包含 ground、collision、poi,可以包含 objects 与 foreground。支持多 tileset、内嵌 tileset和外部 TSX;tile 像素尺寸读取地图自身的 tilewidth/tileheight。
Portal 使用标准 Tiled properties:
targetScene:目标场景 ID。targetPoi:目标场景中的落点 POI。
迁移期仍兼容 targetMap 和旧 objects 碰撞层。住宅 POI 的类型为 residence,使用 unitId、label、tags、capacity properties;第一版容量必须为 1。
npm run validate:scenes该只读命令会检查清单、文件、图层尺寸、POI/住宅唯一性、portal 引用及往返可达性、tileset 与图片资源。
占位地图由 node client/scripts/gen-maps.mjs 生成。目前有 7 个独立场景、48 个 POI 和 12 套测试住宅,后续可直接替换为正式 Tiled 美术包。
客户端消息:hello、createCharacter、sendGuidance、requestSceneSnapshot。
服务端消息:session、characterCreated、sceneSnapshot、sceneDelta、guidanceAck、guidanceDelivered、error。
sceneSnapshot 与 sceneDelta 均携带 sceneId。服务端只推送玩家本人当前场景的数据,客户端会丢弃上一场景迟到的增量。消息目标不由客户端提交,服务端从会话绑定的角色推导。
默认数据库为 data/smallville.db。v2 新增:
players:访客 token 哈希与唯一角色绑定。housing_assignments:住宅预订和入住状态。messages:玩家与本人居民的双向消息。agents.appearance/agents.housing_status:可扩展外观 token 与住房阶段。
启动时自动从旧结构迁移并保留原有 NPC、居民、记忆、日程和世界时间。已有 NPC 会登记为其住宅场景中的已入住住户。
npm test
npm run smoke
npm run validate:scenes
npx tsc --noEmit -p shared
npx tsc --noEmit -p server
npx tsc --noEmit -p client
npm run build自动化覆盖旧库迁移、token 哈希、角色唯一绑定、外观重启稳定、消息历史、非星型跨场景路线、迟到 delta、住房选择/并发占用/无房等待、NPC 作息和完整游戏日。UI 已在 1440×900 与 390×844 下完成首次创建、刷新恢复、消息回复、相机拖动/回中和安全区布局检查。