【水浒传:第二篇】AI江湖 —项目详细设计指南(一)

水浒传:AI江湖 --- 项目详细设计

技术栈 : Next.js 16 + React 19 + TypeScript + Prisma + SQLite + Tailwind CSS

代码规模: ~62,000+ 行 (engine.ts ~9082行 + route.ts ~23440行 + page.tsx ~6000行)


1. 系统总览架构

1.1 整体分层架构

#mermaid-svg-6ArmJuSR43RyChOd{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-6ArmJuSR43RyChOd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6ArmJuSR43RyChOd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6ArmJuSR43RyChOd .error-icon{fill:#552222;}#mermaid-svg-6ArmJuSR43RyChOd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6ArmJuSR43RyChOd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6ArmJuSR43RyChOd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6ArmJuSR43RyChOd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6ArmJuSR43RyChOd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6ArmJuSR43RyChOd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6ArmJuSR43RyChOd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6ArmJuSR43RyChOd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6ArmJuSR43RyChOd .marker.cross{stroke:#333333;}#mermaid-svg-6ArmJuSR43RyChOd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6ArmJuSR43RyChOd p{margin:0;}#mermaid-svg-6ArmJuSR43RyChOd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6ArmJuSR43RyChOd .cluster-label text{fill:#333;}#mermaid-svg-6ArmJuSR43RyChOd .cluster-label span{color:#333;}#mermaid-svg-6ArmJuSR43RyChOd .cluster-label span p{background-color:transparent;}#mermaid-svg-6ArmJuSR43RyChOd .label text,#mermaid-svg-6ArmJuSR43RyChOd span{fill:#333;color:#333;}#mermaid-svg-6ArmJuSR43RyChOd .node rect,#mermaid-svg-6ArmJuSR43RyChOd .node circle,#mermaid-svg-6ArmJuSR43RyChOd .node ellipse,#mermaid-svg-6ArmJuSR43RyChOd .node polygon,#mermaid-svg-6ArmJuSR43RyChOd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6ArmJuSR43RyChOd .rough-node .label text,#mermaid-svg-6ArmJuSR43RyChOd .node .label text,#mermaid-svg-6ArmJuSR43RyChOd .image-shape .label,#mermaid-svg-6ArmJuSR43RyChOd .icon-shape .label{text-anchor:middle;}#mermaid-svg-6ArmJuSR43RyChOd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6ArmJuSR43RyChOd .rough-node .label,#mermaid-svg-6ArmJuSR43RyChOd .node .label,#mermaid-svg-6ArmJuSR43RyChOd .image-shape .label,#mermaid-svg-6ArmJuSR43RyChOd .icon-shape .label{text-align:center;}#mermaid-svg-6ArmJuSR43RyChOd .node.clickable{cursor:pointer;}#mermaid-svg-6ArmJuSR43RyChOd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6ArmJuSR43RyChOd .arrowheadPath{fill:#333333;}#mermaid-svg-6ArmJuSR43RyChOd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6ArmJuSR43RyChOd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6ArmJuSR43RyChOd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6ArmJuSR43RyChOd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6ArmJuSR43RyChOd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6ArmJuSR43RyChOd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6ArmJuSR43RyChOd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6ArmJuSR43RyChOd .cluster text{fill:#333;}#mermaid-svg-6ArmJuSR43RyChOd .cluster span{color:#333;}#mermaid-svg-6ArmJuSR43RyChOd 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-6ArmJuSR43RyChOd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6ArmJuSR43RyChOd rect.text{fill:none;stroke-width:0;}#mermaid-svg-6ArmJuSR43RyChOd .icon-shape,#mermaid-svg-6ArmJuSR43RyChOd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6ArmJuSR43RyChOd .icon-shape p,#mermaid-svg-6ArmJuSR43RyChOd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6ArmJuSR43RyChOd .icon-shape .label rect,#mermaid-svg-6ArmJuSR43RyChOd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6ArmJuSR43RyChOd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6ArmJuSR43RyChOd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6ArmJuSR43RyChOd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 数据层 Data Layer
AI 层 AI Integration
业务逻辑层 Business Logic
API 层 API Gateway
展示层 Presentation
page.tsx 主页面

React 组件树
globals.css

20+ @keyframes
Framer Motion

动画层
/api/game/create

角色创建
/api/game/action

核心行动处理器

~23,440行
/api/game/map

地图服务
/api/game/stats

统计数据
/api/game/achievements

成就系统
/api/llm-config

AI模型配置
engine.ts 游戏引擎

~9,082行
指令解析器 parseCommand()
战斗系统 calcDamage()
技能子系统管理器

43个双字母系统
事件系统

随机事件/奇遇
自定义 LLM

OpenAI 兼容 API
z-ai-web-dev-sdk

内置模型回退
Prisma ORM
SQLite

数据库
内存状态

Map/Dictionary

1.2 请求-响应完整链路

Prisma + SQLite数据库 ai.tsAI 模型层 engine.ts游戏引擎 parseCommand()指令解析器 /api/game/actionNext.js API Route page.tsxReact 前端 Prisma + SQLite数据库 ai.tsAI 模型层 engine.ts游戏引擎 parseCommand()指令解析器 /api/game/actionNext.js API Route page.tsxReact 前端 #mermaid-svg-pQsFRb69rKqH24I6{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-pQsFRb69rKqH24I6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pQsFRb69rKqH24I6 .error-icon{fill:#552222;}#mermaid-svg-pQsFRb69rKqH24I6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pQsFRb69rKqH24I6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pQsFRb69rKqH24I6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pQsFRb69rKqH24I6 .marker.cross{stroke:#333333;}#mermaid-svg-pQsFRb69rKqH24I6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pQsFRb69rKqH24I6 p{margin:0;}#mermaid-svg-pQsFRb69rKqH24I6 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-pQsFRb69rKqH24I6 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-pQsFRb69rKqH24I6 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-pQsFRb69rKqH24I6 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-pQsFRb69rKqH24I6 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-pQsFRb69rKqH24I6 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-pQsFRb69rKqH24I6 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-pQsFRb69rKqH24I6 .sequenceNumber{fill:white;}#mermaid-svg-pQsFRb69rKqH24I6 #sequencenumber{fill:#333;}#mermaid-svg-pQsFRb69rKqH24I6 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-pQsFRb69rKqH24I6 .messageText{fill:#333;stroke:none;}#mermaid-svg-pQsFRb69rKqH24I6 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-pQsFRb69rKqH24I6 .labelText,#mermaid-svg-pQsFRb69rKqH24I6 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-pQsFRb69rKqH24I6 .loopText,#mermaid-svg-pQsFRb69rKqH24I6 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-pQsFRb69rKqH24I6 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-pQsFRb69rKqH24I6 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-pQsFRb69rKqH24I6 .noteText,#mermaid-svg-pQsFRb69rKqH24I6 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-pQsFRb69rKqH24I6 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-pQsFRb69rKqH24I6 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-pQsFRb69rKqH24I6 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-pQsFRb69rKqH24I6 .actorPopupMenu{position:absolute;}#mermaid-svg-pQsFRb69rKqH24I6 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-pQsFRb69rKqH24I6 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-pQsFRb69rKqH24I6 .actor-man circle,#mermaid-svg-pQsFRb69rKqH24I6 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-pQsFRb69rKqH24I6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} alt移动指令 altNPC对话 / 自由文本 玩家 输入自然语言指令如 "向北"POST { playerId, command, dialogueHistory }解析指令字符串{ type: 'move', direction: 'north' }canMove(currentLocCode, direction)查询 Location 连接关系目标地点{ success: true, targetCode }aiChatCompletion(messages)AI 生成的叙事文本更新玩家状态JSON 响应 { scene, player, message, ... }更新 React state渲染消息流显示游戏输出 玩家


2. 数据库设计(ER 图)

2.1 实体关系图

#mermaid-svg-Kuf6XedxDUJlaHDi{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-Kuf6XedxDUJlaHDi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Kuf6XedxDUJlaHDi .error-icon{fill:#552222;}#mermaid-svg-Kuf6XedxDUJlaHDi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Kuf6XedxDUJlaHDi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Kuf6XedxDUJlaHDi .marker.cross{stroke:#333333;}#mermaid-svg-Kuf6XedxDUJlaHDi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Kuf6XedxDUJlaHDi p{margin:0;}#mermaid-svg-Kuf6XedxDUJlaHDi .entityBox{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Kuf6XedxDUJlaHDi .relationshipLabelBox{fill:hsl(80, 100%, 96.2745098039%);opacity:0.7;background-color:hsl(80, 100%, 96.2745098039%);}#mermaid-svg-Kuf6XedxDUJlaHDi .relationshipLabelBox rect{opacity:0.5;}#mermaid-svg-Kuf6XedxDUJlaHDi .labelBkg{background-color:rgba(248.6666666666, 255, 235.9999999999, 0.5);}#mermaid-svg-Kuf6XedxDUJlaHDi .edgeLabel .label{fill:#9370DB;font-size:14px;}#mermaid-svg-Kuf6XedxDUJlaHDi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Kuf6XedxDUJlaHDi .edge-pattern-dashed{stroke-dasharray:8,8;}#mermaid-svg-Kuf6XedxDUJlaHDi .node rect,#mermaid-svg-Kuf6XedxDUJlaHDi .node circle,#mermaid-svg-Kuf6XedxDUJlaHDi .node ellipse,#mermaid-svg-Kuf6XedxDUJlaHDi .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Kuf6XedxDUJlaHDi .relationshipLine{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Kuf6XedxDUJlaHDi .marker{fill:none!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-Kuf6XedxDUJlaHDi .edgeLabel{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Kuf6XedxDUJlaHDi .edgeLabel .label rect{fill:rgba(232,232,232, 0.8);}#mermaid-svg-Kuf6XedxDUJlaHDi .edgeLabel .label text{fill:#333;}#mermaid-svg-Kuf6XedxDUJlaHDi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 拥有
进行
记录
被持有
被接受
Player
string
id
PK
cuid()
string
name
UK
角色名
string
title
称号
int
level
等级
int
exp
经验
int
hp
生命
int
maxHp
生命上限
int
mp
内力
int
maxMp
内力上限
int
gold
黄金
int
silver
白银
int
copper
铜钱
int
strength
力量 0-100
int
agility
敏捷 0-100
int
intelligence
智力 0-100
int
constitution
体质 0-100
int
charisma
魅力 0-100
int
luck
运气 0-100
int
attack
攻击力
int
defense
防御力
int
critRate
暴击率
int
dodgeRate
闪避率
int
swordProf
剑熟练度
int
spearProf
枪熟练度
int
staffProf
棍熟练度
int
bowProf
弓熟练度
int
liangshanRep
梁山声望
int
courtRep
朝廷声望
int
jianghuRep
江湖声望
string
currentLocId
FK
当前位置
string
faction
所属阵营
string
status
状态
int
plotProgress
剧情进度
string
completedMilestones
JSON
string
skillLevels
JSON 技能等级
string
achievements
JSON 成就
string
mails
JSON 邮件
string
pets
JSON 宠物
string
guildInfo
JSON 帮派
string
repPurchases
JSON 声望购买
PlayerItem
string
id
PK
string
playerId
FK
string
itemId
FK
int
quantity
数量
boolean
equipped
已装备
PlayerQuest
string
id
PK
string
playerId
FK
string
questId
FK
string
status
进行中/已完成/已放弃
int
currentStep
当前步骤
datetime
startedAt
datetime
completedAt
DialogueLog
string
id
PK
string
playerId
FK
string
npcCode
NPC编码
string
role
player/npc
string
content
对话内容
datetime
createdAt
Item
string
id
PK
string
name
UK
名称
string
type
武器/防具/药品/杂物/秘籍
string
subType
子类型
string
rarity
普通/精良/稀有/传说
string
description
描述
int
price
价格
int
attackBonus
攻击加成
int
defenseBonus
防御加成
int
hpBonus
生命加成
int
mpBonus
内力加成
int
healHp
恢复HP
int
healMp
恢复MP
boolean
usable
可使用
boolean
equippable
可装备
string
equipSlot
装备槽位
Location
string
id
PK
string
code
UK
地点编码
string
name
名称
string
description
描述
string
area
区域
string
faction
势力
string
north
北向连接
string
south
南向连接
string
east
东向连接
string
west
西向连接
string
up
上向连接
string
down
下向连接
boolean
hasShop
有商店
boolean
hasHealer
有医馆
int
dangerLevel
危险等级
string
npcs
JSON NPC列表
Npc
string
id
PK
string
code
UK
NPC编码
string
name
姓名
string
nickname
绰号
string
starRank
星号
int
rank
108将排名
string
title
称号
int
strength
力量
int
agility
敏捷
int
intelligence
智力
int
constitution
体质
int
charisma
魅力
int
luck
运气
int
attack
攻击
int
defense
防御
int
hp
生命
int
maxHp
生命上限
string
personality
性格描述
string
personalityTags
性格标签
string
faction
阵营
string
loyaltyTo
忠于
string
relationships
JSON 关系网
string
greeting
问候语
string
backStory
背景故事
string
locationCode
所在位置
boolean
alive
存活
boolean
recruitable
可招募
boolean
recruited
已招募
Quest
string
id
PK
string
code
UK
任务编码
string
name
名称
string
type
main/side/random
string
description
描述
string
requirements
JSON 触发条件
string
steps
JSON 步骤
string
rewards
JSON 奖励
int
plotProgressReq
剧情进度要求
int
priority
优先级
boolean
active
启用
Battle
string
id
PK
string
player1Id
玩家ID
string
player2Id
对手ID
string
npcCode
NPC编码
int
turn
回合数
string
status
进行中/胜利/失败/逃跑
string
log
JSON 战斗日志

2.2 核心关系总结

关系 类型 说明
Player → PlayerItem 1:N 玩家拥有多个物品
Item → PlayerItem 1:N 物品被多个玩家持有
Player → PlayerQuest 1:N 玩家接取多个任务
Quest → PlayerQuest 1:N 任务被多个玩家进行
Player → DialogueLog 1:N 玩家与NPC对话历史
Player.currentLocId → Location.code N:1 玩家当前位置
Npc.locationCode → Location.code N:1 NPC所在位置
Location.direction → Location.code N:1 地图连接关系

3. 游戏引擎设计

3.1 引擎模块结构

#mermaid-svg-Tsy3L3quh1l4RcKZ{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-Tsy3L3quh1l4RcKZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Tsy3L3quh1l4RcKZ .error-icon{fill:#552222;}#mermaid-svg-Tsy3L3quh1l4RcKZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Tsy3L3quh1l4RcKZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .marker.cross{stroke:#333333;}#mermaid-svg-Tsy3L3quh1l4RcKZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Tsy3L3quh1l4RcKZ p{margin:0;}#mermaid-svg-Tsy3L3quh1l4RcKZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .cluster-label text{fill:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .cluster-label span{color:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .cluster-label span p{background-color:transparent;}#mermaid-svg-Tsy3L3quh1l4RcKZ .label text,#mermaid-svg-Tsy3L3quh1l4RcKZ span{fill:#333;color:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .node rect,#mermaid-svg-Tsy3L3quh1l4RcKZ .node circle,#mermaid-svg-Tsy3L3quh1l4RcKZ .node ellipse,#mermaid-svg-Tsy3L3quh1l4RcKZ .node polygon,#mermaid-svg-Tsy3L3quh1l4RcKZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .rough-node .label text,#mermaid-svg-Tsy3L3quh1l4RcKZ .node .label text,#mermaid-svg-Tsy3L3quh1l4RcKZ .image-shape .label,#mermaid-svg-Tsy3L3quh1l4RcKZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-Tsy3L3quh1l4RcKZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .rough-node .label,#mermaid-svg-Tsy3L3quh1l4RcKZ .node .label,#mermaid-svg-Tsy3L3quh1l4RcKZ .image-shape .label,#mermaid-svg-Tsy3L3quh1l4RcKZ .icon-shape .label{text-align:center;}#mermaid-svg-Tsy3L3quh1l4RcKZ .node.clickable{cursor:pointer;}#mermaid-svg-Tsy3L3quh1l4RcKZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .arrowheadPath{fill:#333333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Tsy3L3quh1l4RcKZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Tsy3L3quh1l4RcKZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Tsy3L3quh1l4RcKZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Tsy3L3quh1l4RcKZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .cluster text{fill:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ .cluster span{color:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ 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-Tsy3L3quh1l4RcKZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Tsy3L3quh1l4RcKZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-Tsy3L3quh1l4RcKZ .icon-shape,#mermaid-svg-Tsy3L3quh1l4RcKZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Tsy3L3quh1l4RcKZ .icon-shape p,#mermaid-svg-Tsy3L3quh1l4RcKZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Tsy3L3quh1l4RcKZ .icon-shape .label rect,#mermaid-svg-Tsy3L3quh1l4RcKZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Tsy3L3quh1l4RcKZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Tsy3L3quh1l4RcKZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Tsy3L3quh1l4RcKZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 子系统示例
engine.ts ~9,082行
战斗公式

calcDamage/getExpForLevel
移动验证

canMove
指令解析器

parseCommand ~600行
天气时间

getWeather/getTimeInfo
技能系统

SKILLS/SKILL_COOLDOWNS
43个技能子系统

DY~ZA 双字母前缀
70+全局系统

TALENTS/RECIPES/GUILD...
🎣 DY_ 垂钓系统

钓鱼点/鱼种/比赛
⚔️ BS_ 狩猎系统

猎物/武器/等级
🔨 ZA_ 锻造系统

材料/武器/等级
⛰️ YT_ 阵法系统

八阵图/军令/攻城

3.2 战斗伤害计算公式

#mermaid-svg-YkQcsUXjxpxDcL6z{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-YkQcsUXjxpxDcL6z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-YkQcsUXjxpxDcL6z .error-icon{fill:#552222;}#mermaid-svg-YkQcsUXjxpxDcL6z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-YkQcsUXjxpxDcL6z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-YkQcsUXjxpxDcL6z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-YkQcsUXjxpxDcL6z .marker.cross{stroke:#333333;}#mermaid-svg-YkQcsUXjxpxDcL6z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-YkQcsUXjxpxDcL6z p{margin:0;}#mermaid-svg-YkQcsUXjxpxDcL6z .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z .cluster-label text{fill:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z .cluster-label span{color:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z .cluster-label span p{background-color:transparent;}#mermaid-svg-YkQcsUXjxpxDcL6z .label text,#mermaid-svg-YkQcsUXjxpxDcL6z span{fill:#333;color:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z .node rect,#mermaid-svg-YkQcsUXjxpxDcL6z .node circle,#mermaid-svg-YkQcsUXjxpxDcL6z .node ellipse,#mermaid-svg-YkQcsUXjxpxDcL6z .node polygon,#mermaid-svg-YkQcsUXjxpxDcL6z .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-YkQcsUXjxpxDcL6z .rough-node .label text,#mermaid-svg-YkQcsUXjxpxDcL6z .node .label text,#mermaid-svg-YkQcsUXjxpxDcL6z .image-shape .label,#mermaid-svg-YkQcsUXjxpxDcL6z .icon-shape .label{text-anchor:middle;}#mermaid-svg-YkQcsUXjxpxDcL6z .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-YkQcsUXjxpxDcL6z .rough-node .label,#mermaid-svg-YkQcsUXjxpxDcL6z .node .label,#mermaid-svg-YkQcsUXjxpxDcL6z .image-shape .label,#mermaid-svg-YkQcsUXjxpxDcL6z .icon-shape .label{text-align:center;}#mermaid-svg-YkQcsUXjxpxDcL6z .node.clickable{cursor:pointer;}#mermaid-svg-YkQcsUXjxpxDcL6z .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-YkQcsUXjxpxDcL6z .arrowheadPath{fill:#333333;}#mermaid-svg-YkQcsUXjxpxDcL6z .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-YkQcsUXjxpxDcL6z .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-YkQcsUXjxpxDcL6z .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YkQcsUXjxpxDcL6z .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-YkQcsUXjxpxDcL6z .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YkQcsUXjxpxDcL6z .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-YkQcsUXjxpxDcL6z .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-YkQcsUXjxpxDcL6z .cluster text{fill:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z .cluster span{color:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z 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-YkQcsUXjxpxDcL6z .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-YkQcsUXjxpxDcL6z rect.text{fill:none;stroke-width:0;}#mermaid-svg-YkQcsUXjxpxDcL6z .icon-shape,#mermaid-svg-YkQcsUXjxpxDcL6z .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-YkQcsUXjxpxDcL6z .icon-shape p,#mermaid-svg-YkQcsUXjxpxDcL6z .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-YkQcsUXjxpxDcL6z .icon-shape .label rect,#mermaid-svg-YkQcsUXjxpxDcL6z .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-YkQcsUXjxpxDcL6z .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-YkQcsUXjxpxDcL6z .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-YkQcsUXjxpxDcL6z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是



发动攻击
闪避判定

dodgeRoll < dodgeRate + CON×0.1?
闪避成功

damage = 0
基础伤害计算

max(1, ATK - DEF×0.5) × (1 + STR×0.01)
暴击判定

critRoll < 10% + LUK×0.15%?
暴击伤害

baseDamage × (1.5 + LUK/200)
普通伤害

baseDamage
最终伤害

max(1, finalDamage)

3.3 等级经验曲线

等级 累计经验 升级所需 公式
1→2 0 100 100 × 1.5⁰
2→3 100 150 100 × 1.5¹
3→4 250 225 100 × 1.5²
4→5 475 338 100 × 1.5³
5→6 813 506 100 × 1.5⁴
10→11 ~3,842 ~3,842 100 × 1.5⁹
20→21 ~221,684 ~221,684 100 × 1.5¹⁹

4. 指令解析系统

4.1 解析器架构

#mermaid-svg-TpKI0bQaoiyNJAvz{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-TpKI0bQaoiyNJAvz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TpKI0bQaoiyNJAvz .error-icon{fill:#552222;}#mermaid-svg-TpKI0bQaoiyNJAvz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TpKI0bQaoiyNJAvz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TpKI0bQaoiyNJAvz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TpKI0bQaoiyNJAvz .marker.cross{stroke:#333333;}#mermaid-svg-TpKI0bQaoiyNJAvz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TpKI0bQaoiyNJAvz p{margin:0;}#mermaid-svg-TpKI0bQaoiyNJAvz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz .cluster-label text{fill:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz .cluster-label span{color:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz .cluster-label span p{background-color:transparent;}#mermaid-svg-TpKI0bQaoiyNJAvz .label text,#mermaid-svg-TpKI0bQaoiyNJAvz span{fill:#333;color:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz .node rect,#mermaid-svg-TpKI0bQaoiyNJAvz .node circle,#mermaid-svg-TpKI0bQaoiyNJAvz .node ellipse,#mermaid-svg-TpKI0bQaoiyNJAvz .node polygon,#mermaid-svg-TpKI0bQaoiyNJAvz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TpKI0bQaoiyNJAvz .rough-node .label text,#mermaid-svg-TpKI0bQaoiyNJAvz .node .label text,#mermaid-svg-TpKI0bQaoiyNJAvz .image-shape .label,#mermaid-svg-TpKI0bQaoiyNJAvz .icon-shape .label{text-anchor:middle;}#mermaid-svg-TpKI0bQaoiyNJAvz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TpKI0bQaoiyNJAvz .rough-node .label,#mermaid-svg-TpKI0bQaoiyNJAvz .node .label,#mermaid-svg-TpKI0bQaoiyNJAvz .image-shape .label,#mermaid-svg-TpKI0bQaoiyNJAvz .icon-shape .label{text-align:center;}#mermaid-svg-TpKI0bQaoiyNJAvz .node.clickable{cursor:pointer;}#mermaid-svg-TpKI0bQaoiyNJAvz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TpKI0bQaoiyNJAvz .arrowheadPath{fill:#333333;}#mermaid-svg-TpKI0bQaoiyNJAvz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TpKI0bQaoiyNJAvz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TpKI0bQaoiyNJAvz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TpKI0bQaoiyNJAvz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TpKI0bQaoiyNJAvz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TpKI0bQaoiyNJAvz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TpKI0bQaoiyNJAvz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TpKI0bQaoiyNJAvz .cluster text{fill:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz .cluster span{color:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz 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-TpKI0bQaoiyNJAvz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TpKI0bQaoiyNJAvz rect.text{fill:none;stroke-width:0;}#mermaid-svg-TpKI0bQaoiyNJAvz .icon-shape,#mermaid-svg-TpKI0bQaoiyNJAvz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TpKI0bQaoiyNJAvz .icon-shape p,#mermaid-svg-TpKI0bQaoiyNJAvz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TpKI0bQaoiyNJAvz .icon-shape .label rect,#mermaid-svg-TpKI0bQaoiyNJAvz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TpKI0bQaoiyNJAvz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TpKI0bQaoiyNJAvz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TpKI0bQaoiyNJAvz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是











玩家输入指令
trim() 清理空白
匹配方向指令?

北/南/东/西/上/下/

north/south/east/west...
type: 'move'

direction: 'north'
匹配方向模式?

向东/向西...
查看指令?

看/观察/look
type: 'look'
对话指令?

和XX说话/对话XX
type: 'talk_npc'

target: NPC名
攻击指令?

打/杀/攻击
type: 'attack'
匹配技能系统名?

垂钓/狩猎/锻造...
type: 'dy'/'bs'/'za'...
继续匹配约190+种

指令类型...
帮助/状态/背包/商店

任务/探索/逃跑/强化

合成/签到/PVP/邮件

酒馆/练功/悬赏/采集

挖掘/秘籍/师徒/帮派

炼丹/藏宝图/奇遇...
type: 'unknown'

自由文本交给AI处理

4.2 GameAction 类型联合

typescript 复制代码
type GameAction = {
  type: 'move' | 'look' | 'talk' | 'attack' | 'use' | 'status' 
       | 'inventory' | 'equip' | 'unequip' | 'shop' | 'rest' 
       | 'help' | 'quest' | 'talk_npc' | 'buy' | 'accept_quest' 
       | 'explore' | 'event_choice' | 'flee' | 'abandon_quest' 
       | 'sell' | 'skill' | 'achievement' | 'ranking' 
       // ... 190+ more types
       | 'dy' | 'sn' | 'lw' | 'yk' | 'jb' | 'cm' | 'xg' | 'ql' 
       | 'ds' | 'gz' | 'bs' | 'xc' | 'wq' | 'lf' | 'pk' | 'rw' 
       | 'sq' | 'gx' | 'vp' | 'xl' | 'qj' | 'nh' | 'zr' | 'td' 
       | 'cr' | 'fn' | 'ks' | 'eh' | 'hl' | 'ik' | 'jw' | 'ln' 
       | 'mz' | 'oq' | 'pr' | 'rv' | 'sx' | 'tz' | 'uw' | 'vm' 
       | 'xo' | 'yt' | 'za'  // 43个技能子系统
       | 'tavern' | 'train' | 'dungeon' | 'news' | 'bounty'
       | 'guild' | 'pvp' | 'mentor' | 'pet' | 'mail'
       | 'fortune' | 'gift' | 'journal' | 'recipe'
       | 'alchemy' | 'treasure_map' | 'hidden_location'
       // ... and more
       | 'unknown';  // fallback to AI
  action?: string;
  target?: string;
  direction?: string;
  item?: string;
  raw: string;
};

5. API 层设计

5.1 API 路由表

端点 方法 功能 行数
/api/game/create POST/GET 创建/列出角色 ~154
/api/game/action POST 核心行动处理 ~23,440
/api/game/map GET 地图数据 ~50
/api/game/stats GET 统计数据 ~50
/api/game/achievements POST 成就查询 ~120
/api/llm-config POST/GET AI配置管理 ~60
/api/settings/model POST 模型设置 ~40

5.2 核心 Action API 处理流程

#mermaid-svg-Fc5rshxMO2MP5fur{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-Fc5rshxMO2MP5fur .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Fc5rshxMO2MP5fur .error-icon{fill:#552222;}#mermaid-svg-Fc5rshxMO2MP5fur .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Fc5rshxMO2MP5fur .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Fc5rshxMO2MP5fur .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Fc5rshxMO2MP5fur .marker.cross{stroke:#333333;}#mermaid-svg-Fc5rshxMO2MP5fur svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Fc5rshxMO2MP5fur p{margin:0;}#mermaid-svg-Fc5rshxMO2MP5fur .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Fc5rshxMO2MP5fur .cluster-label text{fill:#333;}#mermaid-svg-Fc5rshxMO2MP5fur .cluster-label span{color:#333;}#mermaid-svg-Fc5rshxMO2MP5fur .cluster-label span p{background-color:transparent;}#mermaid-svg-Fc5rshxMO2MP5fur .label text,#mermaid-svg-Fc5rshxMO2MP5fur span{fill:#333;color:#333;}#mermaid-svg-Fc5rshxMO2MP5fur .node rect,#mermaid-svg-Fc5rshxMO2MP5fur .node circle,#mermaid-svg-Fc5rshxMO2MP5fur .node ellipse,#mermaid-svg-Fc5rshxMO2MP5fur .node polygon,#mermaid-svg-Fc5rshxMO2MP5fur .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Fc5rshxMO2MP5fur .rough-node .label text,#mermaid-svg-Fc5rshxMO2MP5fur .node .label text,#mermaid-svg-Fc5rshxMO2MP5fur .image-shape .label,#mermaid-svg-Fc5rshxMO2MP5fur .icon-shape .label{text-anchor:middle;}#mermaid-svg-Fc5rshxMO2MP5fur .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Fc5rshxMO2MP5fur .rough-node .label,#mermaid-svg-Fc5rshxMO2MP5fur .node .label,#mermaid-svg-Fc5rshxMO2MP5fur .image-shape .label,#mermaid-svg-Fc5rshxMO2MP5fur .icon-shape .label{text-align:center;}#mermaid-svg-Fc5rshxMO2MP5fur .node.clickable{cursor:pointer;}#mermaid-svg-Fc5rshxMO2MP5fur .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Fc5rshxMO2MP5fur .arrowheadPath{fill:#333333;}#mermaid-svg-Fc5rshxMO2MP5fur .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Fc5rshxMO2MP5fur .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Fc5rshxMO2MP5fur .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Fc5rshxMO2MP5fur .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Fc5rshxMO2MP5fur .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Fc5rshxMO2MP5fur .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Fc5rshxMO2MP5fur .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Fc5rshxMO2MP5fur .cluster text{fill:#333;}#mermaid-svg-Fc5rshxMO2MP5fur .cluster span{color:#333;}#mermaid-svg-Fc5rshxMO2MP5fur 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-Fc5rshxMO2MP5fur .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Fc5rshxMO2MP5fur rect.text{fill:none;stroke-width:0;}#mermaid-svg-Fc5rshxMO2MP5fur .icon-shape,#mermaid-svg-Fc5rshxMO2MP5fur .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Fc5rshxMO2MP5fur .icon-shape p,#mermaid-svg-Fc5rshxMO2MP5fur .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Fc5rshxMO2MP5fur .icon-shape .label rect,#mermaid-svg-Fc5rshxMO2MP5fur .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Fc5rshxMO2MP5fur .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Fc5rshxMO2MP5fur .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Fc5rshxMO2MP5fur :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 失败
成功
move
look
talk_npc
attack
skill
shop / buy / sell
guild / pvp / pet
unknown
POST /api/game/action

{ playerId, command, dialogueHistory }
验证参数
400 缺少参数
从 DB 加载玩家数据

加载当前场景
parseCommand(command)

解析指令为 GameAction
action.type 分发
🚶 移动处理器

canMove → 更新位置
👁️ 场景查看

读取 Location 描述
💬 NPC对话

AI生成回复
⚔️ 战斗处理器

calcDamage 回合制
✨ 技能子系统处理器

43种技能路由
🛒 商店/经济处理器
🏛️ 帮派/PVP/宠物处理器
🤖 AI 自由文本处理

aiChatCompletion()
💾 更新 Player 数据

记录日志
✅ 返回 JSON

{ player, scene, message,

items, quests, ... }

5.3 响应数据结构

typescript 复制代码
interface ActionResponse {
  // 核心数据(始终返回)
  player: PlayerData;
  scene: SceneData;
  message: string;
  messages: GameMessage[];
  
  // 条件数据(按需返回)
  items?: PlayerItem[];           // 背包变更时
  battle?: BattleState;           // 战斗中
  dialogueNpc?: NpcInfo;          // 对话中
  questUpdate?: QuestUpdate;      // 任务更新时
  achievement?: AchievementInfo;  // 成就解锁时
  skillResult?: SkillResult;      // 技能使用时
  eventChoices?: EventChoice[];   // 随机事件选项
  
  // 面板数据(按需返回)
  mailResult?: MailData;          // 邮件系统
  petResult?: PetData;            // 宠物系统
  guildResult?: GuildData;        // 帮派系统
  pvpResult?: PvpData;            // PVP系统
  // ... 30+ 面板数据字段
}

6. 前端架构设计

6.1 组件树

#mermaid-svg-jr66daPnIYWaKJjO{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-jr66daPnIYWaKJjO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jr66daPnIYWaKJjO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jr66daPnIYWaKJjO .error-icon{fill:#552222;}#mermaid-svg-jr66daPnIYWaKJjO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jr66daPnIYWaKJjO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jr66daPnIYWaKJjO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jr66daPnIYWaKJjO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jr66daPnIYWaKJjO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jr66daPnIYWaKJjO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jr66daPnIYWaKJjO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jr66daPnIYWaKJjO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jr66daPnIYWaKJjO .marker.cross{stroke:#333333;}#mermaid-svg-jr66daPnIYWaKJjO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jr66daPnIYWaKJjO p{margin:0;}#mermaid-svg-jr66daPnIYWaKJjO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-jr66daPnIYWaKJjO .cluster-label text{fill:#333;}#mermaid-svg-jr66daPnIYWaKJjO .cluster-label span{color:#333;}#mermaid-svg-jr66daPnIYWaKJjO .cluster-label span p{background-color:transparent;}#mermaid-svg-jr66daPnIYWaKJjO .label text,#mermaid-svg-jr66daPnIYWaKJjO span{fill:#333;color:#333;}#mermaid-svg-jr66daPnIYWaKJjO .node rect,#mermaid-svg-jr66daPnIYWaKJjO .node circle,#mermaid-svg-jr66daPnIYWaKJjO .node ellipse,#mermaid-svg-jr66daPnIYWaKJjO .node polygon,#mermaid-svg-jr66daPnIYWaKJjO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jr66daPnIYWaKJjO .rough-node .label text,#mermaid-svg-jr66daPnIYWaKJjO .node .label text,#mermaid-svg-jr66daPnIYWaKJjO .image-shape .label,#mermaid-svg-jr66daPnIYWaKJjO .icon-shape .label{text-anchor:middle;}#mermaid-svg-jr66daPnIYWaKJjO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jr66daPnIYWaKJjO .rough-node .label,#mermaid-svg-jr66daPnIYWaKJjO .node .label,#mermaid-svg-jr66daPnIYWaKJjO .image-shape .label,#mermaid-svg-jr66daPnIYWaKJjO .icon-shape .label{text-align:center;}#mermaid-svg-jr66daPnIYWaKJjO .node.clickable{cursor:pointer;}#mermaid-svg-jr66daPnIYWaKJjO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jr66daPnIYWaKJjO .arrowheadPath{fill:#333333;}#mermaid-svg-jr66daPnIYWaKJjO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jr66daPnIYWaKJjO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jr66daPnIYWaKJjO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jr66daPnIYWaKJjO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jr66daPnIYWaKJjO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jr66daPnIYWaKJjO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jr66daPnIYWaKJjO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jr66daPnIYWaKJjO .cluster text{fill:#333;}#mermaid-svg-jr66daPnIYWaKJjO .cluster span{color:#333;}#mermaid-svg-jr66daPnIYWaKJjO 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-jr66daPnIYWaKJjO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jr66daPnIYWaKJjO rect.text{fill:none;stroke-width:0;}#mermaid-svg-jr66daPnIYWaKJjO .icon-shape,#mermaid-svg-jr66daPnIYWaKJjO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jr66daPnIYWaKJjO .icon-shape p,#mermaid-svg-jr66daPnIYWaKJjO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jr66daPnIYWaKJjO .icon-shape .label rect,#mermaid-svg-jr66daPnIYWaKJjO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jr66daPnIYWaKJjO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jr66daPnIYWaKJjO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jr66daPnIYWaKJjO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} GamePage 主组件

~6,000行 / 60+ useState
标题画面

角色创建
游戏画面
职业选择

武夫/书生/游侠/医者
角色名输入
左侧面板
中央消息流
底部输入栏
小地图 (Sheet)
状态面板

属性/HP/MP/EXP
背包面板

物品/装备
技能面板

43个技能进度
合成面板
消息列表

ScrollArea
战斗横幅

胜利/失败/平局
事件选项

1-4 个按钮
命令输入框

  • 快捷指令按钮
    弹窗/Overlay层

30+ 面板
邮件面板
宠物面板
帮派面板
PVP面板
悬赏面板
藏宝图面板
... +25 more

6.2 核心状态管理

#mermaid-svg-XdrANIxUexGAfaNT{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-XdrANIxUexGAfaNT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XdrANIxUexGAfaNT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XdrANIxUexGAfaNT .error-icon{fill:#552222;}#mermaid-svg-XdrANIxUexGAfaNT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XdrANIxUexGAfaNT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XdrANIxUexGAfaNT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XdrANIxUexGAfaNT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XdrANIxUexGAfaNT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XdrANIxUexGAfaNT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XdrANIxUexGAfaNT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XdrANIxUexGAfaNT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XdrANIxUexGAfaNT .marker.cross{stroke:#333333;}#mermaid-svg-XdrANIxUexGAfaNT svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XdrANIxUexGAfaNT p{margin:0;}#mermaid-svg-XdrANIxUexGAfaNT defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-XdrANIxUexGAfaNT g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-XdrANIxUexGAfaNT g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-XdrANIxUexGAfaNT g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-XdrANIxUexGAfaNT g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-XdrANIxUexGAfaNT g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-XdrANIxUexGAfaNT .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-XdrANIxUexGAfaNT .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-XdrANIxUexGAfaNT .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-XdrANIxUexGAfaNT .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-XdrANIxUexGAfaNT .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-XdrANIxUexGAfaNT .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-XdrANIxUexGAfaNT .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-XdrANIxUexGAfaNT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XdrANIxUexGAfaNT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XdrANIxUexGAfaNT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XdrANIxUexGAfaNT .edgeLabel .label text{fill:#333;}#mermaid-svg-XdrANIxUexGAfaNT .label div .edgeLabel{color:#333;}#mermaid-svg-XdrANIxUexGAfaNT .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-XdrANIxUexGAfaNT .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-XdrANIxUexGAfaNT .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-XdrANIxUexGAfaNT .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-XdrANIxUexGAfaNT .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-XdrANIxUexGAfaNT .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XdrANIxUexGAfaNT .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XdrANIxUexGAfaNT #statediagram-barbEnd{fill:#333333;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XdrANIxUexGAfaNT .cluster-label,#mermaid-svg-XdrANIxUexGAfaNT .nodeLabel{color:#131300;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-XdrANIxUexGAfaNT .note-edge{stroke-dasharray:5;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-note text{fill:black;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram-note .nodeLabel{color:black;}#mermaid-svg-XdrANIxUexGAfaNT .statediagram .edgeLabel{color:red;}#mermaid-svg-XdrANIxUexGAfaNT #dependencyStart,#mermaid-svg-XdrANIxUexGAfaNT #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-XdrANIxUexGAfaNT .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XdrANIxUexGAfaNT :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 启动
点击"开始游戏"
创建成功
退出游戏
title
creating
input_name
select_profession
submit
playing
触发战斗
发送指令
收到响应
战斗结束
触发事件
事件完成
loading
battle
idle
show_status
show_inventory
show_skills
show_map
show_news
show_mail
show_pet
show_guild
event

6.3 消息类型系统

消息类型 CSS 类 图标 用途
system .message-system ⚙️ 系统提示、状态变更
narrative .message-narrative 📜 AI 生成的场景叙事
dialogue .message-dialogue 💬 NPC 对话内容
action .message-action ⚔️ 玩家行动反馈
battle .message-battle 战斗日志
error .message-error 错误提示
success .message-success 成功提示
info .message-info ℹ️ 信息提示
rumor .message-rumor 📰 江湖传闻
mentor .message-mentor 🎓 师徒相关

6.4 视觉主题

主题变量 用途
--color-ink #2c1810 主文字色
--color-parchment #f5e6c8 羊皮纸背景
--color-blood #8b1a1a 战斗/警告色
--color-gold #c9a84c 成就/稀有物品
--color-jade #2d6a4f 成功/治疗
--color-muted-foreground #ccc0b0 辅助文字

相关推荐
AI客栈1 小时前
Go Channel 事件分发:K8s 控制器升级零中断实践
人工智能
Bruce_Liuxiaowei2 小时前
Prompt注入_我的AI编码助手被策反了
人工智能·ai·prompt·提示词·智能体
CryptoPP2 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链
米小虾2 小时前
AI Agent 上下文管理实战:让你的智能体不再"失忆"
人工智能·agent
凌云拓界2 小时前
文件管理:让AI安全操作你的电脑 ——CogitoAgent开发实战(三)
javascript·人工智能·架构·开源·node.js
火山引擎开发者社区2 小时前
Viking AI 搜索 CLI 正式发布:会说话,就能做搜索推荐
人工智能
云烟成雨TD3 小时前
Spring AI 1.x 系列【51】可观测性技术选型
java·人工智能·spring
unicrom_深圳市由你创科技3 小时前
基于Spring AI框架的RAG应用
人工智能·spring·机器学习