diff --git a/PluginDocs/PluginStructure.MD b/PluginDocs/PluginStructure.MD
deleted file mode 100644
index 9c6c9d278..000000000
--- a/PluginDocs/PluginStructure.MD
+++ /dev/null
@@ -1,26 +0,0 @@
-# 插件结构
-
-请注意, 如果你有IDEA,推荐使用idea插件, 可以全自动配置环境, 插件结构, debug运行
-本文是为没有IDEA, 也想开发mirai-console插件的人准备的, 除去插件结构外, 您还需要自己配置运行环境
-
-
-### Plugin.yml
-你应当有一个plugin.yml, 放置在resources文件夹下
-```
-name: "插件名字"
-author: "作者名字"
-version: "0.1.0"
-main: "my_package_name.ExamplePluginBase"
-info: "插件介绍"
-depends: []
-```
-其中main指向 你的PluginBase
-
-### PluginBase
-pluginBase为你插件的启动点, 生命管理周期, 他应该被放到src/main/java或src/main/kotlin下
-一般来说, 他要被放到一个package下, 假如它叫MyPluginBase, 放到package为my.package下, 那么plugin.yml的main则要写my.package.MyPluginBase
-你可以在下面的DEMO中找到PluginBase的一些简单例子
-
-
-## DEMO
-[插件结构例子](https://github.com/mamoe/mirai-console/tree/master/PluginDocs/demo)
\ No newline at end of file
diff --git a/PluginDocs/ToStart.MD b/PluginDocs/ToStart.MD
deleted file mode 100644
index cf737e52e..000000000
--- a/PluginDocs/ToStart.MD
+++ /dev/null
@@ -1,166 +0,0 @@
-# 如何开发Mirai-console插件
-
-
-####
-首先, 你需要一些基础的编程知识
-开发插件的下限很低, 仅仅了解开发用的语言即可
-当然, 插件开发的上限也很高, Mirai-Console的插件的控制层下至简单的回复逻辑, 上至修改与QQ通讯的协议
-目前, Java与Kotlin均可用来开发, 仅需了解任意一门语言, 都可以进行插件开发
-
-### 我没有学习过任何与编程相关的知识或我没有学过这两种语言
-你有两个选择,学习Java或者Kotlin
-学习Java/Kotlin的好处: 学习速度相对较快, 学习资料多
-学习Kotlin的好处: mirai源开发语言为kotlin, 学习了kotlin可以顺便读懂mirai及其分支项目, 更容易写出更高质量的插件
-
-方法1: 认真读书
-[30分钟精通JAVA](https://www.runoob.com/java/java-tutorial.html) 最低只需要学完Java 教程, Java 面向对象两章
-[30分钟精通Kotlin](https://www.kotlincn.net/docs/reference/) 最低只需要学完类与对象
-
-方法2: 通过例子边学插件边学语言
-需要较高悟性, 不推荐完全没有接触编程的人尝试
-## 我需要什么?
-### Java环境
-JDK是Java语言的软件开发工具包,开发Java软件时必须安装jdk。
-推荐安装JDK 11, 最低推荐使用JDK 8来开发Mirai-Console插件。
-
-
-打开控制台(windows按徽标键+R,在弹出的窗口输入cmd然后回车;linux直接打开控制台),输入以下代码并回车:
-```$xslt
-javac -version
-```
-返回的应该类似于以下的结果:
-```$xslt
-javac 1.8.0_60-ea
-```
-如果类似于以上的结果,恭喜你已经成功的安装了jdk 8并且不希望更新版本可以跳过这个步骤的教程。
-如果返回的版本是1.7.0或者更旧的版本,或者返回的类似于“'javac' 不是内部或外部命令,也不是可运行的程序或批处理文件”,说明你还没有安装最新版本的jdk。
-
-#### 安装最新版JDK
-请打开以下链接下载JDK, 推荐使用稳定的11:https://www.oracle.com/java/technologies/javase-downloads.html
-安装过程因系统而异,这里就不详细讲解了。
-另外,jdk安装包也包含相应版本的jre,所以你无需在java官网上再下载安装一次jre。
-在windows系统安装jdk后,你需要配置jdk来保证命令行正常使用。
-#### windows系统中旧版JDK的配置
-大部分JDK在安装时已经可以自己配置, 请直接检查是否成功, 如不成功在阅读本块
-检查是否配置成功: 点击windows徽标键+R,输入cmd并回车,在打开的控制台输入“javac -version”和“java -version”,如果都能正确的返回版本信息,说明配置环境变量成功了。至此,你的jdk已经安装并配置完成
-如果没有, 以下只写了简单流程, 如需要图文帮助可以搜索"windows系统中JDK的配置"
-- 右键“计算机”,点击“属性”,
-- 在弹出的窗口中点击“高级系统设置”,“环境变量”,
-- 点击“系统变量”下面的“新建”,在弹出的窗口的“变量名”输入“JAVA_HOME”(不带引号),“变量值”输入你之前安装jdk的安装路径,我的是“C:\Program Files\Java\jdk1.8.0_60”(不带引号),这里根据你安装jdk的路径来输入。然后点击确定
-- 在“系统变量”中寻找“Path”(不带引号)变量,选中后点击“编辑”,在“变量值”的最后面(注意不是把整个替换,是添加在最后面)输入:
-```$xslt
-%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
-```
-这里要注意原来Path的变量值末尾有没有;号,如果没有,先输入;号再输入上面的代码。
-点击“系统变量”下面的“新建”,在弹出的窗口的“变量名”输入“CLASSPATH”(不带引号),“变量值”输入以下的字符串(注意,最前面有一个点“.”不要忘了):
-```$xslt
-.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
-```
-- 检查是否配置成功。
-#### IDE
-IDE,即集成开发环境,是辅助编程开发的软件。使用合适的IDE能有效地减少代码语法错误、编译麻烦等问题,加大开发效率。目前java开发者常用的IDE有Eclipse,NetBeans,IntelliJ IDEA等软件。我这里使用IntelliJ IDEA 14.1(以下简称“IDEA”)与windows 7系统为例子,来讲IDE的安装和配置。
-强烈推荐IDEA, IDEA可以使用idea插件[mirai-console-intellij](https://github.com/mamoe/mirai-console-intellij)快速进行插件开发
-
-打开[IntelliJ IDEA的官方网站]( http://www.jetbrains.com/idea/),点击“Get IntelliJ IDEA now”
-
-IDEA分付费的Ultimate版和免费的Community版,选择自己的系统后,根据自己的需求点击下载使用,一般的使用免费的Community版就足够了。
-
-
-### 我要如何开始
-**此处使用IDEA作为演示IDE**
-新手只推荐使用IDEA, 如执着于不使用idea, 可以阅读[PluginStructure](PluginStructure.MD)手动构建插件环境
-
-#### IDE准备
-安装idea插件[mirai-console-intellij](https://github.com/mamoe/mirai-console-intellij), 这是一个用于快速创建Mirai Console插件的IDE插件
-1: 自动安装
-打开IDEA, 点击Preferences或按[Ctrl+Alt+Shift+S]/[Cmd+Alt+Shift+S], 点击插件[Plugins], 市场[Market place], 搜索Mirai, 安装Mirai-Console
-预计2020/3/11号后才可以在market里搜索到
-
-
-2: 手动安装
-前往[这里](https://github.com/mamoe/mirai-console-intellij/releases)下载最新的插件[.jar]
-打开IDEA, 点击Preferences或按[Ctrl+Alt+Shift+S]/[Cmd+Alt+Shift+S], 按下图操作, 选择下载的jar 然后重启IDE
-![如何手动安装](assets/ideaInstall.png)
-
-
-
-#### 启动项目
-1: 点击New Project
-2: 在左侧选择Mirai Console Plugin
-3: 根据下图辅助填写信息
-![填写信息1](assets/ideaplugin1.jpg)
-4: 点击[next]
-5: 根据下图辅助继续填写信息
-![填写信息2](assets/ideaplugin2.jpg)
-6: 点击[next]
-7: 最后一页与本地储存位置有关, 如不懂使用默认即可
-8: 点击[Finish]稍作等待
-9: 等待这个页面加载出来
-![外观1](assets/ideaplugin3.png)
-10: 点击右下↘的Import gradle project或Import Maven Project
-11: 等待进度条结束
-![进度条](assets/ideaplugin4.png)
-12: 等待这个页面加载出来(这是第一页选的Java语言, kotlin类似)
-![外观2](assets/ideaplugin5.png)
-13: 插件环境正式完成
-
-
-
-
-
-
-#### 如何运行
-
-1: 根据下图帮助打开gradle window 并双击对应task
-![运行task](assets/run1.png)
-2: 此时你应该能看到正在进行编译,编译完成之后将会自动启动console
-3: 输入密码完成登录,开始测试
-
-
-
-
-#### 如何debug
-
-在进行了上述配置之后,直接用debug模式运行task可能会无法成功断点,请按照以下方式配置
-1: 点击这里打开运行配置
-![打开运行配置](assets/debug1.png)
-2: 选择刚刚自带生成的配置并复制一份
-![复制配置](assets/debug2.png)
-3: 修改复制的配置,按照下图添加 `--debug-jvm`
-![修改配置](assets/debug3.png)
-4: 添加Remote Debug,一般来说不需要更改设置,直接确认即可
-![remote debug](assets/debug4.png)
-5: 运行task
-![run](assets/debug5.png)
-6: 出现以下显示的时候切换到Remote并点击debug
-![listening](assets/debug6.png)
-![debug](assets/debug7.png)
-7: 当调试器附加成功时程序才会开始运行,因此你可以在任何地方使用断点,当然也可能会出现一些问题导致某些地方断点失效
-![breakpoint](assets/debug8.png)
-
-
-
-
-
-
-
-#### 如何打包插件
-1: 根据下图帮助打开gradle window[maven同理]
-![打开window](assets/ideaplugin6.jpg)
-2: 根据下图帮助点击JAR
-![找菜单](assets/ideaplugin7.png)
-3: 在这里找到成品, 完成
-![点击](assets/ideaplugin8.png)
-
-PS: 如果要打包有依赖lib的插件, 请继续向后读
-
-
-## 下一步
-
-Java 玩家->[我的第一个插件](https://github.com/mamoe/mirai-console/blob/master/PluginDocs/java/)
-Kotlin玩家->[我的第一个插件](https://github.com/mamoe/mirai-console/blob/master/PluginDocs/kotlin/)
-
-
-本章部分章节引用自[搭建环境 - Nukkit插件从0开始](https://www.cnblogs.com/xtypr/p/nukkit_plugin_start_from_0_build_environment.html),
-
-
diff --git a/PluginDocs/assets/debug1.png b/PluginDocs/assets/debug1.png
deleted file mode 100644
index 30291c253..000000000
Binary files a/PluginDocs/assets/debug1.png and /dev/null differ
diff --git a/PluginDocs/assets/debug2.png b/PluginDocs/assets/debug2.png
deleted file mode 100644
index f9cebdfd3..000000000
Binary files a/PluginDocs/assets/debug2.png and /dev/null differ
diff --git a/PluginDocs/assets/debug3.png b/PluginDocs/assets/debug3.png
deleted file mode 100644
index 66a52111e..000000000
Binary files a/PluginDocs/assets/debug3.png and /dev/null differ
diff --git a/PluginDocs/assets/debug4.png b/PluginDocs/assets/debug4.png
deleted file mode 100644
index 573d0c8a5..000000000
Binary files a/PluginDocs/assets/debug4.png and /dev/null differ
diff --git a/PluginDocs/assets/debug5.png b/PluginDocs/assets/debug5.png
deleted file mode 100644
index d7822e1b2..000000000
Binary files a/PluginDocs/assets/debug5.png and /dev/null differ
diff --git a/PluginDocs/assets/debug6.png b/PluginDocs/assets/debug6.png
deleted file mode 100644
index 511ddbc47..000000000
Binary files a/PluginDocs/assets/debug6.png and /dev/null differ
diff --git a/PluginDocs/assets/debug7.png b/PluginDocs/assets/debug7.png
deleted file mode 100644
index 9f8f2ce6e..000000000
Binary files a/PluginDocs/assets/debug7.png and /dev/null differ
diff --git a/PluginDocs/assets/debug8.png b/PluginDocs/assets/debug8.png
deleted file mode 100644
index f79fcf87b..000000000
Binary files a/PluginDocs/assets/debug8.png and /dev/null differ
diff --git a/PluginDocs/assets/ideaInstall.png b/PluginDocs/assets/ideaInstall.png
deleted file mode 100644
index 25fc4a3f3..000000000
Binary files a/PluginDocs/assets/ideaInstall.png and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin1.jpg b/PluginDocs/assets/ideaplugin1.jpg
deleted file mode 100644
index b0a3e6267..000000000
Binary files a/PluginDocs/assets/ideaplugin1.jpg and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin2.jpg b/PluginDocs/assets/ideaplugin2.jpg
deleted file mode 100644
index c91c12139..000000000
Binary files a/PluginDocs/assets/ideaplugin2.jpg and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin3.png b/PluginDocs/assets/ideaplugin3.png
deleted file mode 100644
index e6f1cea56..000000000
Binary files a/PluginDocs/assets/ideaplugin3.png and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin4.png b/PluginDocs/assets/ideaplugin4.png
deleted file mode 100644
index 1dda62172..000000000
Binary files a/PluginDocs/assets/ideaplugin4.png and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin5.png b/PluginDocs/assets/ideaplugin5.png
deleted file mode 100644
index 8f1cb6880..000000000
Binary files a/PluginDocs/assets/ideaplugin5.png and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin6.jpg b/PluginDocs/assets/ideaplugin6.jpg
deleted file mode 100644
index bf4e26d2e..000000000
Binary files a/PluginDocs/assets/ideaplugin6.jpg and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin7.png b/PluginDocs/assets/ideaplugin7.png
deleted file mode 100644
index d4f0886cd..000000000
Binary files a/PluginDocs/assets/ideaplugin7.png and /dev/null differ
diff --git a/PluginDocs/assets/ideaplugin8.png b/PluginDocs/assets/ideaplugin8.png
deleted file mode 100644
index 06e4cde11..000000000
Binary files a/PluginDocs/assets/ideaplugin8.png and /dev/null differ
diff --git a/PluginDocs/assets/run1.png b/PluginDocs/assets/run1.png
deleted file mode 100644
index c13d1634b..000000000
Binary files a/PluginDocs/assets/run1.png and /dev/null differ
diff --git a/PluginDocs/demo/README.md b/PluginDocs/demo/README.md
deleted file mode 100644
index e6de92065..000000000
--- a/PluginDocs/demo/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-这是一个demo, 请将这里当做你的项目根目录
-
diff --git a/PluginDocs/demo/src/main/java/my_package_name/MyPluginBase.java b/PluginDocs/demo/src/main/java/my_package_name/MyPluginBase.java
deleted file mode 100644
index 3213498d1..000000000
--- a/PluginDocs/demo/src/main/java/my_package_name/MyPluginBase.java
+++ /dev/null
@@ -1,99 +0,0 @@
-//在这里创建你的PluginBase, 他应该是一个object
-/**
-kotlin example
-
-
-object ExamplePluginMain : PluginBase() {
- override fun onLoad() {
- super.onLoad()
- }
-
- override fun onEnable() {
- super.onEnable()
-
- logger.info("Plugin loaded!")
-
- subscribeMessages {
- "greeting" reply { "Hello ${sender.nick}" }
- }
-
- subscribeAlways { event ->
- logger.info { "${event.authorId} 的消息被撤回了" }
- }
- }
-}
-
-
-
-java example
-
-
-class ExamplePluginBase extends PluginBase {
-
- public void onLoad(){
- bot.getFriends().forEach(friend -> {
- System.out.println(friend.getId() + ":" + friend.getNick());
- return Unit.INSTANCE; // kotlin 的所有函数都有返回值. Unit 为最基本的返回值. 请在这里永远返回 Unit
- });
-
- Events.subscribeAlways(GroupMessage.class, (GroupMessage event) -> {
-
- if (event.getMessage().contains("reply")) {
- // 引用回复
- final QuoteReplyToSend quote = MessageUtils.quote(event.getMessage(), event.getSender());
- event.getGroup().sendMessage(quote.plus("引用回复"));
-
- } else if (event.getMessage().contains("at")) {
- // at
- event.getGroup().sendMessage(new At(event.getSender()));
-
- } else if (event.getMessage().contains("permission")) {
- // 成员权限
- event.getGroup().sendMessage(event.getPermission().toString());
-
- } else if (event.getMessage().contains("mixed")) {
- // 复合消息, 通过 .plus 连接两个消息
- event.getGroup().sendMessage(
- MessageUtils.newImage("{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png") // 演示图片, 可能已过期
- .plus("Hello") // 文本消息
- .plus(new At(event.getSender())) // at 群成员
- .plus(AtAll.INSTANCE) // at 全体成员
- );
-
- } else if (event.getMessage().contains("recall1")) {
- event.getGroup().sendMessage("你看不到这条消息").recall();
- // 发送消息马上就撤回. 因速度太快, 客户端将看不到这个消息.
-
- } else if (event.getMessage().contains("recall2")) {
- final Job job = event.getGroup().sendMessage("3秒后撤回").recallIn(3000);
-
- // job.cancel(new CancellationException()); // 可取消这个任务
-
- } else if (event.getMessage().contains("上传图片")) {
- File file = new File("myImage.jpg");
- if (file.exists()) {
- final Image image = event.getGroup().uploadImage(new File("myImage.jpg"));
- // 上传一个图片并得到 Image 类型的 Message
-
- final String imageId = image.getImageId(); // 可以拿到 ID
- final Image fromId = MessageUtils.newImage(imageId); // ID 转换得到 Image
-
- event.getGroup().sendMessage(image); // 发送图片
- }
-
- } else if (event.getMessage().contains("friend")) {
- final Future> future = event.getSender().sendMessageAsync("Async send"); // 异步发送
- try {
- future.get();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
- });
- }
-
- public void onEnable(){
- logger.info("Plugin loaded!");
- }
-
-}
diff --git a/PluginDocs/demo/src/main/resources/plugin.yml b/PluginDocs/demo/src/main/resources/plugin.yml
deleted file mode 100644
index 0078c2a03..000000000
--- a/PluginDocs/demo/src/main/resources/plugin.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: "Example"
-author: "你的名字"
-version: "0.1.0"
-main: "my_package_name.ExamplePluginBase"
-info: "My info"
-depends: []
\ No newline at end of file
diff --git a/PluginDocs/java/MyFirstPlugin.MD b/PluginDocs/java/MyFirstPlugin.MD
deleted file mode 100644
index 495778997..000000000
--- a/PluginDocs/java/MyFirstPlugin.MD
+++ /dev/null
@@ -1,3 +0,0 @@
-Java的插件教程
-
-你可以下载source.java和MyFirstPluginJava.pdf 一起阅读
diff --git a/PluginDocs/java/MyFirstPluginJava origin.pages b/PluginDocs/java/MyFirstPluginJava origin.pages
deleted file mode 100644
index d807280a2..000000000
Binary files a/PluginDocs/java/MyFirstPluginJava origin.pages and /dev/null differ
diff --git a/PluginDocs/java/MyFirstPluginJava.pdf b/PluginDocs/java/MyFirstPluginJava.pdf
deleted file mode 100644
index 3878808d9..000000000
Binary files a/PluginDocs/java/MyFirstPluginJava.pdf and /dev/null differ
diff --git a/PluginDocs/java/README.md b/PluginDocs/java/README.md
deleted file mode 100644
index 495778997..000000000
--- a/PluginDocs/java/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Java的插件教程
-
-你可以下载source.java和MyFirstPluginJava.pdf 一起阅读
diff --git a/PluginDocs/kotlin/MyFirstPlugin.MD b/PluginDocs/kotlin/MyFirstPlugin.MD
deleted file mode 100644
index 04873e652..000000000
--- a/PluginDocs/kotlin/MyFirstPlugin.MD
+++ /dev/null
@@ -1,3 +0,0 @@
-由于文件较大, 请选择上面的
-
-pdf/docs/pages一种进行下载观看
diff --git a/PluginDocs/kotlin/README.md b/PluginDocs/kotlin/README.md
deleted file mode 100644
index 04873e652..000000000
--- a/PluginDocs/kotlin/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-由于文件较大, 请选择上面的
-
-pdf/docs/pages一种进行下载观看
diff --git a/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.docx b/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.docx
deleted file mode 100644
index 0cdd2daa9..000000000
Binary files a/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.docx and /dev/null differ
diff --git a/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.pages b/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.pages
deleted file mode 100644
index 2cab74c74..000000000
Binary files a/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.pages and /dev/null differ
diff --git a/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.pdf b/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.pdf
deleted file mode 100644
index fc761cb86..000000000
Binary files a/PluginDocs/kotlin/mirai-myfirstplugin-kotlin.pdf and /dev/null differ
diff --git a/backend/mirai-console/README.md b/backend/mirai-console/README.md
index 53ff01b27..901c73a94 100644
--- a/backend/mirai-console/README.md
+++ b/backend/mirai-console/README.md
@@ -34,35 +34,6 @@
[`JavaPluginScheduler`]: src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt
[`ResourceContainer`]: src/main/kotlin/net/mamoe/mirai/console/plugin/ResourceContainer.kt
-## 准备工作
-
-### 开发 mirai-console 插件的准备工作
-- 需使用 IDE: [IntelliJ IDEA](https://www.jetbrains.com/idea/)
-- IntelliJ 需装有 [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge) 插件 (启动 IntelliJ, 点击 [一键安装](https://plugins.jetbrains.com/embeddable/install/14816))
-- 安装并配置 JDK 8
-
-### 前置知识
-- 你需要掌握 Java 基础.
-- 你需要了解 Kotlin 基础语法:
- - [基本类型](https://www.kotlincn.net/docs/reference/basic-types.html)
- - [类与继承](https://www.kotlincn.net/docs/reference/classes.html)
- - [属性与字段](https://www.kotlincn.net/docs/reference/properties.html)
- - [接口](https://www.kotlincn.net/docs/reference/interfaces.html)
- - [扩展](https://www.kotlincn.net/docs/reference/extensions.html)
- - [数据类](https://www.kotlincn.net/docs/reference/data-classes.html)
- - [对象](https://www.kotlincn.net/docs/reference/object-declarations.html)
- - [密封类](https://www.kotlincn.net/docs/reference/sealed-classes.html)
- - **[Java 中调用 Kotlin](https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html)**
-
-## 包结构
-- `net.mamoe.mirai.console.`
- - `command`:指令模块:[`Command`]
- - `data`:存储模块:[`PluginData`], [`PluginConfig`], [`PluginDataStorage`]
- - `event`:Console 实现的事件.
- - `plugin`:插件模块:[`Plugin`], [`PluginLoader`], [`JvmPlugin`]
- - `util`:工具类:[`Annotations`], [`BotManager`], [`ConsoleInput`], [`JavaPluginScheduler`]
- - `internal`:内部实现
-
## 基础
diff --git a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt
index e6bb091d8..a9d2ac6f9 100644
--- a/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt
+++ b/backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt
@@ -35,7 +35,6 @@ import net.mamoe.mirai.utils.MiraiLogger
* 实现为 [ClassLoader.getResourceAsStream]
*
* ## 实现 [JvmPlugin]
- * j
*
* @see AbstractJvmPlugin 默认实现
*
diff --git a/docs/Commands.md b/docs/Commands.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/Extensions.md b/docs/Extensions.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/FrontEnd.md b/docs/FrontEnd.md
new file mode 100644
index 000000000..4287ca861
--- /dev/null
+++ b/docs/FrontEnd.md
@@ -0,0 +1 @@
+#
\ No newline at end of file
diff --git a/docs/PermissionService.md b/docs/PermissionService.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/Permissions.md b/docs/Permissions.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/PluginData.md b/docs/PluginData.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/PluginLoader.md b/docs/PluginLoader.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/Plugins.md b/docs/Plugins.md
new file mode 100644
index 000000000..8b9fec694
--- /dev/null
+++ b/docs/Plugins.md
@@ -0,0 +1,242 @@
+# Mirai Console Backend - Plugins
+
+[`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt
+[`PluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/description/PluginDescription.kt
+[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt
+[`PluginManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginManager.kt
+[`JarPluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JarPluginLoader.kt
+[`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt
+[`JvmPluginDescription`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPluginDescription.kt
+[`AbstractJvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/AbstractJvmPlugin.kt
+[`KotlinPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/KotlinPlugin.kt
+[`JavaPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPlugin.kt
+
+
+[`PluginData`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt
+[`PluginConfig`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginConfig.kt
+[`PluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt
+
+[`MiraiConsole`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsole.kt
+[`MiraiConsoleImplementation`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/MiraiConsoleImplementation.kt
+
+
+[`Command`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt
+[`CompositeCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CompositeCommand.kt
+[`SimpleCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/SimpleCommand.kt
+[`RawCommand`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/RawCommand.kt
+[`CommandManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/CommandManager.kt
+
+[`BotManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt
+[`Annotations`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/Annotations.kt
+[`ConsoleInput`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/ConsoleInput.kt
+[`JavaPluginScheduler`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt
+[`ResourceContainer`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/ResourceContainer.kt
+[`PluginFileExtensions`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginFileExtensions.kt
+[`AutoSavePluginDataHolder`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataHolder.kt#L45
+
+[Kotlin]: https://www.kotlincn.net/
+[Java]: https://www.java.com/zh_CN/
+[JVM]: https://zh.wikipedia.org/zh-cn/Java%E8%99%9A%E6%8B%9F%E6%9C%BA
+[JAR]: https://zh.wikipedia.org/zh-cn/JAR_(%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F)
+
+[为什么不支持热加载和卸载插件?]: QA.md#为什么不支持热加载和卸载插件
+[使用 ServiceLoader 加载插件]: QA.md#使用-serviceloader-加载插件
+
+Mirai Console 运行在 [JVM],支持使用 [Kotlin] 或 [Java] 语言编写的插件。
+
+## 通用的插件接口 - [`Plugin`]
+
+所有 Console 插件都必须实现 [`Plugin`] 接口。
+
+> **解释 *插件***:只要实现了 [`Plugin`] 接口的类和对象都可以叫做「Mirai Console 插件」,简称 「插件」。
+> 为了便捷,内含 [`Plugin`] 实现的一个 [JAR] 文件也可以被称为「插件」。
+
+基础的 [`Plugin`] 很通用,它只拥有很少的成员:
+
+```kotlin
+interface Plugin : CommandOwner { // CommandOwner 是空的 interface
+ val isEnabled: Boolean
+ val loader: PluginLoader<*, *> // 能处理这个 Plugin 的 PluginLoader
+}
+```
+
+[`Plugin`] 接口拥有强扩展性,以支持 Mirai Console 统一管理使用其他编程语言编写的插件 (详见进阶章节 [实现 PluginLoader](PluginLoader.md))。
+
+## JVM 平台插件接口 - [`JvmPlugin`]
+
+所有的 JVM 插件都必须实现 [`JvmPlugin`](否则不会被 [`JarPluginLoader`] 加载)。
+Mirai Console 提供一些基础的实现,即 [`AbstractJvmPlugin`],并将 [`JvmPlugin`] 分为 [`KotlinPlugin`] 和 [`JavaPlugin`]。
+
+### 主类和描述
+
+**Kotlin 使用者的插件主类应继承 [`KotlinPlugin`]。**
+**其他 JVM 语言(如 Java)使用者的插件主类应继承 [`JavaPlugin`]。**
+
+#### 描述
+插件描述需要在主类构造器传递给 `super`。因此插件不需要 `plugin.yml`, `plugin.xml` 等配置文件来指示信息。
+
+Mirai Console 使用 `ServiceLoader` 加载插件。推荐的做法是使用 `AutoService`(如何[使用 ServiceLoader 加载插件])。
+
+##### 插件名
+插件名仅取决于 `PluginDescription` 提供的 `name`,与主类类名等其他信息无关。
+
+#### 实现 Kotlin 插件主类
+
+一个 Kotlin 插件的主类通常需:
+- 继承 [`KotlinPlugin`]
+- 访问权限为 `public` 或默认 (不指定)
+
+```kotlin
+@AutoService(JvmPlugin::class) // 让 Console 知道这个 object 是一个插件主类.
+object SchedulePlugin : KotlinPlugin(
+ SimpleJvmPluginDescription( // 插件的描述, name 和 version 是必须的
+ name = "Schedule",
+ version = "1.0.0",
+ // author, description, ...
+ )
+) {
+ // ...
+}
+```
+
+#### 实现 Java 插件
+
+一个 Java 插件的主类通常需:
+- 继承 [`JavaPlugin`]
+- 访问权限为 `public`
+
+(推荐) 静态初始化:
+```java
+@AutoService(JvmPlugin.class)
+public final class JExample extends JavaPlugin {
+ public static final JExample INSTANCE = new JExample(); // 可以像 Kotlin 一样静态初始化单例
+ private JExample() {
+ super(new SimpleJvmPluginDescription(
+ "JExample", // name
+ "1.0.0" // version
+ ));
+ }
+}
+```
+
+由 Console 初始化(仅在某些静态初始化不可用的情况下使用):
+```java
+@AutoService(JvmPlugin.class)
+public final class JExample extends JavaPlugin {
+ private static final JExample instance;
+ public static JExample getInstance() {
+ return instance;
+ }
+ public JExample() { // 此时必须 public
+ super(new SimpleJvmPluginDescription(
+ "JExample", // name
+ "1.0.0" // version
+ ));
+ instance = this;
+ }
+}
+```
+
+### 依赖管理
+
+一个插件被允许依赖于另一个插件。可在 `SimpleJvmPluginDescription` 构造时提供信息。
+
+若插件拥有依赖,则会首先加载其依赖。但任何一个插件的 `onEnable()` 都会在所有插件的 `onLoad()` 都调用成功后再调用。
+
+多个插件的加载是*顺序的*,意味着若一个插件的 `onLoad()` 等回调处理缓慢,后续插件的加载也会被延后,即使它们可能没有依赖关系。
+因此请尽量让 `onLoad()`,`onEnable()`,`onDisable()`快速返回。
+
+### 插件生命周期
+
+Mirai Console 不提供热加载和热卸载功能,所有插件只能在服务器启动前加载,在服务器结束时卸载。([为什么不支持热加载和卸载插件?])
+
+插件仅可以通过如下三个回调知晓自身的加载情况。
+
+较小概率情况:
+- 如果 `onLoad()` 被调用,`onEnable()` 不一定会调用。因为可能在调用后续插件的 `onLoad()` 或 `onEnable()` 时可能会出错而导致服务器被关闭。
+- 如果 `onLoad()` 或 `onEnable()` 调用时抛出异常,`onDisable()` 不会被调用。(注意:这是仍处于争议状态的行为,后续可能有修改)
+- 如果 `onEnable()` 被成功调用,`onDisable()` 一定会调用,无论其他插件是否发生错误。
+
+#### 加载
+
+[`JarPluginLoader`] 调用插件的 `onLoad()`,在 `onLoad()` 正常返回后插件被认为成功加载。
+
+由于 `onLoad()` 只会被初始化一次,插件可以在该方法内进行一些*一次性*的*初始化*任务。
+
+**在 `onLoad()` 时插件并未处于启用状态,此时插件不能进行监听事件,加载配置等操作。**
+
+若在 Kotlin 使用 `object`,或在 Java 使用静态初始化方式定义插件主类, `onLoad()` 与 `init` 代码块作用几乎相同。
+
+#### 启用
+
+[`JarPluginLoader`] 调用插件的 `onEnable()`,意为启用一个插件。
+
+此时插件可以启动所有协程,事件监听,和其他任务。**但这些任务都应该拥有生命周期管理,详见 [任务生命周期管理](#任务生命周期管理)。**
+
+#### 禁用
+
+[`JarPluginLoader`] 调用插件的 `onDisable()`,意为禁用一个插件。
+
+插件的任何类和对象都不会被卸载。「禁用」仅表示停止关闭所有正在进行的任务,保存所有数据,停止处理将来的数据。
+
+插件应正确实现「禁用」,以为用户提供完全的控制可能。
+
+### 任务生命周期管理
+
+#### 协程管理
+
+[`JvmPlugin`] 实现 `CoroutineScope`,并由 Console 内部实现提供其 `coroutineContext`。
+
+`JvmPlugin.coroutineContext` 包含元素 `CoroutineName`, `SupervisorJob`, `CoroutineExceptionHandler`。
+**所有插件启动的协程都应该受 `JvmPlugin` 作用域的管理**
+
+如要启动一个协程,正确的做法是:
+```kotlin
+// object MyPluginMain : KotlinPlugin()
+
+MyPluginMain.launch {
+ // job
+}
+```
+
+#### Java 线程管理
+
+*TODO*:Mirai Console 暂未支持自动的线程管理。请手动在 `onDisable()` 时关闭启动的线程。
+
+### 访问数据目录和配置目录
+
+[`JvmPlugin`] 实现接口 [`PluginFileExtensions`]。插件可通过 `resolveDataFile`,`resolveConfigFile` 等方法取得数据目录或配置目录下的文件。
+
+可以在任何时刻使用这些方法。
+
+详见 [`PluginFileExtensions`]。
+
+#### 物理目录路径
+用 `$root` 表示 Mirai Console 运行路径,`$name` 表示插件名
+插件数据目录一般在 `$root/plugins/`,
+
+### 访问 [JAR] 包内资源文件
+
+[`JvmPlugin`] 实现接口 [`ResourceContainer`]。插件可通过 `getResource`,`getResourceAsStream` 等取得 [JAR] 包内资源文件。
+
+可以在任何时刻使用这些方法。
+
+详见 [`ResourceContainer`]。
+
+### 读取 [`PluginData`] 或 [`PluginConfig`]
+
+> 本节基于章节 [PluginData](PluginData.md) 的内容。
+> 在阅读本节前建议先阅读上述基础章节。
+
+[`JvmPlugin`] 实现接口 [`AutoSavePluginDataHolder`],提供:
+
+Kotlin:
+- `public fun T.reload()`
+- `public fun T.reload()`
+
+Java:
+- `public fun reloadPluginData(PluginData)`
+- `public fun reloadPluginData(PluginConfig)`
+
+**仅可在插件 onEnable() 时及其之后才能使用这些方法。**
+**在插件 onDisable() 之后不能使用这些方法。**
\ No newline at end of file
diff --git a/docs/QA.md b/docs/QA.md
new file mode 100644
index 000000000..bb941b910
--- /dev/null
+++ b/docs/QA.md
@@ -0,0 +1,36 @@
+# Q&A
+
+## 插件
+
+
+### 使用 ServiceLoader 加载插件
+
+- 方法 A. (推荐) 自动创建 service 文件 (使用 Google auto-service)
+ 在 `build.gradle.kts` 添加:
+ ```kotlin
+ plugins {
+ kotlin("kapt")
+ }
+ dependencies {
+ val autoService = "1.0-rc7"
+ kapt("com.google.auto.service", "auto-service", autoService)
+ compileOnly("com.google.auto.service", "auto-service-annotations", autoService)
+ }
+ ```
+ *对于 `build.gradle` 用户, 请自行按照 Groovy DSL 语法翻译*
+
+- 方法 B. 手动创建 service 文件
+ 在 `jar` 内 `META-INF/services/net.mamoe.mirai.console.plugin.jvm.JvmPlugin` 文件内存放插件主类全名.
+
+
+**注意**:
+- 插件自身的版本要求遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/) 规范, 合格的版本例如: `1.0.0`, `1.0`, `1.0-M1`, `1.0-pre-1`
+- 插件依赖的版本遵循 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/) 规范, 同时支持 [Apache Ivy 风格表示方法](http://ant.apache.org/ivy/history/latest-milestone/settings/version-matchers.html).
+
+
+### 为什么不支持热加载和卸载插件?
+
+在热加载过程容易产生冲突情况;
+卸载时不容易完全卸载所有静态对象。
+
+为了避免这些麻烦,Mirai Console 认为没有支持热加载和热卸载的必要。
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..d7bdfdc00
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,66 @@
+# MiraiConsole
+
+欢迎来到 mirai-console 开发文档!
+
+## 准备工作
+
+### 开发 mirai-console 插件的准备工作
+- 需使用 IDE: [IntelliJ IDEA](https://www.jetbrains.com/idea/)
+- IntelliJ 需装有 [Kotlin Jvm Blocking Bridge](https://github.com/mamoe/kotlin-jvm-blocking-bridge) 插件 (启动 IntelliJ, 点击 [一键安装](https://plugins.jetbrains.com/embeddable/install/14816))
+- 安装并配置 JDK 8
+
+### 前置知识
+要学习为 mirai-console 开发原生支持的插件, 需要:
+
+- 掌握 Java 基础.
+- 了解 Kotlin 基础语法:
+ - [基本类型](https://www.kotlincn.net/docs/reference/basic-types.html)
+ - [类与继承](https://www.kotlincn.net/docs/reference/classes.html)
+ - [属性与字段](https://www.kotlincn.net/docs/reference/properties.html)
+ - [接口](https://www.kotlincn.net/docs/reference/interfaces.html)
+ - [扩展](https://www.kotlincn.net/docs/reference/extensions.html)
+ - [数据类](https://www.kotlincn.net/docs/reference/data-classes.html)
+ - [对象](https://www.kotlincn.net/docs/reference/object-declarations.html)
+ - [密封类](https://www.kotlincn.net/docs/reference/sealed-classes.html)
+ - **[Java 中调用 Kotlin](https://www.kotlincn.net/docs/reference/java-to-kotlin-interop.html)**
+- 至少能使用 Java 或 Kotlin 一种一门语言解决问题
+- 了解 JVM 和 Java 等同类编程语言的关系
+
+## 目录
+
+### 后端插件开发基础
+
+- 包结构
+ `net.mamoe.mirai.console.`
+ - `command`:指令模块:[`Command`]
+ - `data`:存储模块:[`PluginData`], [`PluginConfig`], [`PluginDataStorage`]
+ - `event`:Console 实现的事件.
+ - `plugin`:插件模块:[`Plugin`], [`PluginLoader`], [`JvmPlugin`]
+ - `util`:工具类:[`Annotations`], [`BotManager`], [`ConsoleInput`], [`JavaPluginScheduler`]
+ - `internal`:内部实现
+
+- 插件 - [Plugin 模块](Plugins.md)
+- 指令 - [Command 模块](Commands.md)
+- 存储 - [PluginData 模块](PluginData.md)
+- 权限 - [Permission 模块](Permissions.md)
+
+### 后端插件开发进阶
+
+- 扩展 - [Extension 模块和扩展点](Extensions.md)
+- 扩展 - [实现 PluginLoader](PluginLoader.md)
+- 扩展 - [实现 PermissionService](PermissionService.md)
+
+### 实现前端
+- [FrontEnd](FrontEnd.md)
+
+[`Plugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/Plugin.kt
+[`Annotations`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/Annotations.kt
+[`PluginData`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginData.kt
+[`JavaPluginScheduler`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JavaPluginScheduler.kt
+[`JvmPlugin`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/jvm/JvmPlugin.kt
+[`PluginConfig`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginConfig.kt
+[`PluginLoader`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/plugin/PluginLoader.kt
+[`ConsoleInput`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/ConsoleInput.kt
+[`PluginDataStorage`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/data/PluginDataStorage.kt
+[`BotManager`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/util/BotManager.kt
+[`Command`]: ../backend/mirai-console/src/main/kotlin/net/mamoe/mirai/console/command/Command.kt