281 lines
11 KiB
Markdown
281 lines
11 KiB
Markdown
# OES-WEB - 上古卷轴 Web 版
|
|
|
|
## Overview
|
|
用 AI 工具开发的 Web 版《上古卷轴》风格 RPG 游戏。2D 俯视角,极简像素/色块美术,重点是系统完整性和 Mod 生态。
|
|
当前阶段: Phase 3 完成,进入 Phase 4 内容扩展。
|
|
|
|
## Tech Stack
|
|
- Language: TypeScript 5.x (strict mode)
|
|
- Framework: Phaser 3.8x (2D game framework)
|
|
- Build: Vite 6
|
|
- Testing: Vitest
|
|
- Persistence: Dexie.js (IndexedDB) + fflate 压缩
|
|
- Audio: Howler.js
|
|
- UI: HTML/CSS overlay on Phaser canvas
|
|
|
|
## Commands
|
|
- `npm run dev` -- 启动开发服务器 (localhost:5173, 热重载)
|
|
- `npm run build` -- 生产构建到 dist/
|
|
- `npm run test` -- 运行测试
|
|
- `npx tsc --noEmit` -- TypeScript 类型检查
|
|
|
|
## Project Structure
|
|
```
|
|
src/
|
|
├── core/ # GameManager, EventBus, EntityManager (核心单例)
|
|
├── components/ # 数据组件 (Health, Combat, Skills...)
|
|
├── systems/ # 游戏系统 (Combat, Magic, Quest...)
|
|
├── scenes/ # Phaser 场景 (GameScene, MenuScene...)
|
|
├── entities/ # 实体工厂 (Player, NPC, Enemy...)
|
|
├── ai/ # AI 控制器和行为树
|
|
├── ui/ # HTML/CSS UI 组件
|
|
│ └── components/ # HUD, Inventory, DialogueUI...
|
|
├── data/ # JSON 游戏数据 (物品/法术/任务/NPC)
|
|
├── mechanics/ # 计算公式 (伤害/技能/炼金...)
|
|
├── save/ # 存档系统 (Dexie.js)
|
|
├── maps/ # 地图管理
|
|
├── mods/ # Mod 系统 (ModLoader, ModManager)
|
|
└── utils/ # 工具函数
|
|
```
|
|
|
|
## Architecture
|
|
- **Entity-Component 模式**: 实体是 ID,组件是数据,系统操作组件
|
|
- **EventBus 事件总线**: 系统间解耦通信,不直接调用
|
|
- **GameManager 单例**: 初始化所有系统,管理主循环
|
|
- **DataRegistry 数据注册表**: 所有游戏数据通过 DataRegistry 加载,支持 Mod 覆盖
|
|
- **系统执行顺序**: Input → AI → Physics → Combat → Magic → Stealth → StatusEffect → Inventory → Corpse → ItemInteraction → Quest → Dialogue → Animation → Spawn → ModHook → Save
|
|
|
|
## Data Architecture (全部可 Mod 覆盖)
|
|
所有游戏数据通过 `DataRegistry` 统一加载和管理。Mod 可覆盖任何数据类型:
|
|
- **DataRegistry**: 中央数据注册表,加载 JSON 文件,监听 `mod:dataResolved` 事件
|
|
- **数据类型**: items, weapons, armor, enemies, quests, races, skills, perks, standingStones, spells, recipes
|
|
- **地图数据**: 由 MapManager 从 `zones.json` 加载,支持 Mod 覆盖
|
|
- **UI 组件**: CharacterCreationUI/SkillTreeUI 从 DataRegistry 读取数据,不再直接导入 JSON
|
|
|
|
## Conventions
|
|
- TypeScript strict mode,不用 `any`,用 `unknown` 然后窄化
|
|
- 组件必须有 `type` 字段作为标识
|
|
- 所有时间值用毫秒,delta-time 从游戏时钟获取
|
|
- 实体位置用浮点数,渲染时四舍五入
|
|
- 文件命名: 组件 PascalCase,工具 camelCase,资源 kebab-case
|
|
- 测试文件: `*.test.ts` 或 `*.spec.ts`
|
|
|
|
## Do Not
|
|
- 不要修改 `src/core/` 下的核心模块除非运行完整测试
|
|
- 不要添加外部依赖未经讨论
|
|
- 不要硬编码屏幕尺寸
|
|
- 不要直接 fetch 资源,通过 AssetManager
|
|
- 不要在游戏循环中产生不必要的对象分配
|
|
- 不要跳过 TypeScript 类型检查直接提交
|
|
|
|
## Development Progress
|
|
|
|
### Phase 0: 项目脚手架 ✅
|
|
- Vite + TypeScript + Phaser 3 配置
|
|
- GameManager, EventBus, EntityManager 核心模块
|
|
- 基础游戏场景和 UI 覆盖层
|
|
- IndexedDB 存档系统骨架
|
|
|
|
### Phase 1: 核心角色系统 ✅
|
|
- 10 个可玩种族 (Nord, Dunmer, Altmer, Argonian, Khajiit, Breton, Imperial, Redguard, Orc, Bosmer)
|
|
- 角色创建界面 (选种族、命名)
|
|
- 生命/魔力/耐力三大属性系统
|
|
- 18 项技能和 XP 追踪
|
|
- 升级系统 (每 10 级技能 = 1 角色等级)
|
|
- **18 棵完整天赋树** (251 个天赋)
|
|
- 种族能力和被动
|
|
- 13 个站立之石
|
|
- 存档/读档角色数据
|
|
|
|
### Phase 2: 基础战斗系统 ✅
|
|
- 实时动作战斗 (鼠标左键攻击)
|
|
- 单手/双手武器系统
|
|
- 盾牌格挡 (右键按住)
|
|
- 强力攻击 (Shift)
|
|
- 暴击系统 (10% 基础 + 潜行加成)
|
|
- 5 种敌人类型 (强盗/狼/骷髅/熊/蜘蛛) + 7 种新敌人 (尸鬼/尸鬼亡灵/洞穴熊/冰霜蜘蛛/强盗逃犯/强盗暴徒/死灵法师)
|
|
- 敌人 AI (追逐/攻击)
|
|
- 玩家死亡和复活
|
|
- 战斗音效和视觉反馈
|
|
- 状态效果系统
|
|
- 回血/回魔/回耐力系统
|
|
|
|
### Phase 3: 探索与世界 ✅
|
|
- 地图系统 (7 个区域)
|
|
- 白漫城 (城市)
|
|
- 白漫城外 (平原)
|
|
- 荒瀑古坟 (地牢)
|
|
- 溪木镇 (村庄)
|
|
- 暗光洞穴 (地牢)
|
|
- 古代遗迹 (地牢)
|
|
- 天际省荒野 (世界地图)
|
|
- 门和区域过渡
|
|
- 宝箱容器系统
|
|
- 地面物品拾取
|
|
- 快速旅行
|
|
- 世界地图 UI
|
|
- 昼夜循环系统
|
|
- 物品交互 (悬停提示/使用/装备)
|
|
- 收藏/快捷栏系统
|
|
|
|
### Phase 4: NPC 与对话 ✅ (基础)
|
|
- NPC 实体和闲置行为
|
|
- 分支对话系统
|
|
- 商人买卖界面
|
|
- 每个城市的 NPC
|
|
- Speech 技能检定
|
|
- 随从招募系统
|
|
|
|
### Phase 5: 扩展战斗与魔法 ✅ (基础)
|
|
- 5 大魔法学派基础法术
|
|
- 法术施放 UI
|
|
- 潜行攻击倍率
|
|
- 完整潜行/检测系统
|
|
- 龙吼系统
|
|
- 尸体系统 (状态机/搜刮/复生)
|
|
|
|
### Phase 6: 制作系统 ✅ (基础)
|
|
- 炼金系统 (材料效果/组合/药水/毒药)
|
|
- 附魔系统 (分解/附魔/灵魂石)
|
|
- 锻造系统 (锻造台/砂轮)
|
|
- 烹饪系统
|
|
|
|
### Phase 7: 任务系统 ✅ (基础)
|
|
- 任务状态机 (开始/目标/完成/失败)
|
|
- 任务日志 UI
|
|
- 主线任务 (3 个)
|
|
- 公会任务线 (战士/盗贼)
|
|
- 魔神任务 (1 个)
|
|
- 辐射任务 (3 个)
|
|
|
|
### Phase 8: 高级系统 🔄
|
|
- **狼人变形** ✅:
|
|
- TransformationSystem: form 组件管理变形状态
|
|
- T 键切换狼人/吸血鬼领主形态
|
|
- 形态加成: 生命+100, 耐力+50, 护甲+10, 移速+60, 爪击伤害 20
|
|
- 变形时替换武器为形态武器,修改精灵外观
|
|
- 形态有时限 (120s) + 冷却 (30s)
|
|
- 狼人专属天赋树 (6 个天赋: 野兽之力/厚皮毛/疾跑/恐惧嚎叫/野性恢复/月圆之夜)
|
|
- **吸血鬼系统** ✅:
|
|
- VampireSystem: 4 阶段感染进度
|
|
- 白天惩罚 (阳光伤害) + 夜间增益 (属性加成)
|
|
- 吸血回复机制
|
|
- 吸血鬼专属天赋树 (6 个天赋: 暗夜视觉/冰霜亲和/生命虹吸/暗夜潜行/血魔法/远古血脉)
|
|
- **传奇技能** ✅:
|
|
- LegendarySystem: 技能 100 后可传奇重置
|
|
- 归零 + 获得 1 天赋点 + 传奇次数 +1
|
|
- 每次传奇该技能获得 +10% XP 加成
|
|
- 阵营声望 (数据已定义)
|
|
- 结婚系统 (待实现)
|
|
|
|
### Phase 8.5: Mod 系统 ✅
|
|
- JSON 数据覆盖加载器
|
|
- 加载优先级系统
|
|
- 插件清单格式 (manifest.json)
|
|
- 事件钩子 API
|
|
- Mod 管理器 UI
|
|
- 依赖检查和冲突检测
|
|
- 示例 Mod (武器/任务)
|
|
- **实体脚本系统** (与原版上古卷轴一致):
|
|
- 脚本定义: properties (持久化变量) + handlers (JS 代码字符串)
|
|
- 生命周期事件: OnLoad, OnUpdate, OnHit, OnDeath, OnActivate, OnUnload, OnEquip, OnUse, OnZoneEnter, OnZoneLeave
|
|
- 沙箱化上下文 API: entity, inventory, combat, magic, dialogue, quest, effects, prop, time, entities, events, data, log
|
|
- ScriptSystem 集成到游戏循环,自动调用 OnUpdate 和事件转发
|
|
- 实体通过 `data.script` 字段挂载脚本
|
|
|
|
### Phase 9: 内容与打磨 🔄
|
|
- 30+ 种敌人 (已完成)
|
|
- 7 个区域 (已完成)
|
|
- 18 棵天赋树 (已完成)
|
|
- 11 个任务 (已完成)
|
|
- 昼夜循环 (已完成)
|
|
- 待完成: 更多地图、更多任务、UI 打磨、音频集成
|
|
|
|
### Phase 10: 最终集成 ⏳
|
|
- 端到端测试
|
|
- 平衡调整
|
|
- 构建优化
|
|
|
|
## Game Content Summary
|
|
- **种族**: 10 个
|
|
- **敌人**: 12 种 (强盗/狼/骷髅/尸鬼/尸鬼亡灵/熊/洞穴熊/蜘蛛/冰霜蜘蛛/强盗逃犯/强盗暴徒/死灵法师)
|
|
- **区域**: 7 个 (白漫城/白漫城外/荒瀑古坟/溪木镇/暗光洞穴/古代遗迹/天际省荒野)
|
|
- **天赋树**: 20 棵 (18 技能 + 狼人 + 吸血鬼, 263 个天赋)
|
|
- **任务**: 11 个 (3 主线/2 战士公会/1 盗贼公会/1 魔神/3 辐射/1 采药)
|
|
- **武器**: 15 种 (铁/钢各 tier)
|
|
- **护甲**: 27 件 (铁/钢/皮革/精灵/兽人/乌木/魔族/龙)
|
|
- **物品**: 28 种 (消耗品/材料/杂物)
|
|
- **法术**: 多种 (毁灭/恢复/召唤/变化)
|
|
- **站立之石**: 13 个
|
|
- **变形形态**: 2 种 (狼人/吸血鬼领主)
|
|
- **高级系统**: 狼人变形 + 吸血鬼感染 + 传奇技能
|
|
|
|
## Mod 生态
|
|
- Mod 格式: JSON 数据文件 + manifest.json 清单
|
|
- 加载方式: 深度合并,后加载覆盖先加载
|
|
- 事件钩子: GameEvents.on('event:name', callback)
|
|
- Mod 管理器: 启用/禁用/排序/冲突检测
|
|
- **全部数据可覆盖**: 所有游戏数据 (物品/武器/护甲/敌人/任务/种族/技能/天赋/站立之石/法术/配方/地图) 均通过 DataRegistry 或 MapManager 加载,Mod 可覆盖任何数据
|
|
|
|
## Mod 脚本系统
|
|
Mod 可为游戏实体附加自定义脚本逻辑,与原版上古卷轴的脚本系统一致。
|
|
|
|
### 脚本定义格式 (Mod JSON)
|
|
```json
|
|
{
|
|
"manifest": { "id": "my-mod", "name": "我的 Mod", "version": "1.0.0" },
|
|
"scripts": {
|
|
"guard_patrol": {
|
|
"properties": { "alertLevel": 0, "homeX": 0 },
|
|
"handlers": {
|
|
"OnLoad": "ctx.log('守卫上线');",
|
|
"OnHit": "ctx.prop('alertLevel', ctx.prop('alertLevel') + 1);",
|
|
"OnDeath": "ctx.log('守卫阵亡');"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 实体挂载
|
|
Zone 数据中的实体通过 `data.script` 字段挂载脚本:
|
|
```json
|
|
{ "type": "npc", "data": { "name": "守卫", "script": "my-mod:guard_patrol" } }
|
|
```
|
|
|
|
### 生命周期事件
|
|
| 事件 | 触发时机 | 参数 |
|
|
|------|---------|------|
|
|
| `OnLoad` | 实体创建时 | 无 |
|
|
| `OnUpdate` | 每帧 | `delta` (ms) |
|
|
| `OnHit` | 被攻击时 | `{ attacker, damage, isCritical }` |
|
|
| `OnDeath` | 死亡时 | `{ killer }` |
|
|
| `OnActivate` | 玩家交互时 | `{ player }` |
|
|
| `OnUnload` | 实体销毁时 | 无 |
|
|
| `OnEquip` | 被装备时 | `{ item, slot }` |
|
|
| `OnUse` | 被使用时 | `{ item }` |
|
|
| `OnZoneEnter` | 区域加载时 | `{ zoneId }` |
|
|
|
|
### 沙箱化上下文 API (`ctx`)
|
|
脚本执行时获得 `ctx` 对象,包含:
|
|
- `entity` — 读写生命/魔力/耐力/位置/技能/等级
|
|
- `inventory` — 增删查物品/金币
|
|
- `combat` — 伤害/治疗/击杀
|
|
- `magic` — 施法/学习/查询法术
|
|
- `dialogue` — 启动对话树 (待实现)
|
|
- `quest` — 任务操作 (待实现)
|
|
- `effects` — 应用/移除状态效果
|
|
- `prop` — 持久化自定义变量
|
|
- `time` — 游戏时间查询
|
|
- `entities` — 查询周围实体
|
|
- `events` — 自定义事件监听/触发
|
|
- `data` — 只读查询游戏数据
|
|
- `log` — 调试日志
|
|
|
|
### 关键文件
|
|
- `src/mods/ModTypes.ts` — ScriptDefinition, ScriptInstance 类型
|
|
- `src/mods/ScriptContext.ts` — 沙箱化 API 实现
|
|
- `src/mods/ModScriptEngine.ts` — 脚本编译和实例管理
|
|
- `src/systems/ScriptSystem.ts` — 游戏循环集成
|
|
- `src/mods/ModLoader.ts` — Mod 加载时注册脚本定义
|