【红楼梦:第二篇】梦境漫游,详细设计指南

红楼梦·梦境漫游

AI文字MUD游戏

详细设计文档

技术栈: Next.js 16 + Tailwind CSS 4 + shadcn/ui + Zustand + Prisma/SQLite + z-ai-web-dev-sdk

总代码量: ~88K行 (TS/TSX 67K+ + CSS 21K+)


1 项目概述

1.1 项目背景

"红楼梦·梦境漫游"是一款基于大语言模型(LLM)驱动的《红楼梦》主题沉浸式文字冒险游戏(AI MUD)。玩家以贾府远房亲戚等等的身份进入大观园,与林黛玉、贾宝玉、薛宝钗等经典角色交互,体验红楼梦世界中的诗词、茶道、节庆、人情与故事。

游戏通过智谱AI大模型实时生成文学风格的叙事内容,结合红楼梦知识库(RAG)提升叙事的专业性和原汁原味,营造真实的沉浸体验。

1.2 核心特性

  • 8位红楼梦经典角色,各具独特性格、语言风格、情感倾向和心情系统
  • 10个大观园场景,每个场景含4个子场景,共计40个可探索地点
  • 31个中国传统小游戏(投壶/围棋/古琴/花灯/华容道/七巧板等)
  • 157+个成就,6大类别,4级稀有度
  • LLM驱动叙事,支持对话/吹诗/灯谜/礼物/梦境等多种交互
  • 7种天气粒子实时渲染 + 季节氛围 + 中国风音效
  • 主线/支线任务系统、亲密度关系事件、角色日程、物品合成等深度玩法

1.3 技术栈总览

层次 技术选型 用途
前端框架 Next.js 16 (App Router) + React 19 全栈框架,SR/SSR支持
UI组件库 shadcn/ui (30+ Radix UI组件) 复杂交互组件
样式方案 Tailwind CSS 4 + tailwindcss-animate 响应式布局 + 动画
状态管理 Zustand 5.0.6 全局游戏状态
数据库 Prisma 6.11 + SQLite 持久化存储
AI SDK z-ai-web-dev-sdk (智谱AI) LLM文本生成
运行时 Bun 服务端运行
部署 Caddy反向代理 (81->3000) 生产环境部署
动画 framer-motion + embla-carousel 页面过渡和轮播
图表 recharts 数据可视化
拖拽 @dnd-kit/core + @dnd-kit/sortable 物品拖拽操作

2 系统架构设计

2.1 整体架构

项目采用前后端一体化架构,基于Next.js App Router实现。前端负责游戏界面渲染和交互,后端通过API Routes处理游戏逻辑和LLM调用,数据通过Prisma/SQLite持久化。

核心数据流向图

#mermaid-svg-Nx2W5HcOp0YUiOVL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Nx2W5HcOp0YUiOVL .error-icon{fill:#552222;}#mermaid-svg-Nx2W5HcOp0YUiOVL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Nx2W5HcOp0YUiOVL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .marker.cross{stroke:#333333;}#mermaid-svg-Nx2W5HcOp0YUiOVL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Nx2W5HcOp0YUiOVL p{margin:0;}#mermaid-svg-Nx2W5HcOp0YUiOVL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .cluster-label text{fill:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .cluster-label span{color:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .cluster-label span p{background-color:transparent;}#mermaid-svg-Nx2W5HcOp0YUiOVL .label text,#mermaid-svg-Nx2W5HcOp0YUiOVL span{fill:#333;color:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .node rect,#mermaid-svg-Nx2W5HcOp0YUiOVL .node circle,#mermaid-svg-Nx2W5HcOp0YUiOVL .node ellipse,#mermaid-svg-Nx2W5HcOp0YUiOVL .node polygon,#mermaid-svg-Nx2W5HcOp0YUiOVL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .rough-node .label text,#mermaid-svg-Nx2W5HcOp0YUiOVL .node .label text,#mermaid-svg-Nx2W5HcOp0YUiOVL .image-shape .label,#mermaid-svg-Nx2W5HcOp0YUiOVL .icon-shape .label{text-anchor:middle;}#mermaid-svg-Nx2W5HcOp0YUiOVL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .rough-node .label,#mermaid-svg-Nx2W5HcOp0YUiOVL .node .label,#mermaid-svg-Nx2W5HcOp0YUiOVL .image-shape .label,#mermaid-svg-Nx2W5HcOp0YUiOVL .icon-shape .label{text-align:center;}#mermaid-svg-Nx2W5HcOp0YUiOVL .node.clickable{cursor:pointer;}#mermaid-svg-Nx2W5HcOp0YUiOVL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .arrowheadPath{fill:#333333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Nx2W5HcOp0YUiOVL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Nx2W5HcOp0YUiOVL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Nx2W5HcOp0YUiOVL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Nx2W5HcOp0YUiOVL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .cluster text{fill:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL .cluster span{color:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Nx2W5HcOp0YUiOVL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Nx2W5HcOp0YUiOVL rect.text{fill:none;stroke-width:0;}#mermaid-svg-Nx2W5HcOp0YUiOVL .icon-shape,#mermaid-svg-Nx2W5HcOp0YUiOVL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Nx2W5HcOp0YUiOVL .icon-shape p,#mermaid-svg-Nx2W5HcOp0YUiOVL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Nx2W5HcOp0YUiOVL .icon-shape .label rect,#mermaid-svg-Nx2W5HcOp0YUiOVL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Nx2W5HcOp0YUiOVL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Nx2W5HcOp0YUiOVL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Nx2W5HcOp0YUiOVL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 外部服务
后端 API Routes
前端
玩家输入指令
前端解析命令类型
调用对应API
服务端构建LLM提示词
LLM生成叙事
服务端解析心情/亲密度变化
更新数据库 + 返回前端
Zustand更新状态 + 渲染UI

2.2 目录结构

目录/文件 职责说明
src/app/ Next.js App Router页面和布局
src/app/api/ 19个API路由端点
src/components/game/ 80+游戏组件(含31个小游戏)
src/components/ui/ shadcn/ui基础组件库
src/components/config/ 6个配置中心组件
src/hooks/ 7个自定义React Hooks
src/lib/ 24个核心业务逻辑模块
src/app/styles/ 9个CSS样式文件(~21K行)
prisma/ 数据库模型定义和种子数据
mini-services/ 独立微服务(game-service)

2.3 数据库设计

数据库采用SQLite,通过Prisma ORM管理,共定义11个模型:

模型名 用途 关键字段
Character 红楼梦角色 name, personality(JSON), speechStyle, emotionalTendency, backgroundStories(JSON), taboos(JSON), avatarEmoji
Relationship 角色间关系 fromCharacterId, toCharacterId, type, affectionLevel(0-100)
GameSession 游戏会话 playerName, playerGender, currentLocation, currentPeriod, gamePhase, playerIdentity
Conversation 对话记录 sessionId, characterId, role, content, scene
CharacterState 角色实时状态 sessionId+characterId(联合唯一), currentMood, relationshipWithPlayer, isPresent
GameEvent 游戏事件 sessionId, eventType, title, content, choices(JSON)
GameConfig 游戏配置 name, config(JSON), isActive
Location 大观园场景 name, description, area, subLocations(JSON), characters(JSON), atmosphere
Inventory 玩家物品 sessionId+itemName(联合唯一), itemType, quantity
KnowledgeEntry 知识库条目 category, title, content, source, tags(JSON)
GameSave 游戏存档 saveName, playerName, sessionId, saveData(JSON)

2.4 状态管理架构

项目采用双层状态管理策略:

2.4.1 Zustand全局状态 (game-store.ts)
  • 单一数据源(Single Source of Truth),包含50+个action方法
  • 管理内容:游戏会话、消息历史、角色状态、物品、任务、成就、天气、时辰、统计数据等
  • 防抖持久化:1秒间隔写入localStorage,最多保留200条消息
2.4.2 角色记忆状态 (character-memory.ts)
  • 独立Zustand store,管理玩家与各角色的互动记忆
  • 记忆类型:conversation | gift | event | location_visit | examine | poetry | milestone
  • 每角色最多50条记忆,独立localStorage持久化
2.4.3 内存存储
  • 物品栏采用服务端内存Map存储(非DB,服务器重启丢失)
状态管理架构图

#mermaid-svg-zExGUywO5PFY1tUS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zExGUywO5PFY1tUS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zExGUywO5PFY1tUS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zExGUywO5PFY1tUS .error-icon{fill:#552222;}#mermaid-svg-zExGUywO5PFY1tUS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zExGUywO5PFY1tUS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zExGUywO5PFY1tUS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zExGUywO5PFY1tUS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zExGUywO5PFY1tUS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zExGUywO5PFY1tUS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zExGUywO5PFY1tUS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zExGUywO5PFY1tUS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zExGUywO5PFY1tUS .marker.cross{stroke:#333333;}#mermaid-svg-zExGUywO5PFY1tUS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zExGUywO5PFY1tUS p{margin:0;}#mermaid-svg-zExGUywO5PFY1tUS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-zExGUywO5PFY1tUS .cluster-label text{fill:#333;}#mermaid-svg-zExGUywO5PFY1tUS .cluster-label span{color:#333;}#mermaid-svg-zExGUywO5PFY1tUS .cluster-label span p{background-color:transparent;}#mermaid-svg-zExGUywO5PFY1tUS .label text,#mermaid-svg-zExGUywO5PFY1tUS span{fill:#333;color:#333;}#mermaid-svg-zExGUywO5PFY1tUS .node rect,#mermaid-svg-zExGUywO5PFY1tUS .node circle,#mermaid-svg-zExGUywO5PFY1tUS .node ellipse,#mermaid-svg-zExGUywO5PFY1tUS .node polygon,#mermaid-svg-zExGUywO5PFY1tUS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zExGUywO5PFY1tUS .rough-node .label text,#mermaid-svg-zExGUywO5PFY1tUS .node .label text,#mermaid-svg-zExGUywO5PFY1tUS .image-shape .label,#mermaid-svg-zExGUywO5PFY1tUS .icon-shape .label{text-anchor:middle;}#mermaid-svg-zExGUywO5PFY1tUS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zExGUywO5PFY1tUS .rough-node .label,#mermaid-svg-zExGUywO5PFY1tUS .node .label,#mermaid-svg-zExGUywO5PFY1tUS .image-shape .label,#mermaid-svg-zExGUywO5PFY1tUS .icon-shape .label{text-align:center;}#mermaid-svg-zExGUywO5PFY1tUS .node.clickable{cursor:pointer;}#mermaid-svg-zExGUywO5PFY1tUS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zExGUywO5PFY1tUS .arrowheadPath{fill:#333333;}#mermaid-svg-zExGUywO5PFY1tUS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zExGUywO5PFY1tUS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zExGUywO5PFY1tUS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zExGUywO5PFY1tUS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zExGUywO5PFY1tUS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zExGUywO5PFY1tUS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zExGUywO5PFY1tUS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zExGUywO5PFY1tUS .cluster text{fill:#333;}#mermaid-svg-zExGUywO5PFY1tUS .cluster span{color:#333;}#mermaid-svg-zExGUywO5PFY1tUS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zExGUywO5PFY1tUS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zExGUywO5PFY1tUS rect.text{fill:none;stroke-width:0;}#mermaid-svg-zExGUywO5PFY1tUS .icon-shape,#mermaid-svg-zExGUywO5PFY1tUS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zExGUywO5PFY1tUS .icon-shape p,#mermaid-svg-zExGUywO5PFY1tUS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zExGUywO5PFY1tUS .icon-shape .label rect,#mermaid-svg-zExGUywO5PFY1tUS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zExGUywO5PFY1tUS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zExGUywO5PFY1tUS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zExGUywO5PFY1tUS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 服务端状态
客户端状态
防抖写入
独立写入
API调用
API调用
Zustand 全局状态

game-store.ts
Zustand 记忆状态

character-memory.ts
localStorage 持久化
SQLite Database

Prisma ORM
内存Map存储

物品栏


3 API接口设计

3.1 API路由总览

共计19个API端点,均基于Next.js API Routes实现:

路径 方法 功能说明
/api GET 健康检查端点
/api/config GET/POST 游戏配置读取/保存
/api/characters GET 角色列表
/api/locations GET 场景查询
/api/game/start POST 创建新游戏会话
/api/game/command POST 核心指令处理(LLM叙事)
/api/game/event POST 随机事件生成
/api/game/move POST 地点移动
/api/game/save GET/POST/DELETE 存档管理
/api/game/load POST 读取存档
/api/game/inventory GET/POST 物品栏管理
/api/game/use-item POST 对角色使用物品
/api/game/poetry POST 诗词创作
/api/game/riddle POST 灯谜出题
/api/game/riddle/answer POST 灯谜答题
/api/game/locations GET 游戏内场景列表
/api/game/schedule POST 时间推进与角色移动
/api/game/session/id GET 获取会话详情
/api/test-connection GET LLM连接测试

3.2 核心API详细设计

3.2.1 POST /api/game/command --- 核心指令处理

这是整个游戏的核心API,负责处理玩家的所有文字指令并返回LLM生成的叙事内容。

请求参数

  • sessionId: 游戏会话ID
  • command: 玩家输入的指令文本
  • characterId: 目标角色ID(可选)
  • providerConfig: LLM提供商配置
  • weather: 天气描述
  • useItemName: 使用的物品名
  • memoriesText/allMemoriesText: 角色记忆文本

处理流程
#mermaid-svg-LPnyDPOngsldK7Df{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LPnyDPOngsldK7Df .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LPnyDPOngsldK7Df .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LPnyDPOngsldK7Df .error-icon{fill:#552222;}#mermaid-svg-LPnyDPOngsldK7Df .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LPnyDPOngsldK7Df .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LPnyDPOngsldK7Df .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LPnyDPOngsldK7Df .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LPnyDPOngsldK7Df .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LPnyDPOngsldK7Df .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LPnyDPOngsldK7Df .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LPnyDPOngsldK7Df .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LPnyDPOngsldK7Df .marker.cross{stroke:#333333;}#mermaid-svg-LPnyDPOngsldK7Df svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LPnyDPOngsldK7Df p{margin:0;}#mermaid-svg-LPnyDPOngsldK7Df .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LPnyDPOngsldK7Df .cluster-label text{fill:#333;}#mermaid-svg-LPnyDPOngsldK7Df .cluster-label span{color:#333;}#mermaid-svg-LPnyDPOngsldK7Df .cluster-label span p{background-color:transparent;}#mermaid-svg-LPnyDPOngsldK7Df .label text,#mermaid-svg-LPnyDPOngsldK7Df span{fill:#333;color:#333;}#mermaid-svg-LPnyDPOngsldK7Df .node rect,#mermaid-svg-LPnyDPOngsldK7Df .node circle,#mermaid-svg-LPnyDPOngsldK7Df .node ellipse,#mermaid-svg-LPnyDPOngsldK7Df .node polygon,#mermaid-svg-LPnyDPOngsldK7Df .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LPnyDPOngsldK7Df .rough-node .label text,#mermaid-svg-LPnyDPOngsldK7Df .node .label text,#mermaid-svg-LPnyDPOngsldK7Df .image-shape .label,#mermaid-svg-LPnyDPOngsldK7Df .icon-shape .label{text-anchor:middle;}#mermaid-svg-LPnyDPOngsldK7Df .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LPnyDPOngsldK7Df .rough-node .label,#mermaid-svg-LPnyDPOngsldK7Df .node .label,#mermaid-svg-LPnyDPOngsldK7Df .image-shape .label,#mermaid-svg-LPnyDPOngsldK7Df .icon-shape .label{text-align:center;}#mermaid-svg-LPnyDPOngsldK7Df .node.clickable{cursor:pointer;}#mermaid-svg-LPnyDPOngsldK7Df .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LPnyDPOngsldK7Df .arrowheadPath{fill:#333333;}#mermaid-svg-LPnyDPOngsldK7Df .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LPnyDPOngsldK7Df .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LPnyDPOngsldK7Df .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LPnyDPOngsldK7Df .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LPnyDPOngsldK7Df .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LPnyDPOngsldK7Df .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LPnyDPOngsldK7Df .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LPnyDPOngsldK7Df .cluster text{fill:#333;}#mermaid-svg-LPnyDPOngsldK7Df .cluster span{color:#333;}#mermaid-svg-LPnyDPOngsldK7Df div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LPnyDPOngsldK7Df .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LPnyDPOngsldK7Df rect.text{fill:none;stroke-width:0;}#mermaid-svg-LPnyDPOngsldK7Df .icon-shape,#mermaid-svg-LPnyDPOngsldK7Df .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LPnyDPOngsldK7Df .icon-shape p,#mermaid-svg-LPnyDPOngsldK7Df .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LPnyDPOngsldK7Df .icon-shape .label rect,#mermaid-svg-LPnyDPOngsldK7Df .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LPnyDPOngsldK7Df .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LPnyDPOngsldK7Df .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LPnyDPOngsldK7Df :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

接收指令
命令类型检测
角色昵称匹配
构建LLM系统提示词
调用LLM生成叙事
提取角色对话
解析心情变化
计算亲密度变化
检测里程碑?
触发特殊剧情
角色日程移动
批量更新数据库
返回叙事结果

  1. 命令类型检测:支持"观察/查看"、"送礼给"等特殊命令
  2. 角色昵称匹配:内置8位角色别名映射(如"黛儿""林妹妹" -> 林黛玉)
  3. LLM叙事生成:构建LLM系统提示词(含地点、时段、在场角色、玩家身份、天气、记忆)
  4. 对话提取:正则提取"X道:「...」"格式的角色对话
  5. 心情解析:关键词在角色名字30字符范围内检测心情变化(10种心情,6级强度)
  6. 亲密度计算:基于叙事中的正/负信号(强+5、中+3、弱+1)+ 额外加成
  7. 亲密度里程碑:检测跨阈值事件,触发LLM生成特殊剧情
  8. 角色日程:时间流逝命令触发1-3个角色的加权随机移动
  9. DB更新:批量更新角色状态(心情、亲密度、在场状态、位置)
3.2.2 POST /api/game/start --- 开始新游戏

创建游戏会话,初始地点为荣国府大门,时段为"乾隆二十五年春",阶段为intro。根据起始地点的characters字段决定初始在场角色,初始亲密度50。

3.2.3 POST /api/game/event --- 随机事件

6种事件类型随机触发:character_appear(角色出现)、invitation(邀请)、rumor(谣言)、poetry_contest(诗词大会)、riddle_game(灯谜游戏)、其他。20%概率获得随机物品。

3.2.4 POST /api/game/schedule --- 时间推进

时段循环:晨 -> 午 -> 昏 -> 夜 -> 翠日晨。角色移动基于性格系统:mobility(偏离日程概率)、stayHomeProbability(留在原地概率)、preferredLocations(偏好地点)。时间段影响角色心情。

3.2.5 POST /api/game/save & /api/game/load --- 存读档

存档包含完整游戏状态(session + 角色状态 + 消息历史 + 地点数据)。读档采用多层回退策略:存档数据优先,DB数据兜底。


4 核心业务系统设计

4.1 LLM引擎系统 (llm-engine.ts)

4.1.1 双Provider支持
  • z-ai SDK:智谱AI官方SDK,30s超时
  • 自定义OpenAI兼容API :自动拼接/v1/chat/completions端点
4.1.2 系统提示词架构

系统提示词包含以下内容:

  • 世界观设定:清代乾隆年间,贾府大观园
  • 叙事规则:文白夹杂,禁止现代用语
  • 在场角色约束:硬性规则,仅在场角色可参与对话
  • 玩家身份:性别影响NPC称呼
  • 时辰氛围映射:10个时辰关键词对应不同氛围描述
  • 角色记忆注入:格式化的近期互动记忆
4.1.3 分场景温度控制
  • 对话(dialog):temperature=0.7
  • 情节(plot):temperature=0.6
  • 诗词(poetry):temperature=0.85

4.2 角色系统

4.2.1 角色定义

共8位经典角色,每位角色具备丰富的属性定义:

角色 居所 性格特质 emoji
林黛玉 潇湘馆 多愁善感、才情绝世 🌸
贾宝玉 怡红院 风流倚信、多情善感 🎭
薛宝钗 蘅芜苑 稳重端庄、学识渊博 🪐
王熙凤 --- 精明强干、张狂火爆 🔥
贾母 --- 慈祥和蔼、享受富贵 🌿
史湘云 --- 英豪阔大、心直口快 🐦
妙玉 栊翠庵 孤高如雪、才情出众 🏛
袭人 --- 温柔贤惠、小心翼翼 💡
4.2.2 角色日程系统 (character-schedule.ts)

按时辰(辰时到亥时)定义8个角色的位置与活动。服务端时间推进时,角色根据mobilitystayHomeProbabilitypreferredLocations等性格参数进行加权随机移动。

4.2.3 角色记忆系统 (character-memory.ts)

管理玩家与各角色的互动记忆,用于LLM上下文注入。每角色最多50条记忆,支持相对时间标签显示(刚刚/一刻钟前/半时辰前/一时辰前等)。

4.3 亲密度与关系系统

4.3.1 亲密度计算机制
  • 基础范围:0-100,初始值50
  • 叙事信号:强正面+5、中正面+3、弱正面+1;强负面-5、中负面-3、弱负面-1
  • 额外加成:送礼+3~8、拜访+2、使用物品+5
4.3.2 亲密度等级映射
数值范围 中文标签 颜色
95+ 至死不渝 中国红
80+ 心心相印 翠绿
70+ 亲密无间 绿色
60+ 惺惺相惜 黄色
50+ 友善相待 黄绿
40+ 点头之交 褐色
30+ 萍水相逢 灰色
20+ 心存隔阂 深褐
<20 形同陌路 暗红
4.3.3 关系事件系统 (relationship-events.ts)

8个角色 x 5个阈值级别 = 40个关系事件。当亲密度跨越特定阈值(30/50/70/80/95)时触发特殊剧情事件,每个事件含有叙事、选择项和奖励。

示例(林黛玉线):潇湘初访(30) -> 共读西厢(50) -> 黛玉葬花(70) -> 泪尽还泪(80) -> 木石前盟(95)

4.4 场景系统

4.4.1 场景定义

共10个大观园场景,每个场景含4个子场景,共计40个可探索地点:

场景 区域 子场景
怡红院 大观园 书房/卧室/后花园/小厨房
潇湘馆 大观园 琴房/竹轩/葬花台/书斋
蘅芜苑 大观园 暖阁/药房/花圃/客厅
稻香村 大观园 农舍/菜园/井台/碾坊
秋爽斋 大观园 画室/绣阁/书房/暖房
藕香榭 大观园 水榭/荷塘/画舫/曲廊
栊翠庵 大观园 佛堂/茶室/净室/竹林
紫菱洲 大观园 闺房/绣楼/水阁/花厅
暖香坞 大观园 暖房/书房/妆台/后院
省亲别墅 大观园 正殿/侧殿/戏台/庭院
4.4.2 天气系统

7种天气状态:sunny(晴)、cloudy(多云)、light_rain(小雨)、heavy_rain(大雨)、snow(雪)、fog(雾)、windy(风)。每种天气对应独特的粒子效果和环境音效。

4.5 任务系统 (quest-system.ts)

4.5.1 主线任务(8个)
  • 初入贾府 -> 结缘黛玉 -> 海棠诗社 -> 元春省亲 -> 宝玉挨打 -> 黛玉葬花 -> 金玉良缘 -> 大观园主
4.5.2 支线任务(5个)
  • 花间寻诗、灯谜高手、义结金兰、求签问卦、收藏鉴赏
4.5.3 每日任务

每天自动生成3个随机任务(吟诗/社交/探索),完成后获得奖励。

4.6 成就系统 (achievements.ts)

157+个成就,分6大类别,4级稀有度:

类别 示例成就 稀有度
探索 初入贾府、游遍大观园、足遍天下(50次移动) common~legendary
社交 初次交谈、知己难求(80+)、众星捧月(全员50+) common~epic
文采 诗词新秀(1首)、才高八斗(5首)、诗仙(10首) common~legendary
收藏 初获宝物、收藏家(5件)、珍宝如山(10件) common~rare
时间 朝花夕拾、百年修行、千古风流 rare~legendary
小游戏 投壶/围棋/古琴/花灯/七巧板/剪窗花等20+种 common~legendary

4.7 小游戏系统

共31个中国传统小游戏,涵盖多种类型:

类型 小游戏
投壶射箭 投壶、射覆、踢毽子
棋类对弈 围棋、象棋残局、华容道、打马图经
诗词文学 飞花令、对联、诗社、接龙诗、牙牌令、诗词多米诺
手工艺术 花灯制作、七巧板、扇面画、剪窗花、风筝制作
音乐开心 古琴、抖空竹
派对社交 划拳、藏钩、击鼓传花、摇骰行令
智力挑战 灯谜、九宫格灯谜、记忆宫殿、记忆翻牌、问答
其他 日运、茶道、梦境、礼物、信件、社交八卦、场景探索、草药制作、赛马、叶子戏

4.8 文化系统

4.8.1 茶道系统
  • 12种名茶数据(龙井/碧螺春/铁观音/大红袍/普洱/白毫银针等)
  • 茶与心情联动:8种茶对8个角色的心情效果矩阵
  • 季节推荐:评分算法(季节匹配30分 + 角色偏好加分 + 最爱茶额外加分)
4.8.2 节日系统 (lunar-festivals.ts + event-calendar.ts)
  • 8个传统节日:春节/元宵节/清明节/端午节/七夕节/中秋节/重阳节/除夕
  • 24个季节事件(每季6个),包含节日、生辰、季节活动等
4.8.3 梦境系统 (dream-interpretation.ts)
  • 10个红楼梦主题梦境,各有解锁条件
  • 梦境心情:mysterious/romantic/melancholy/joyful/profound/tragic/elegant/lively
4.8.4 礼物系统 (gift-system.ts)
  • 24种礼物,6大类别:文房雅器/珠宝玉器/茶道香道/绣品织物/花卉草木/实用器物
  • 8个角色的礼物偏好矩阵(loved/liked/disliked/neutral)
  • 效果计算:loved +15~20,liked +8~12,neutral +3~5,disliked -5~-10

4.9 物品合成系统 (item-crafting.ts)

10个合成配方,支持消耗材料合成新物品。包含传说级配方"红楼遗梦"(鹰鸢佩 + 金玉缘卷)。

4.10 知识库系统 (red-chamber-knowledge.ts)

红楼梦经典知识数据库,用于RAG增强LLM叙事质量。约24条知识条目,分5类:

  • 诗词(8首):开篇诗、判词、葬花吟、题帕三绝、秋窗风雨夕等
  • 名句(6条):宝黛初见、宝玉外貌、护官符、好了歌等
  • 场景(5个):大观园、潇湘馆、怡红院、蘅芜苑、荣国府正堂
  • 角色(5个):贾宝玉、林黛玉、薛宝钗、王熙凤、史湘云
  • 事件(3个):元春省亲、黛玉葬花、宝玉挨打

根据地点/角色/关键词检索相关知识,最多返回5条,注入LLM上下文。

4.11 音效系统 (sound-manager.ts)

基于Web Audio API的纯程序化音效系统,无需音频文件。中国风五声音阶。

  • 环境音:雨声、风声、晴天、雪天、雾天
  • 交互音:点击、移动、成就、通知、打字机
  • 背景音乐:随机五声音阶旋律,带颤音效果

5 前端界面设计

5.1 页面布局

游戏采用三栏布局设计,移动端自动切换为Tab导航:

区域 桌面端 移动端 内容
左侧栏 角色面板 Tab1: 叙事 CharacterPanel(角色卡片+关系雷达图)
中央区域 叙事+输入 Tab2: 角色 NarrativePanel + CommandInput
右侧栏 操作面板 Tab3: 操作 SidePanel(31个小游戏+功能入口)
前端布局示意图

#mermaid-svg-EsaXrUaymVmNK2M7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EsaXrUaymVmNK2M7 .error-icon{fill:#552222;}#mermaid-svg-EsaXrUaymVmNK2M7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EsaXrUaymVmNK2M7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EsaXrUaymVmNK2M7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EsaXrUaymVmNK2M7 .marker.cross{stroke:#333333;}#mermaid-svg-EsaXrUaymVmNK2M7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EsaXrUaymVmNK2M7 p{margin:0;}#mermaid-svg-EsaXrUaymVmNK2M7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 .cluster-label text{fill:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 .cluster-label span{color:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 .cluster-label span p{background-color:transparent;}#mermaid-svg-EsaXrUaymVmNK2M7 .label text,#mermaid-svg-EsaXrUaymVmNK2M7 span{fill:#333;color:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 .node rect,#mermaid-svg-EsaXrUaymVmNK2M7 .node circle,#mermaid-svg-EsaXrUaymVmNK2M7 .node ellipse,#mermaid-svg-EsaXrUaymVmNK2M7 .node polygon,#mermaid-svg-EsaXrUaymVmNK2M7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EsaXrUaymVmNK2M7 .rough-node .label text,#mermaid-svg-EsaXrUaymVmNK2M7 .node .label text,#mermaid-svg-EsaXrUaymVmNK2M7 .image-shape .label,#mermaid-svg-EsaXrUaymVmNK2M7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-EsaXrUaymVmNK2M7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EsaXrUaymVmNK2M7 .rough-node .label,#mermaid-svg-EsaXrUaymVmNK2M7 .node .label,#mermaid-svg-EsaXrUaymVmNK2M7 .image-shape .label,#mermaid-svg-EsaXrUaymVmNK2M7 .icon-shape .label{text-align:center;}#mermaid-svg-EsaXrUaymVmNK2M7 .node.clickable{cursor:pointer;}#mermaid-svg-EsaXrUaymVmNK2M7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EsaXrUaymVmNK2M7 .arrowheadPath{fill:#333333;}#mermaid-svg-EsaXrUaymVmNK2M7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EsaXrUaymVmNK2M7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EsaXrUaymVmNK2M7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EsaXrUaymVmNK2M7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EsaXrUaymVmNK2M7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EsaXrUaymVmNK2M7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EsaXrUaymVmNK2M7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EsaXrUaymVmNK2M7 .cluster text{fill:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 .cluster span{color:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EsaXrUaymVmNK2M7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EsaXrUaymVmNK2M7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-EsaXrUaymVmNK2M7 .icon-shape,#mermaid-svg-EsaXrUaymVmNK2M7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EsaXrUaymVmNK2M7 .icon-shape p,#mermaid-svg-EsaXrUaymVmNK2M7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EsaXrUaymVmNK2M7 .icon-shape .label rect,#mermaid-svg-EsaXrUaymVmNK2M7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EsaXrUaymVmNK2M7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EsaXrUaymVmNK2M7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EsaXrUaymVmNK2M7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 移动端布局
切换
切换
Tab1: 叙事
Tab2: 角色
Tab3: 操作
桌面端布局
左侧栏

角色面板
中央区域

叙事+输入
右侧栏

操作面板

5.2 核心组件设计

5.2.1 NarrativePanel(叙事面板)
  • 消息类型:叙事、玩家、角色对话、系统消息、诗词
  • 打字机效果:最新叙事逐字显示(50ms/字),可点击跳过
  • Markdown渲染:自定义中文小说样式(首行缩进、行高、引用金色边框)
  • 自动滚动到底部 + 新消息浮动按钮
5.2.2 CommandInput(命令输入)
  • 命令别名系统:缩写自动展开("诗"->吟诗,"看"->观察四周)
  • 命令检测与分发:move/visit/gift/give/use等类型自动识别
  • 16个快捷命令按钮
  • 自动补全 + 历史记录(上下箭头翻阅)
5.2.3 CharacterPanel(角色面板)
  • CharacterCard(React.memo优化):头像+心情+性格标签+亲密度进度条
  • 展开详情:个性描述、背景故事、亲密度趋势图、里程碑徽章
  • RelationshipRadar:SVG雷达图展示全角色亲密度
5.2.4 SidePanel(操作面板)

集成了游戏的所有功能入口,包括:物品栏、游戏日志、关系图谱、统计面板、灯谜、记忆回溯、成就、任务、小地图、每日运势、时间线、结局,以及31个小游戏入口。

5.3 自定义Hooks

Hook 职责 返回值
useGameActions 游戏动作封装 handlePoetry/handleRandomEvent/handleTimePassage/handleMoveToLocation
useSaveLoad 存读档逻辑 handleSaveGame/handleLoadGame/handleDeleteSave
useAchievementChecker 成就检查(60+条件) checkAchievements/checkAndUpdateQuests
useRelationshipEvents 关系事件触发 checkAndTriggerRelationshipEvents/handleRelEventChoice
useMobile 移动端检测 isMobile
useSwipe 滑动手势 滑动方向检测
useToast Toast通知 toast函数

5.4 CSS样式体系

9个CSS文件,共计21K+行:

文件 内容
globals.css 全局样式导入
base.css 基础样式变量
components.css 组件通用样式
decorative.css 装饰增强(22个装饰类)
animations.css 动画定义(250+自定义动画)
game-specific.css 游戏专属样式(~6900行)
responsive.css 响应式布局
seasonal.css 季节主题
weather.css 天气粒子效果
scrollbar.css 自定义滚动条

CSS微交互系统:32个组件交互类 + 22个装饰增强 + 250+自定义动画。


6 配置与部署

6.1 配置中心

游戏提供完整的配置中心(ConfigCenter),包含6个子模块:

  • ModelConfig:LLM模型选择(Provider、模型类型、API Key)
  • ParameterTuning:分场景温度调节(对话/情节/诗词)
  • CharacterManagement:角色启用/禁用管理
  • KnowledgeBase:知识库管理
  • AdvancedSettings:高级设置

6.2 部署架构

  • 运行时:Bun
  • Next.js输出模式:standalone(适合Docker/容器化)
  • 反向代理:Caddy,监听端口81,代理到localhost:3000
  • 开发模式:支持XTransformPort查询参数动态端口代理
  • TypeScript构建:忽略类型错误(ignoreBuildErrors: true)
部署架构图

#mermaid-svg-xM20IQGFgPEyeZzR{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xM20IQGFgPEyeZzR .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xM20IQGFgPEyeZzR .error-icon{fill:#552222;}#mermaid-svg-xM20IQGFgPEyeZzR .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xM20IQGFgPEyeZzR .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xM20IQGFgPEyeZzR .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xM20IQGFgPEyeZzR .marker.cross{stroke:#333333;}#mermaid-svg-xM20IQGFgPEyeZzR svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xM20IQGFgPEyeZzR p{margin:0;}#mermaid-svg-xM20IQGFgPEyeZzR .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xM20IQGFgPEyeZzR .cluster-label text{fill:#333;}#mermaid-svg-xM20IQGFgPEyeZzR .cluster-label span{color:#333;}#mermaid-svg-xM20IQGFgPEyeZzR .cluster-label span p{background-color:transparent;}#mermaid-svg-xM20IQGFgPEyeZzR .label text,#mermaid-svg-xM20IQGFgPEyeZzR span{fill:#333;color:#333;}#mermaid-svg-xM20IQGFgPEyeZzR .node rect,#mermaid-svg-xM20IQGFgPEyeZzR .node circle,#mermaid-svg-xM20IQGFgPEyeZzR .node ellipse,#mermaid-svg-xM20IQGFgPEyeZzR .node polygon,#mermaid-svg-xM20IQGFgPEyeZzR .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xM20IQGFgPEyeZzR .rough-node .label text,#mermaid-svg-xM20IQGFgPEyeZzR .node .label text,#mermaid-svg-xM20IQGFgPEyeZzR .image-shape .label,#mermaid-svg-xM20IQGFgPEyeZzR .icon-shape .label{text-anchor:middle;}#mermaid-svg-xM20IQGFgPEyeZzR .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xM20IQGFgPEyeZzR .rough-node .label,#mermaid-svg-xM20IQGFgPEyeZzR .node .label,#mermaid-svg-xM20IQGFgPEyeZzR .image-shape .label,#mermaid-svg-xM20IQGFgPEyeZzR .icon-shape .label{text-align:center;}#mermaid-svg-xM20IQGFgPEyeZzR .node.clickable{cursor:pointer;}#mermaid-svg-xM20IQGFgPEyeZzR .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xM20IQGFgPEyeZzR .arrowheadPath{fill:#333333;}#mermaid-svg-xM20IQGFgPEyeZzR .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xM20IQGFgPEyeZzR .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xM20IQGFgPEyeZzR .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xM20IQGFgPEyeZzR .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xM20IQGFgPEyeZzR .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xM20IQGFgPEyeZzR .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xM20IQGFgPEyeZzR .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xM20IQGFgPEyeZzR .cluster text{fill:#333;}#mermaid-svg-xM20IQGFgPEyeZzR .cluster span{color:#333;}#mermaid-svg-xM20IQGFgPEyeZzR div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xM20IQGFgPEyeZzR .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xM20IQGFgPEyeZzR rect.text{fill:none;stroke-width:0;}#mermaid-svg-xM20IQGFgPEyeZzR .icon-shape,#mermaid-svg-xM20IQGFgPEyeZzR .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xM20IQGFgPEyeZzR .icon-shape p,#mermaid-svg-xM20IQGFgPEyeZzR .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xM20IQGFgPEyeZzR .icon-shape .label rect,#mermaid-svg-xM20IQGFgPEyeZzR .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xM20IQGFgPEyeZzR .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xM20IQGFgPEyeZzR .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xM20IQGFgPEyeZzR :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 构建配置
服务器
81端口
代理请求
运行时
数据读写
调用
standalone输出
ignoreBuildErrors: true
用户
Caddy 反向代理
Next.js 应用

localhost:3000
Bun
SQLite数据库
智谱AI LLM API
Build Script
TypeScript 编译


7 已知问题与优化方向

问题 描述 建议优化方向
服务器内存压力 需NODE_OPTIONS="--max-old-space-size=4096" 优化LLM调用和组件渲染性能
物品系统内存存储 服务器重启后物品丢失 迁移到Prisma DB持久化
成就检查不稳定 部分依赖字符串匹配 采用结构化事件触发机制
game-specific.css过大 已增长至~6900行 拆分为小游戏独立样式文件
Safari音效兼容性 Web Audio API在Safari上可能有问题 添加兼容性检测和降级方案
agent-browser OOM 浏览器自动化存在内存溢出 优化内存使用策略

8 总结

"红楼梦·梦境漫游"是一个技术复杂度较高的AI驱动文字游戏项目,总代码量约88K行。项目将红楼梦的文学传统与现代AI技术深度融合,构建了一个包含角色系统、场景系统、任务系统、成就系统、小游戏系统、文化系统等多层次玩法的完整游戏世界。

核心亮点包括:LLM驱动的动态叙事、红楼梦知识库RAG增强、丰富的角色亲密度与关系事件系统、31个中国传统小游戏、以及精心设计的视觉效果(天气粒子、季节氛围、中国风音效)。

相关推荐
code bean1 小时前
【LangChain】 文本分割器全景指南:从 RecursiveCharacterTextSplitter 到各类分割器对比
人工智能·自然语言处理·langchain
暗夜猎手-大魔王1 小时前
hermes源码学习3-Agent Loop 内部机制
人工智能·学习
ting94520001 小时前
Superlog 开源自主可观测性工具全栈技术深度剖析
人工智能·架构·开源
学计算机的计算基1 小时前
2026 年 AI 助手三国杀:Claude Code vs 腾讯马维斯 vs MiniMax Mavis,我同时用了三周,结论很意外
java·人工智能·python·算法·langchain
_Aaron___1 小时前
Spring AI 应用上线前,先把大模型调用变成可观测链路
java·人工智能·spring
basketball6161 小时前
AI Infra 硬件体系与编程模型:6. Warp 调度器详解
人工智能
我有2只猫1 小时前
LabelStudio二次开发
人工智能·python·django·ocr
多年小白1 小时前
AI 日报 - 2026年6月7日
人工智能·量子计算
前端的阶梯1 小时前
如何节省你的token,请看CodeGraph
前端·人工智能·后端