diff --git a/App/Program.cs b/App/Program.cs
index ee4de0ca..1c4ecaeb 100644
--- a/App/Program.cs
+++ b/App/Program.cs
@@ -19,7 +19,8 @@ internal static class Program
var options = AppOptions.FromArgs(args);
var baseDirectory = AppPaths.BaseDirectory;
- var moduleStore = new ModuleStore(ModuleStore.ResolveModuleDirectory(baseDirectory));
+ var moduleStore = new ModuleStore(ModuleStore.ResolveModuleDirectory());
+ ShowModuleMigrationHint(baseDirectory, moduleStore);
var triggerKeyState = new WindowsTriggerKeyState();
var processLocator = new WowProcessLocator(baseDirectory);
var runtimeFactory = new ShigureRuntimeFactory(baseDirectory, moduleStore, triggerKeyState, processLocator);
@@ -33,4 +34,37 @@ internal static class Program
processLocator,
runtimeSession));
}
+
+ // 模块目录迁移提示:旧目录(baseDirectory/module)存在且有内容、且新目录(用户配置目录)尚无模块文件时,
+ // 弹一次纯文案提示,引导用户手动移动模块;条件不满足或检测异常时静默,不影响启动。
+ private static void ShowModuleMigrationHint(string baseDirectory, ModuleStore moduleStore)
+ {
+ try
+ {
+ var oldDirectory = Path.Combine(baseDirectory, "module");
+ if (!Directory.Exists(oldDirectory)
+ || !Directory.EnumerateFileSystemEntries(oldDirectory).Any())
+ {
+ return;
+ }
+
+ // 新目录以是否存在模块文件(.json)判空,避免保存崩溃残留的 .tmp 原子写文件阻断提示。
+ if (Directory.EnumerateFiles(moduleStore.ModuleDirectory, "*.json", SearchOption.AllDirectories).Any())
+ {
+ return;
+ }
+
+ MessageBox.Show(
+ $"模块目录已迁移到用户配置目录。\n\n" +
+ $"新的模块目录:\n{moduleStore.ModuleDirectory}\n\n" +
+ $"请将旧目录 {oldDirectory} 中的模块文件手动移动到新目录。",
+ "Shigure",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Information);
+ }
+ catch
+ {
+ // 检测或提示异常时静默跳过,避免影响启动。
+ }
+ }
}
diff --git a/CLAUDE.md b/CLAUDE.md
index b372245a..ae8f5dc3 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -20,7 +20,7 @@ dotnet run --project .\Shigure.csproj -- --toggle XBUTTON2 --mode switch --logic
- **没有测试项目**:验证 = 能编译 + 实际运行点开「设置」走查。`dotnet build` 干净通过(0 警告 0 错误)是基线要求。
- 启动参数见 [README.md](README.md#运行)(`--toggle/--mode/--logic-ms/--render-ms`),解析在 [App/AppOptions.cs](App/AppOptions.cs)。目标进程名来自 `wow_process.txt`。
-程序直接从当前 EXE 所在目录运行;`AppPaths.BaseDirectory` 即 `AppContext.BaseDirectory`,配置、按键映射、模块和插件源码均从该目录读取。
+程序直接从当前 EXE 所在目录运行;`AppPaths.BaseDirectory` 即 `AppContext.BaseDirectory`,配置、按键映射和插件源码均从该目录读取;模块从用户配置目录读取(`ModuleStore.ResolveModuleDirectory()`,见下)。
## 架构与数据流
@@ -53,13 +53,14 @@ Input/ keymap 读取、按键发送、Win32 API
Infrastructure/ 配置读取(ConfigService)、JSON 辅助、UI 缓存、路径、Fuyutsui 插件文件读写
UI/ WinForms 界面、编辑器、主题
Fuyutsui/ 内置插件权威源;构建/发布时完整复制,运行时部署到游戏 AddOns
-config/ keymap/ module/ 运行时 JSON 数据(构建时复制到输出, 见 .csproj 的 None+CopyToOutputDirectory)
+config/ keymap/ 运行时 JSON 数据(构建时复制到输出, 见 .csproj 的 None+CopyToOutputDirectory)
+module 运行时模块数据位于用户配置目录 ~/.config/Shigure/module(启动时自动创建, 不随构建复制)
wow_process.txt 目标游戏进程名列表;构建时复制,运行期间每次定位都会重新读取
```
## 模块解析(改逻辑前必读)
-- 模块以 `module/模块名.json` 平铺保存,**文件名取自模块名,故模块名不可重复**;加载递归扫描子目录。模型在 [Modules/ModuleStore.cs](Modules/ModuleStore.cs)(`ModuleDefinition`/`ModuleMatch`/`ModuleRule`/`ModuleUnit`/`ModuleCountField`/`ModuleValueAdjustment`)。`RecommendedTalent` 是 `ModuleDefinition` 上的纯展示字段,不参与匹配(`ModuleMatch.Specificity` 不计入)。
+- 模块以 `~/.config/Shigure/module/模块名.json` 平铺保存(`ModuleStore.ResolveModuleDirectory()` 返回用户配置目录,`{UserProfile}/.config/{程序集名}/module`),**文件名取自模块名,故模块名不可重复**;加载递归扫描子目录。模型在 [Modules/ModuleStore.cs](Modules/ModuleStore.cs)(`ModuleDefinition`/`ModuleMatch`/`ModuleRule`/`ModuleUnit`/`ModuleCountField`/`ModuleValueAdjustment`)。`RecommendedTalent` 是 `ModuleDefinition` 上的纯展示字段,不参与匹配(`ModuleMatch.Specificity` 不计入)。
- `ModuleStore` 的 `Reload`/`Save`/`Delete` 会在同一个门锁内串行完整文件事务与内存快照更新;`Save` 通过同目录临时文件提交,重命名失败会回滚新文件。编辑器写入不要绕过它,避免运行时读到半次操作。运行时工厂不再自行 `Reload`:启动和模块刷新先由 `ModuleDependencyService` 导入依赖、拒绝宏容量超限模块,再把已验证的内存快照交给运行时。
- 职业/专精明确的模块保存时会写入 `Dependencies` 快照。`ModuleDependencyService` 以本地为优先追加缺失的 ClassBlocks/spellsList/ClassMacros,按动态宏 30 槽、其它宏 1 槽检查所有受影响专精;任一专精超过 keymap 容量就拒绝整个模块且不写 Lua。依赖提交失败会恢复配置和宏原文。
- 选择优先级:`ModuleStore.FindSelectedOrBestMatch` —— 先用 UI/参数选定的 `ModuleId`;否则取 `Match` 命中字段最多者(`ModuleMatch.Specificity` 越大越优先),并列按名称。`Match` 字段留空 = 任意。`PartyType` 数字会归一化为 `"1-40"`。
diff --git a/Infrastructure/AppInfo.cs b/Infrastructure/AppInfo.cs
index 1b2a45d7..5a21abbd 100644
--- a/Infrastructure/AppInfo.cs
+++ b/Infrastructure/AppInfo.cs
@@ -3,11 +3,14 @@ using System.Reflection;
namespace Shigure;
///
-/// 应用版本信息的单一来源。优先取 csproj 的 <Version>(AssemblyInformationalVersion),
-/// 退化到 AssemblyVersion。
+/// 应用名称与版本信息的单一来源:AppName 取自程序集名,
+/// Version 优先取 csproj 的 <Version>(AssemblyInformationalVersion),退化到 AssemblyVersion。
///
internal static class AppInfo
{
+ // 取自程序集名(重命名程序集时自动跟随),与 Version 从程序集读取的惯例一致。
+ public static string AppName { get; } = Assembly.GetExecutingAssembly().GetName().Name ?? "Shigure";
+
public static string Version { get; } = ResolveVersion();
private static string ResolveVersion()
diff --git a/Modules/ModuleStore.cs b/Modules/ModuleStore.cs
index 9fd52f42..aa8a4be2 100644
--- a/Modules/ModuleStore.cs
+++ b/Modules/ModuleStore.cs
@@ -289,15 +289,13 @@ public sealed class ModuleStore
public string ModuleDirectory { get; }
- public static string ResolveModuleDirectory(string baseDirectory)
+ public static string ResolveModuleDirectory()
{
- var currentModuleDirectory = Path.Combine(baseDirectory, "module");
- if (Directory.Exists(currentModuleDirectory) || File.Exists(Path.Combine(baseDirectory, "Shigure.csproj")))
- {
- return currentModuleDirectory;
- }
-
- return Path.Combine(baseDirectory, "module");
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
+ ".config",
+ AppInfo.AppName,
+ "module");
}
public IReadOnlyList GetModules()
diff --git a/Obsidian/30-Shigure/00-Shigure-MOC.md b/Obsidian/30-Shigure/00-Shigure-MOC.md
index 13a1e35e..60a4732f 100644
--- a/Obsidian/30-Shigure/00-Shigure-MOC.md
+++ b/Obsidian/30-Shigure/00-Shigure-MOC.md
@@ -89,7 +89,7 @@ Program.Main
| 状态步骤映射 | ClassBlocks Lua,经转换器生成 | `ConfigService` / `StateBuilder` | `config/*.json` |
| 法术宏到键位 | ClassMacros Lua,经转换器生成 | `KeymapService` | `keymap/*.json` |
| 游戏插件副本 | 项目内置 `Fuyutsui/` | WoW AddOn 加载器 | `Interface/AddOns/Fuyutsui` |
-| 行为规则 | 模块编辑器或手工 JSON | `ModuleStore` / `ModuleLogic` | `module/*.json` |
+| 行为规则 | 模块编辑器或手工 JSON | `ModuleStore` / `ModuleLogic` | `~/.config/Shigure/module` |
| UI 缓存与偏好 | WinForms 界面 | WinForms 界面 | `cache/` |
| 运行状态 | `ShigureRuntime` 单循环 | `StatusForm` | `RenderSnapshot`,不持久化 |
diff --git a/Obsidian/30-Shigure/01-Shigure-启动随机副本与会话协调.md b/Obsidian/30-Shigure/01-Shigure-启动随机副本与会话协调.md
index f3f6edf5..7caf5562 100644
--- a/Obsidian/30-Shigure/01-Shigure-启动随机副本与会话协调.md
+++ b/Obsidian/30-Shigure/01-Shigure-启动随机副本与会话协调.md
@@ -73,7 +73,7 @@ verified_at: 2026-08-10
## 核心数据与不变量
-- 随机子进程**不复制业务数据目录**;`config`、`keymap`、`module`、`cache` 仍由原始根目录提供。
+- 随机子进程**不复制业务数据目录**;`config`、`keymap`、`cache` 仍由原始根目录提供,模块由用户配置目录 `~/.config/Shigure/module` 提供。
- `SHIGURE_RANDOMIZED_PROCESS=1` 是防递归开关。外部若伪造相关环境变量,也会改变启动和路径行为。
- 清理范围是按源 EXE 路径哈希隔离的专属临时根目录;清理会递归删除其所有子项并吞掉 IO/权限异常。
- 每次会话构造新的 `ConfigService`、`KeymapService`、`PixelScanner`、`StateBuilder`、`KeySender` 和 `LogicRegistry`;`ModuleStore` 与触发键读取器跨会话共享。
diff --git a/Obsidian/30-Shigure/10-Shigure-UI功能地图与数据所有权.md b/Obsidian/30-Shigure/10-Shigure-UI功能地图与数据所有权.md
index 2c22d397..8f4d0b92 100644
--- a/Obsidian/30-Shigure/10-Shigure-UI功能地图与数据所有权.md
+++ b/Obsidian/30-Shigure/10-Shigure-UI功能地图与数据所有权.md
@@ -56,7 +56,7 @@ verified_at: 2026-08-10
| `MainForm` 浮条 | 启停、打开设置/状态、关闭、拖动 | 会话状态、UI 缓存 | `SetEnabled`、重启/停止、窗口偏好 |
| 通用设置 | 触发键、模式、模块选择、配置生成与插件部署 | `AppOptions`、模块目录、项目 Fuyutsui | 缓存/设置、会话重启、同步队列 |
| `StatusForm` | 九个状态/诊断页 | `RenderSnapshot`、日志 | 不拥有运行状态 |
-| 模块编辑器 | 匹配、规则、动态单位、数量、调整/公式、排序 | 模块快照 | `module/*.json` |
+| 模块编辑器 | 匹配、规则、动态单位、数量、调整/公式、排序 | 模块快照 | `~/.config/Shigure/module` |
| ClassBlocks 编辑器 | 职业/专精状态块编辑 | `Fuyutsui/class/*.lua` 项目源 | ClassBlocks table、config、当前 Lua 游戏部署 |
| ClassMacros 编辑器 | common/spec/static/special 宏编辑 | `Fuyutsui/core/classmacros.lua` 项目源 | ClassMacros table、keymap、当前 Lua 游戏部署 |
| 条件/单位对话框 | 构造受限条件和动态定义 | 当前草稿 | 返回编辑器内存模型 |
diff --git a/Obsidian/30-Shigure/11-Shigure-本地数据路径构建与验证.md b/Obsidian/30-Shigure/11-Shigure-本地数据路径构建与验证.md
index 0f49d4ff..48458957 100644
--- a/Obsidian/30-Shigure/11-Shigure-本地数据路径构建与验证.md
+++ b/Obsidian/30-Shigure/11-Shigure-本地数据路径构建与验证.md
@@ -41,7 +41,7 @@ verified_at: 2026-08-10
# Shigure 本地数据、路径、构建与验证
> [!abstract] AI 快速摘要
-> Shigure 的业务根目录通常是正式 EXE 所在目录;随机副本子进程通过环境变量仍指回该目录。程序从这里读取内置 `Fuyutsui/`、`config`、`keymap`、`module`、`cache` 和 `wow_process.txt`。项目插件是权威源,目标游戏中的 Fuyutsui 只是由部署服务维护的运行副本。项目是无第三方 NuGet 引用的 `net10.0-windows` WinForms WinExe,仓库没有测试项目。
+> Shigure 的业务根目录通常是正式 EXE 所在目录;随机副本子进程通过环境变量仍指回该目录。程序从这里读取内置 `Fuyutsui/`、`config`、`keymap`、`cache` 和 `wow_process.txt`;模块从用户配置目录 `~/.config/Shigure/module` 读取。项目插件是权威源,目标游戏中的 Fuyutsui 只是由部署服务维护的运行副本。项目是无第三方 NuGet 引用的 `net10.0-windows` WinForms WinExe,仓库没有测试项目。
## 图谱位置
@@ -65,7 +65,7 @@ verified_at: 2026-08-10
AppContext.BaseDirectory = 随机临时目录(仅运行依赖)
```
-这使随机 EXE 可以加载临时目录 DLL,同时配置和用户数据仍落在正式安装目录。环境变量属于信任边界:若外部预先设置/篡改,可能改变业务数据根目录。
+这使随机 EXE 可以加载临时目录 DLL,同时配置、Keymap 和缓存等数据仍落在正式安装目录;模块则在用户配置目录(子进程与父进程同属一个 Windows 用户,解析结果一致)。环境变量属于信任边界:若外部预先设置/篡改,可能改变业务数据根目录。
## 本地数据地图
@@ -74,7 +74,7 @@ verified_at: 2026-08-10
| `config/common.json` | 协议固定字段 | `ConfigService` | 打包内容/人工维护 |
| `config/.json` | 13 职业和专精步骤映射、法术元数据 | `ConfigService`, `StateBuilder` | `FuyutsuiConfigConverter` |
| `keymap/*.json` | unit/spell/macroCondition→hotkey | `KeymapService`, `KeymapCatalog` | `FuyutsuiKeymapConverter` |
-| `module/**/*.json` | 匹配、规则、动态值和公式 | `ModuleStore` | 模块编辑器/人工 |
+| `~/.config/Shigure/module/**/*.json` | 匹配、规则、动态值和公式 | `ModuleStore` | 模块编辑器/人工 |
| `cache/` | 窗口和 UI 偏好 | UI 基础设施 | MainForm/各 UI |
| `Fuyutsui/class/*.lua` | 内置 ClassBlocks 权威源 | ClassBlocks Store/转换器 | ClassBlocks 编辑器/人工 |
| `Fuyutsui/core/classmacros.lua` | 内置宏权威源 | ClassMacros Store/转换器 | 宏编辑器/人工 |
@@ -99,7 +99,7 @@ verified_at: 2026-08-10
- 开启 nullable 与 implicit usings。
- 应用版本在项目文件中为 1.2.1,并被模块编辑器保存到模块元数据。
- 项目没有 `PackageReference`;核心只依赖 .NET/WinForms/System.Drawing 和 Win32 P/Invoke。
-- 项目文件声明嵌入 UI assets,并把 `Fuyutsui/**`、配置、Keymap、模块和 `wow_process.txt` 按规则复制到输出;Fuyutsui 同时明确复制到 publish。
+- 项目文件声明嵌入 UI assets,并把 `Fuyutsui/**`、配置、Keymap 和 `wow_process.txt` 按规则复制到输出;Fuyutsui 同时明确复制到 publish。模块不随构建/发布复制,由用户配置目录 `~/.config/Shigure/module` 提供。
- 实际打包策略还应对照 `打包说明.md`;随机启动器只复制正式输出目录**顶层**运行依赖到临时目录。
## 当前验证能力
diff --git a/README.md b/README.md
index 05b7a5c8..b3a92b3c 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ Shigure 是一个 Windows WinForms 桌面程序。它从目标窗口读取 Fuyut
- `日志`:记录启动、停止、职业识别、模块匹配、逻辑状态、施放步骤、配置同步和异常。
- `关于`:显示产品、公司、版本、模块目录和配置目录。
-触发键、发送模式、模块选择、模块保存以及配置同步都会按需重启运行循环。窗口位置、大小、模块选择和表格列宽等 UI 状态保存在 `cache/window-state.json`。`module/` 与 `cache/` 都是本地数据,默认不提交到 Git。
+触发键、发送模式、模块选择、模块保存以及配置同步都会按需重启运行循环。窗口位置、大小、模块选择和表格列宽等 UI 状态保存在 `cache/window-state.json`;模块保存在用户配置目录 `~/.config/Shigure/module`。`cache/` 与模块数据都是本地数据,默认不提交到 Git。
## 环境要求
@@ -87,7 +87,7 @@ dotnet run --project .\Shigure.csproj -- --toggle XBUTTON2 --mode switch --logic
- `click`:每次按下只执行一轮逻辑。
- `hold`:按住时运行,松开后停止。
-程序会直接从当前 EXE 所在目录运行,并从该目录读取 `Fuyutsui/`、`config/`、`keymap/`、`module/` 和 `wow_process.txt`。
+程序会直接从当前 EXE 所在目录运行,并从该目录读取 `Fuyutsui/`、`config/`、`keymap/` 和 `wow_process.txt`;模块从用户配置目录 `~/.config/Shigure/module` 读取。
## 构建
@@ -95,7 +95,7 @@ dotnet run --project .\Shigure.csproj -- --toggle XBUTTON2 --mode switch --logic
dotnet build .\Shigure.csproj
```
-应用图标为 `Assets\arasaka-icon.ico`。项目会把 `Fuyutsui/**`、`config/*.json`、`keymap/*.json`、本地 `module/**/*.json` 和 `wow_process.txt` 复制到输出/发布目录;图标、职业图和专精图作为嵌入资源打包。
+应用图标为 `Assets\arasaka-icon.ico`。项目会把 `Fuyutsui/**`、`config/*.json`、`keymap/*.json` 和 `wow_process.txt` 复制到输出/发布目录;图标、职业图和专精图作为嵌入资源打包。
## 项目结构
@@ -111,7 +111,7 @@ Assets\ 应用图标、品牌资源、职业图和专精图
Fuyutsui\ 权威插件源码、配置/宏编辑源及游戏部署源
config\ 由 Fuyutsui 职业配置生成的扫描映射
keymap\ 由 Fuyutsui 职业宏生成的按键映射
-module\ 本地模块(运行后或在 UI 中保存时创建)
+module\ 模块示例模板(运行时模块保存在用户配置目录 `~/.config/Shigure/module`)
Tools\ 辅助脚本
```
@@ -159,9 +159,9 @@ Tools\ 辅助脚本
## 模块系统
-模块以 `模块名.json` 保存在 `module/`。名称不能重复;加载时会递归扫描子目录,以兼容旧版布局。模块页保存时会写入当前 Shigure 版本。职业和专精均已指定时,模块还会携带该专精的 `ClassBlocks`、职业 `spellsList`,以及该职业的通用/专精动态宏、静态宏和特殊宏;旧模块没有这些依赖信息时仍可正常使用。
+模块以 `模块名.json` 保存在用户配置目录 `~/.config/Shigure/module`。名称不能重复;加载时会递归扫描子目录,以兼容旧版布局。模块页保存时会写入当前 Shigure 版本。职业和专精均已指定时,模块还会携带该专精的 `ClassBlocks`、职业 `spellsList`,以及该职业的通用/专精动态宏、静态宏和特殊宏;旧模块没有这些依赖信息时仍可正常使用。
-启动和“刷新模块”会把模块携带而本地缺少的配置与宏追加到项目 `Fuyutsui/`,不会覆盖或删除本地已有条目。发生新增后会自动重建 `config/keymap`、同步游戏插件并按需重启运行。导入前会按每项动态宏 30 个槽位、静态/特殊宏各 1 个槽位检查该职业所有受影响专精;合并结果超过 273 个槽位时,整个模块不会进入模块列表或运行时,本地 Lua 也不会被修改。模块文件仍保留在 `module/`,清理宏后可刷新重试。
+启动和“刷新模块”会把模块携带而本地缺少的配置与宏追加到项目 `Fuyutsui/`,不会覆盖或删除本地已有条目。发生新增后会自动重建 `config/keymap`、同步游戏插件并按需重启运行。导入前会按每项动态宏 30 个槽位、静态/特殊宏各 1 个槽位检查该职业所有受影响专精;合并结果超过 273 个槽位时,整个模块不会进入模块列表或运行时,本地 Lua 也不会被修改。模块文件仍保留在模块目录,清理宏后可刷新重试。
模块匹配字段:
diff --git a/Shigure.csproj b/Shigure.csproj
index d4376026..03f16b4e 100644
--- a/Shigure.csproj
+++ b/Shigure.csproj
@@ -30,7 +30,6 @@
-
diff --git a/UI/ModuleEditorControl.cs b/UI/ModuleEditorControl.cs
index 6b569665..09951cca 100644
--- a/UI/ModuleEditorControl.cs
+++ b/UI/ModuleEditorControl.cs
@@ -3031,7 +3031,7 @@ public sealed class ModuleEditorControl : UserControl
private void OpenModuleFolder()
{
- var moduleDirectory = ModuleStore.ResolveModuleDirectory(_baseDirectory);
+ var moduleDirectory = ModuleStore.ResolveModuleDirectory();
var filePath = _selectedModule?.FilePath;
try
{
diff --git a/UI/StatusForm.cs b/UI/StatusForm.cs
index eea9a6ff..6225f962 100644
--- a/UI/StatusForm.cs
+++ b/UI/StatusForm.cs
@@ -737,7 +737,7 @@ public sealed class StatusForm : Form
AddAboutRow(details, "类型", "冲锋枪");
AddAboutRow(details, "介绍", "它一分钟打出去的子弹比荒坂偷的税还要多。");
AddAboutRow(details, "用途", "有时人们只想把子弹全打出去,在硝烟过后品味眼前的一片狼藉。");
- var modulePath = ModuleStore.ResolveModuleDirectory(AppPaths.BaseDirectory);
+ var modulePath = ModuleStore.ResolveModuleDirectory();
var configPath = ConfigService.ResolveConfigPath(AppPaths.BaseDirectory);
AddAboutRow(details, "模块目录", FormatAboutPath(modulePath), modulePath);
AddAboutRow(details, "配置目录", FormatAboutPath(configPath), configPath);
@@ -862,6 +862,13 @@ public sealed class StatusForm : Form
var baseDirectory = Path.GetFullPath(AppPaths.BaseDirectory);
var fullPath = Path.GetFullPath(path);
var relativePath = Path.GetRelativePath(baseDirectory, fullPath);
+ // 路径位于 exe 目录之外时直接显示完整路径,避免冗长的 ..\..\ 相对路径文本。
+ if (relativePath == ".."
+ || relativePath.StartsWith(".." + Path.DirectorySeparatorChar, StringComparison.Ordinal))
+ {
+ return fullPath;
+ }
+
return string.IsNullOrWhiteSpace(relativePath) ? "." : relativePath;
}
catch
diff --git a/打包说明.md b/打包说明.md
index d06e9cc4..352bbed7 100644
--- a/打包说明.md
+++ b/打包说明.md
@@ -138,12 +138,13 @@ artifacts\publish\win-x64
Fuyutsui
config
keymap
-module
wow_process.txt
```
其中插件目录是插件权威源,程序会在启动或“更新配置”时把它部署到已运行游戏的 `Interface\AddOns\插件名称`;`Assets` 中的图标和职业/专精图片已作为资源嵌入程序,不要求单独分发。上述运行数据会在发布时复制到输出目录,最稳妥的方式仍是把 `win-x64` 整个文件夹压缩成 zip 再发送。
+模块不随发布包分发:模块保存在用户配置目录 `~/.config/Shigure/module`(首次运行自动创建),全新用户首次启动模块列表为空。使用改名脚本打包时该目录随程序名变化,例如改名为 `MyShigure` 后为 `~/.config/MyShigure/module`。
+
不要只发送单个 exe,也不要删除发布目录中的插件目录。如果缺少内置插件目录,配置/宏编辑和游戏插件部署都会失败。
## 7. 常见问题