Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a0730b4
test(23-01): council types, constants, lore + failing registry tests
moyunzero Jun 25, 2026
afaad9d
feat(23-01): LOCKED dossiers npc-1..3 + registry index
moyunzero Jun 25, 2026
7238be2
feat(23-01): persona prompt formatter + registry display names
moyunzero Jun 25, 2026
8679301
feat(23-02): add LOCKED council dossiers npc-4..8
moyunzero Jun 25, 2026
97b405c
feat(23-02): complete COUNCIL_PERSONAS registry npc-9..12
moyunzero Jun 25, 2026
cb005a6
test(23-02): full registry validation + voting split gates
moyunzero Jun 25, 2026
faa1d41
feat(23-03): registry-derived personalitySeed for 12 council seats
moyunzero Jun 25, 2026
2118961
feat(23-03): sync Python NPC_PERSONALITY_SEED to 12 registry values
moyunzero Jun 25, 2026
32b62a7
test(23-03): cross-layer collective seed parity for 12 seats
moyunzero Jun 25, 2026
87c5d91
feat(23-04): async idempotent __council__ LTM seed on room create
moyunzero Jun 25, 2026
0eb3699
feat(23-04): council memory isolation + worker fetch stub
moyunzero Jun 25, 2026
15fd48c
docs(23-04): add C-07 council memory scope draft to CONTRACTS
moyunzero Jun 25, 2026
c002f1d
test(23-05): add persona prompt length and gating tests
moyunzero Jun 25, 2026
5ec3208
feat(23-05): implement build_persona_block for council trio
moyunzero Jun 25, 2026
36aa3c0
feat(23-06): widen schema and rewrite npc-1..3 schedules
moyunzero Jun 25, 2026
aa36ed8
feat(23-06): add npc-4..12 council schedule placeholders
moyunzero Jun 25, 2026
0a78eb7
test(23-06): assert 12 schedules with registry archetype personas
moyunzero Jun 25, 2026
bfb4ede
feat(23-05): inject persona block into speak graph paths
moyunzero Jun 25, 2026
1e4e973
fix(23-05): align ambient intent NPC names with council registry
moyunzero Jun 25, 2026
e008183
feat(23-06): widen schedule loader to npc-1..12
moyunzero Jun 25, 2026
8d710b9
test(23-07): add CouncilRosterPanel read-only roster vitest
moyunzero Jun 25, 2026
5d3474f
feat(23-07): wire 星际议会 drawer tab after collective
moyunzero Jun 25, 2026
73d6f8f
style(23-07): add council-roster-panel BEM styles
moyunzero Jun 25, 2026
f0a26b7
test(23): align collective attitude tests with registry personality s…
moyunzero Jun 25, 2026
7b9034c
feat(23): UAT polish, relationship labels, and shell cleanup
moyunzero Jun 25, 2026
5b79800
test(23): align npc-memory collective seed test with registry
moyunzero Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

AetherLife 是一款 AI 驱动的多人联机生活模拟 Web 游戏。玩家与拥有独立记忆、反思与长期规划的 NPC 通过自然语言/语音互动,共同影响一个可程序化扩展、由 LLM 注入叙事灵魂的世界。目标用户是喜欢《模拟人生》《动物森友会》《我的世界》的玩家、AI 爱好者,以及偏社交与叙事驱动的玩家。

**Core Value:** 玩家可以用自然语言指挥 NPC 完成复杂任务,NPC 会记住互动并据此改变未来行为——这一「记忆→反思→规划→执行」闭环必须在 MVP 中可验证、可感知。
**Core Value:** 玩家可以用自然语言指挥 NPC 完成复杂任务,NPC 会记住互动并据此改变未来行为——这一「记忆→反思→执行」闭环必须在 MVP 中可验证、可感知。

### Constraints

Expand Down
163 changes: 111 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,126 @@
# AetherLife / 以太人生

[![CI](https://github.com/moyunzero/AetherLife/actions/workflows/ci.yml/badge.svg)](https://github.com/moyunzero/AetherLife/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)

AI 驱动的多人联机生活模拟 Web 游戏:与拥有记忆的 NPC 用自然语言互动,在可扩展的程序化世界中移动、协作与叙事。
> **EN:** AetherLife is a multiplayer life-simulation web game where you guide memory-bearing NPCs through natural language in a procedural pixel world. Colyseus handles authoritative sync; LangGraph workers run async NPC turns with persistent pgvector memory.
>
> **中文:** AetherLife 是一款 AI 驱动的多人联机生活模拟 Web 游戏。玩家用自然语言指挥拥有持久记忆的 NPC,在 Phaser 4 程序化世界中探索与叙事;Colyseus 权威同步,LangGraph worker 异步执行 NPC 回合。

## 特性
## Table of Contents / 目录

- **多人联机** — Colyseus 权威同步,最多 4 人同房间
- **自然语言指挥** — 通过 ai-gateway 解析意图,worker 异步执行 NPC 回合
- **持久记忆** — Postgres + pgvector,NPC 会记住互动并影响后续行为
- **Phaser 4 世界** — 2D 像素「地球Online」风:网格移动、程序化 chunk 地形与世界 lore
- **智能 Ambient NPC(v3)** — schedule/zone 漫游、异步 LLM intent 副行、Tiled 碰撞与 village-plaza 跨区(Phase 16)
- **Speak SLA(v3)** — worker-state / memory-context 缓存、stale fallback、并行 speak 多 Tab 不丢回复(Phase 17 / ISSUE-048)
- **集体态度** — NPC 对玩家/群体的态度随行为演化(Phase 12+)
- [About / 项目简介](#about--项目简介)
- [Project Status / 项目状态](#project-status--项目状态)
- [Demo / 演示](#demo--演示)
- [Features / 特性](#features--特性)
- [Tech Stack / 技术栈](#tech-stack--技术栈)
- [Quick Start / 快速开始](#quick-start--快速开始)
- [Architecture / 架构](#architecture--架构)
- [Testing / 测试](#testing--测试)
- [Documentation / 文档](#documentation--文档)
- [Contributing / 贡献](#contributing--贡献)
- [License](#license)

## 技术栈
## About / 项目简介

| 层 | 技术 |
**EN:** Players explore a Stardew-inspired 2D world, discover LLM-generated lore, and shape NPC collective attitudes through dialogue and actions. The core loop—**perceive → remember → reflect → act**—must be verifiable in every milestone removed from quest-strip UI in favor of ambient world echo.

**中文:** 玩家在星露谷式 2D 世界中探索、发现 LLM 注入的区块 lore,并通过对话与行为影响 NPC 对群体的集体态度。核心闭环——**感知 → 记忆 → 反思 → 执行**——须在每次会话中可验证;v4 起移除任务条 UI,改为 ambient 世界回响。

**Target audience / 目标用户:** Life-sim fans (*The Sims*, *Animal Crossing*, *Minecraft*), AI enthusiasts, and narrative-driven multiplayer players.

## Project Status / 项目状态

| Milestone | Phases | Status | Shipped |
|-----------|--------|--------|---------|
| **v0** Phase 0 text loop | 01–05 | ✅ Shipped / 已交付 | 2026-06-04 |
| **v1** Graphics + multiplayer + world | 06–08, 10–12.1 (09 deferred) | ✅ Shipped | 2026-06-07 |
| **v2** Playable AI town | 12.2–15 | ✅ Shipped | 2026-06-09 |
| **v3** Intelligent ambient + Speak SLA | 16–17.1, 18 | ✅ Shipped | 2026-06-11 |
| **v4** Solo life loop | 19–22 | ✅ Shipped | 2026-06-22 |
| **v5** AI Society / Council Worldview | 23–27 | 🔨 In progress / 进行中 | Phase 23 ✅ (2026-06-25) |
| **Deferred** Voice pipeline | 09 | ⏸ Deferred / 暂缓 | — |

**EN:** Phase 24–27 (world chronicle, council vote/debate, 12-NPC map presence, personal life timeline) are planned. See the full development history for every phase, decision, and verification gate.

**中文:** Phase 24–27(世界编年史、议会辩论表决、12 NPC 上地图、个人人生时间线)规划中。完整 37 个 Phase 的开发时间、思路、状态与验收命令见开发历程文档。

→ **[Development History / 开发历程](./docs/DEVELOPMENT-HISTORY.md)**

## Demo / 演示

| | |
|---|---|
| **Local / 本地** | [http://localhost:5173](http://localhost:5173) — run `pnpm dev:stack` |
| **Screenshots / 截图** | _Coming soon / 即将补充_ |
| **Public deploy / 公网部署** | _Not yet available / 暂无_ |

## Features / 特性

| EN | 中文 |
|----|------|
| 客户端 | React 19 · Vite · Phaser 4 |
| 实时 | Colyseus · SSE |
| **Multiplayer** — Colyseus authoritative sync, up to 4 players per room | **多人联机** — Colyseus 权威同步,最多 4 人同房间 |
| **Natural language** — ai-gateway parses intent; worker runs async NPC turns | **自然语言指挥** — ai-gateway 解析意图,worker 异步执行 NPC 回合 |
| **Persistent memory** — Postgres + pgvector; NPCs remember and adapt | **持久记忆** — Postgres + pgvector,NPC 记住互动并影响后续行为 |
| **Phaser 4 world** — Grid movement, procedural chunks, world lore | **Phaser 4 世界** — 网格移动、程序化 chunk 地形与世界 lore |
| **Intelligent ambient NPCs (v3)** — Schedule/zone wander, async LLM intent, Tiled collision | **智能 Ambient NPC(v3)** — schedule/zone 漫游、异步 LLM intent、Tiled 碰撞 |
| **Speak SLA (v3)** — worker-state cache, stale fallback, multi-tab speak | **Speak SLA(v3)** — worker-state / memory-context 缓存、stale fallback、多 Tab speak |
| **Collective attitude** — NPC group attitude evolves with player behavior | **集体态度** — NPC 对玩家/群体的态度随行为演化 |
| **Council personas (v5)** — 12-NPC registry, `__council__` memory scope (Phase 23) | **议会人格(v5)** — 12 人 registry、`__council__` 记忆 scope(Phase 23) |

## Tech Stack / 技术栈

| Layer / 层 | Technology / 技术 |
|------------|-------------------|
| Client / 客户端 | React 19 · Vite · Phaser 4 |
| Realtime / 实时 | Colyseus · SSE |
| AI | LangGraph worker · FastAPI gateway |
| 数据 | Supabase Postgres · Upstash Redis |
| Data / 数据 | Supabase Postgres · Upstash Redis |

Monorepo`apps/web` · `apps/game-server` · `apps/ai-gateway` · `workers/agent-worker` · `packages/*`
Monorepo: `apps/web` · `apps/game-server` · `apps/ai-gateway` · `workers/agent-worker` · `packages/*`

## 快速开始
## Quick Start / 快速开始

### 前置条件
### Prerequisites / 前置条件

- Node.js 20+pnpm 9+`corepack enable && corepack prepare pnpm@9.15.0 --activate`
- [Supabase](https://supabase.com) 项目(Postgres + `CREATE EXTENSION vector`
- Node.js 20+, pnpm 9+ (`corepack enable && corepack prepare pnpm@9.15.0 --activate`)
- [Supabase](https://supabase.com) project (Postgres + `CREATE EXTENSION vector`)
- [Upstash](https://upstash.com) Redis
- Python 3.12+[uv](https://docs.astral.sh/uv/)ai-gateway / worker
- LLM API Key(见 `.env.example`;生产默认 **NVIDIA NIM** + OpenRouter embed
- Python 3.12+, [uv](https://docs.astral.sh/uv/) (ai-gateway / worker)
- LLM API keys (see `.env.example`; production defaults to **NVIDIA NIM** + OpenRouter embed)

### 安装与启动
### Install & run / 安装与启动

```bash
git clone https://github.com/moyunzero/AetherLife.git
cd AetherLife
pnpm install
cp .env.example .env # 填入 DATABASE_URLREDIS_URLLLM 密钥
cp .env.example .env # fill DATABASE_URL, REDIS_URL, LLM keys
pnpm verify:cloud
pnpm --filter @aetherlife/npc-memory db:migrate
cd apps/ai-gateway && uv sync --extra dev && cd ../..
pnpm dev:stack
```

浏览器打开 **http://localhost:5173**`Ctrl+C` 停止全部本地进程。
Open **http://localhost:5173** in your browser. Press `Ctrl+C` to stop all local processes.

> 无需本地 Postgres/Redis — 开发默认使用 Supabase + Upstash 云实例。
> UI 冒烟可用 `pnpm dev:stack:mock`;**phase 验收脚本须真实 LLM**(`pnpm dev:stack`,禁止 `LLM_MOCK=1`)。
**EN:** No local Postgres/Redis required — dev uses Supabase + Upstash cloud. UI smoke: `pnpm dev:stack:mock`. Phase verification scripts require **real LLM** (`pnpm dev:stack`, never `LLM_MOCK=1`).

### 健康检查
**中文:** 无需本地 Postgres/Redis — 开发默认使用 Supabase + Upstash 云实例。UI 冒烟可用 `pnpm dev:stack:mock`;**phase 验收脚本须真实 LLM**(`pnpm dev:stack`,禁止 `LLM_MOCK=1`)。

### Health checks / 健康检查

```bash
curl -sf http://127.0.0.1:5173/
curl -sf http://127.0.0.1:2567/health
curl -sf http://127.0.0.1:8000/health
```

## 架构
## Architecture / 架构

```mermaid
flowchart LR
Browser["浏览器 :5173"] --> Web["Vite web"]
Browser["Browser :5173"] --> Web["Vite web"]
Web -->|"/api"| GS["game-server :2567"]
Web -->|"/v1"| GW["ai-gateway :8000"]
GW --> GS
Expand All @@ -76,48 +131,52 @@ flowchart LR
Worker --> PG
```

| 服务 | 端口 | 职责 |
|------|------|------|
| web | 5173 | UI;代理 `/v1` → gateway`/api` → game-server |
| game-server | 2567 | Colyseus 房间、SSE、记忆 API |
| ai-gateway | 8000 | NL 解析、输入审核、chat 入口 |
| agent-worker | — | Redis 队列消费,NPC LangGraph 回合 |
| Service / 服务 | Port / 端口 | Role / 职责 |
|----------------|-------------|-------------|
| web | 5173 | UI; proxies `/v1` → gateway, `/api` → game-server |
| game-server | 2567 | Colyseus rooms, SSE, memory API |
| ai-gateway | 8000 | NL parse, input guard, chat ingress |
| agent-worker | — | Redis queue consumer, LangGraph NPC turns |

分终端调试`pnpm dev` · `pnpm dev:ai` · `pnpm dev:worker`(等价于 `pnpm dev:stack`)。
Per-terminal debug / 分终端调试: `pnpm dev` · `pnpm dev:ai` · `pnpm dev:worker` (equivalent to `pnpm dev:stack`).

## 测试
## Testing / 测试

```bash
pnpm turbo test
pnpm turbo build
pnpm verify # build + test + verify:cloud
pnpm agent:verify # diff → mapped unit tests (mock LLM OK)

# 跨层单测(可 mock LLM
# Cross-layer unit tests (mock LLM OK) / 跨层单测
pnpm --filter @aetherlife/game-server test
cd workers/agent-worker && LLM_MOCK=1 uv run pytest -q
cd apps/ai-gateway && uv run pytest tests -q
```

Phase 集成验收(需 `pnpm dev:stack` + 真实 API Key):见 [CONTRIBUTING.md](./CONTRIBUTING.md#集成验收)。
v3 Speak SLA / Golden Flows:`pnpm agent:verify --e2e --base`(见 [docs/E2E-POLICY.md](./docs/E2E-POLICY.md))。
**EN:** Phase integration gates require `pnpm dev:stack` + real API keys — see [CONTRIBUTING.md](./CONTRIBUTING.md#集成验收). Golden flows: `pnpm agent:verify --e2e --base` ([E2E-POLICY.md](./docs/E2E-POLICY.md)).

**中文:** Phase 集成验收需 `pnpm dev:stack` + 真实 API Key,见 [CONTRIBUTING.md](./CONTRIBUTING.md#集成验收)。Golden Flows:`pnpm agent:verify --e2e --base`([docs/E2E-POLICY.md](./docs/E2E-POLICY.md))。

Action schema: [packages/game-actions/README.md](./packages/game-actions/README.md)

Action schema:[packages/game-actions/README.md](./packages/game-actions/README.md)
## Documentation / 文档

## 文档
| Document / 文档 | Description / 说明 |
|-----------------|-------------------|
| **[Development History / 开发历程](./docs/DEVELOPMENT-HISTORY.md)** | All 37 phases: timeline, rationale, status, verify gates |
| [CONTRIBUTING.md](./CONTRIBUTING.md) | Workflow, constraints, acceptance commands |
| [docs/CONTRACTS.md](./docs/CONTRACTS.md) | game-server ↔ worker API contracts |
| [docs/INVARIANTS-MULTIPLAYER.md](./docs/INVARIANTS-MULTIPLAYER.md) | Multiplayer spatial + NL invariants |
| [docs/MOVEMENT-ARCHITECTURE.md](./docs/MOVEMENT-ARCHITECTURE.md) | Phaser movement + Colyseus sync |
| [docs/E2E-POLICY.md](./docs/E2E-POLICY.md) | E2E / UAT policy + Golden Flows |
| [docs/PHASE-EVOLUTION.md](./docs/PHASE-EVOLUTION.md) | Phase evolution + cross-layer guardrails |

| 文档 | 说明 |
|------|------|
| [CONTRIBUTING.md](./CONTRIBUTING.md) | 协作流程、约束与验收命令 |
| [docs/CONTRACTS.md](./docs/CONTRACTS.md) | game-server ↔ worker API 契约 |
| [docs/INVARIANTS-MULTIPLAYER.md](./docs/INVARIANTS-MULTIPLAYER.md) | 多人空间与 NL 不变量 |
| [docs/MOVEMENT-ARCHITECTURE.md](./docs/MOVEMENT-ARCHITECTURE.md) | Phaser 移动与 Colyseus 同步 |
| [docs/E2E-POLICY.md](./docs/E2E-POLICY.md) | E2E / UAT 策略与 Golden Flows |
| [docs/PHASE-EVOLUTION.md](./docs/PHASE-EVOLUTION.md) | 阶段演进与跨层防债务 |
## Contributing / 贡献

## 贡献
**EN:** Issues and PRs welcome. Read [CONTRIBUTING.md](./CONTRIBUTING.md) first. Never commit `.env` or API keys.

欢迎 Issue 与 PR。请先阅读 [CONTRIBUTING.md](./CONTRIBUTING.md)。请勿提交 `.env` 或 API 密钥。
**中文:** 欢迎 Issue 与 PR。请先阅读 [CONTRIBUTING.md](./CONTRIBUTING.md)。请勿提交 `.env` 或 API 密钥。

## License

Expand Down
4 changes: 2 additions & 2 deletions apps/game-server/data/schedules/npc-1.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"npcId": "npc-1",
"persona": "scholar",
"_comment": "Hybrid persona — AM stationary orchard (home), PM wander plaza, evening orchard.",
"persona": "order_keeper",
"_comment": "Order keeper — AM stationary orchard study, PM patrol orchard, evening plaza social, night orchard rest.",
"segments": [
{
"fromMinute": 360,
Expand Down
35 changes: 35 additions & 0 deletions apps/game-server/data/schedules/npc-10.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"npcId": "npc-10",
"persona": "brawler",
"_comment": "Brawler — AM plaza patrol, PM plaza wander, evening orchard chopping.",
"segments": [
{
"fromMinute": 360,
"toMinute": 720,
"activityKey": "patrol",
"zoneId": "beginning-fields@v1:plaza",
"mobility": "wander"
},
{
"fromMinute": 720,
"toMinute": 1080,
"activityKey": "wandering",
"zoneId": "beginning-fields@v1:plaza",
"mobility": "wander"
},
{
"fromMinute": 1080,
"toMinute": 1200,
"activityKey": "chopping_wood",
"zoneId": "beginning-fields@v1:orchard",
"mobility": "stationary"
},
{
"fromMinute": 1200,
"toMinute": 360,
"activityKey": "resting",
"zoneId": "beginning-fields@v1:plaza",
"mobility": "stationary"
}
]
}
35 changes: 35 additions & 0 deletions apps/game-server/data/schedules/npc-11.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"npcId": "npc-11",
"persona": "perfectionist",
"_comment": "Perfectionist — AM orchard tending stationary, PM orchard watering, evening orchard reading.",
"segments": [
{
"fromMinute": 360,
"toMinute": 540,
"activityKey": "tending_crops",
"zoneId": "beginning-fields@v1:orchard",
"mobility": "stationary"
},
{
"fromMinute": 540,
"toMinute": 900,
"activityKey": "watering",
"zoneId": "beginning-fields@v1:orchard",
"mobility": "stationary"
},
{
"fromMinute": 900,
"toMinute": 1200,
"activityKey": "reading",
"zoneId": "beginning-fields@v1:orchard",
"mobility": "stationary"
},
{
"fromMinute": 1200,
"toMinute": 360,
"activityKey": "resting",
"zoneId": "beginning-fields@v1:orchard",
"mobility": "stationary"
}
]
}
42 changes: 42 additions & 0 deletions apps/game-server/data/schedules/npc-12.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"npcId": "npc-12",
"persona": "explorer",
"_comment": "Explorer — AM orchard wander, PM plaza patrol, evening pond fishing, night plaza wander.",
"segments": [
{
"fromMinute": 360,
"toMinute": 540,
"activityKey": "wandering",
"zoneId": "beginning-fields@v1:orchard",
"mobility": "wander"
},
{
"fromMinute": 540,
"toMinute": 900,
"activityKey": "patrol",
"zoneId": "beginning-fields@v1:plaza",
"mobility": "wander"
},
{
"fromMinute": 900,
"toMinute": 1080,
"activityKey": "fishing",
"zoneId": "beginning-fields@v1:pond",
"mobility": "stationary"
},
{
"fromMinute": 1080,
"toMinute": 1200,
"activityKey": "socializing",
"zoneId": "beginning-fields@v1:plaza",
"mobility": "poi"
},
{
"fromMinute": 1200,
"toMinute": 360,
"activityKey": "wandering",
"zoneId": "beginning-fields@v1:plaza",
"mobility": "wander"
}
]
}
Loading
Loading