# 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**: 中央数据注册表,加载 24 个 JSON 文件,监听 `mod:dataResolved` 事件 - **19 个数据域**: items, armor, enemies, races, skills, perkTrees, spells, shouts, standingStones, quests, recipes, enchantments, soulGems, smithing, cooking, dialogue, transforms, vampireStages, gameConfig - **JSON 数据文件** (24 个): - `src/data/items/` — items.json, weapons.json, armor.json, enchantments.json, soul-gems.json - `src/data/spells/` — spells.json, shouts.json - `src/data/enemies/` — enemies.json - `src/data/quests/` — quests.json - `src/data/races/` — races.json - `src/data/skills/` — skills.json, perks.json, werewolf-perks.json, vampire-perks.json - `src/data/world/` — standing-stones.json - `src/data/alchemy/` — ingredients.json, potions.json - `src/data/crafting/` — smithing.json, cooking.json - `src/data/dialogue/` — trees.json - `src/data/transforms.json`, `vampire-stages.json`, `game-config.json` - **系统数据驱动化**: 11 个游戏系统全部从 DataRegistry 读取数据,不再硬编码: - MagicSystem, CombatSystem, LevelingSystem, RegenSystem - EnchantingSystem, SmithingSystem, AlchemySystem, CookingSystem - TransformationSystem, VampireSystem, DialogueSystem - **循环依赖解决**: CombatSystem/MagicSystem/QuestSystem/DialogueSystem 通过 `globalThis` 注册,ScriptContext lazy 访问 - **地图数据**: 由 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 格式: `ModPackage` (manifest + data + scripts),通过 `modLoader.loadMod()` 加载 - 加载方式: 深度合并,按 priority 排序后加载,后加载覆盖先加载 - 依赖检查: `manifest.dependencies` 声明前置依赖,未满足则拒绝加载 - 冲突检测: 同域同 ID 多个 Mod 声明冲突,最后一个赢 - 事件钩子: `mod:loaded`, `mod:dataResolved` 事件 - Mod 管理器: 启用/禁用/排序/冲突检测 - **19 个数据域全部可覆盖**: items, armor, enemies, races, skills, perkTrees, spells, shouts, standingStones, quests, recipes, enchantments, soulGems, smithing, cooking, dialogue, transforms, vampireStages, gameConfig - **E2E 测试验证**: `src/mods/ModE2E.test.ts` — 10 个测试覆盖数据覆盖、新数据添加、优先级排序、依赖检查、系统热重载 ## 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 加载时注册脚本定义