
藿香
Minecraft NeoForge 指南书模组
查看大图一个面向 Minecraft NeoForge 的指南书模组,旨在为其他模组提供游戏内指南。Ageratum 提供丰富的 Markdown 渲染、i18n 本地化,以及可扩展的自定义语法/组件系统。
文档
特性
核心 Markdown 支持
✅ 块级元素
- ATX 标题(
# ~ ######)和 Setext 标题(下划线风格) - 段落和换行
- 有序、无序和任务列表(多级嵌套)
- 引用块(多级嵌套)
- 围栏代码块(反引号和波浪号)以及缩进代码块
- 分隔线
- 支持对齐设置的表格
- 图片(命名空间本地引用)
✅ 行内元素
- 粗体、斜体、删除线
- 行内代码片段(支持多个反引号)
- 链接 和自动链接
- 转义字符支持
- 自定义颜色标签
- 悬停和点击事件(
<hover>和<click>标签)
✅ 高级特性
- 引用链接定义和引用链接语法
- 自动链接扩展
- 代码块行号
- 表格列对齐(左/中/右)
国际化(i18n)
- 文档按
ageratum/<语言代码>/组织(例如en_us、zh_cn) - 如果缺少本地化版本,默认回退到
en_us - 完全支持多字节字符(中文、日文等)
扩展语法
用于自定义组件的两种块级扩展语法:
1. 冒号语法
::: info
这是一个信息框。
:::
::: tip
这是一个提示。
:::
::: warning
这是一个警告。
:::
::: danger
这是一个危险警告。
:::
2. 标签语法
<namespace:component key="value" param=123>
块内容支持 Markdown 语法。
</namespace:component>
<namespace:component/>
无内容的自闭合形式。
命名空间可以省略(默认为 ageratum:)。
内置扩展组件
ageratum:info- 蓝色信息框ageratum:tip- 绿色提示框ageratum:warning- 橙色警告框ageratum:danger- 红色危险框
悬停和点击事件
支持交互式文本,允许玩家悬停查看工具提示或点击执行操作。
悬停事件(<hover>)
悬停在文本上时显示提示文本:
<hover type="SHOW_TEXT" data="这是工具提示">悬停在我上面</hover>
支持的类型:
SHOW_TEXT- 显示纯文本工具提示(data为工具提示内容)
点击事件(<click>)
点击文本时执行操作:
<click type="OPEN_URL" data="https://example.com">点击打开链接</click>
<click type="COPY_TO_CLIPBOARD" data="要复制的文本">点击复制</click>
<click type="SUGGEST_COMMAND" data="/say hello">点击建议命令</click>
支持的类型:
OPEN_URL- 打开 URL(data为完整 URL)COPY_TO_CLIPBOARD- 复制文本到剪贴板(data为要复制的文本)SUGGEST_COMMAND- 在聊天中建议命令(data为命令文本)
组合样式
你可以在同一段文本中组合多种样式:
<hover type="SHOW_TEXT" data="这是工具提示"><click type="OPEN_URL" data="https://example.com">点击并悬停在我上面!</click></hover>
配方组件(<recipe/>)
使用 recipe 扩展可直接在 Markdown 文档中渲染配方:
<recipe id="minecraft:acacia_boat"/>
id:必填,目标配方ResourceLocation- 内置支持:
RecipeType.CRAFTING(工作台配方) - 渲染行为:每个输入槽位显示其
Ingredient的第一个候选物品 - 回退行为:如果客户端关卡不可用、配方缺失或没有匹配的工厂,组件将渲染为无可见高度
你可以通过 AgeratumRegistries.RECIPE_COMPONENT_FACTORIES 注册额外的配方组件工厂:
public static final DeferredHolder<MDRecipeComponent.RecipeComponentFactory<?>, MDRecipeComponent.RecipeComponentFactory<?>> SMELTING =
AgeratumRegistries.RECIPE_COMPONENT_FACTORIES.register(
"smelting",
() -> MDRecipeComponent.RecipeComponentFactory.create(RecipeType.SMELTING, MDSmeltingRecipeComponent::new)
);
结构 NBT 组件(<structure/>)
使用 structure 扩展可直接在文档中为 .nbt 结构文件渲染摘要、俯视方块预览和有界 NBT 树:
<structure id="minecraft:village/plains/houses/plains_small_house_1"/>
<structure id="./test.nbt"/>
id/path:必填,目标结构文件ResourceLocationmaxDepth:可选,最大展开深度,默认2maxEntries:可选,每层显示的键/列表条目最大数量,默认12- 支持相对路径,会相对于当前文档目录解析,包括放置在资源包中 Markdown 文档旁的
.nbt文件;在预览模式下会从run/ageratum_review/加载匹配的文件 - 该组件首先显示结构元数据,如尺寸、调色板、方块数量和实体数量,然后渲染俯视方块预览,随后显示深度受限的 NBT 树
- 悬停预览中的方块会显示其方块 ID、结构坐标、调色板索引,以及是否携带方块实体 NBT
预加载与缓存
- 在资源加载时自动扫描并预解析 Markdown 文档为
MDComponent列表 - 立即打开缓存的组件,无解析延迟
- 资源重载时自动刷新缓存
跨端打开指南
// Client: open directly
Ageratum.openGuide(ResourceLocation location);
// Server: notify client via network packet
Ageratum.
openGuide(ResourceLocation location);
项目结构
目录布局
src/main/java/dev/anvilcraft/resource/ageratum/
├── Ageratum.java // Main mod class + command registration
├── GuideDocumentLoader.java // Document loading utils
├── GuideDocumentCache.java // Preload cache & reload listener
│
├── client/
│ ├── AgeratumClient.java // Client hooks (reserved)
│ ├── gui/
│ │ └── GuideScreen.java // Guide reading GUI
│ └── feat/markdown/
│ ├── MarkdownParser.java // Markdown block-level parser
│ ├── BuiltinExtensionComponents.java // Built-in extension registration
│ ├── BlockExtensionState.java // Block extension state machine
│ ├── SelfClosingBlockExtensionState.java
│ ├── ExtensionParamParser.java // Parameter parsing utility
│ ├── MDExtensionContext.java // Extension execution context
│ ├── MDExtensionComponentFactory.java // Extension factory interface
│ └── component/
│ ├── MDComponent.java // Base class + inline parsing
│ ├── MDTextComponent.java // Plain text paragraphs
│ ├── MDHeaderComponent.java // Headings
│ ├── MDCodeBlockComponent.java // Code blocks
│ ├── MDListComponent.java // Lists (inc. task lists)
│ ├── MDQuoteComponent.java // Blockquotes
│ ├── MDTableComponent.java // Tables
│ ├── MDImageComponent.java // Images
│ ├── MDHorizontalRuleComponent.java
│ └── MDNoticeBoxComponent.java // Notice box container
│
└── network/
├── AgeratumNetwork.java // Network registration & dispatch
└── OpenGuidePayload.java // Guide open network packet
设计原则
- 关注点分离:每个类只负责单一职责
- 无超大类:最长文件约 400 行,所有内部类均已提取
- 全面文档:所有公共 API 均有中文 Javadoc,复杂逻辑有内联注释
- 可扩展性:通过
registerExtensionComponent()注册自定义块类型
使用指南
玩家
使用客户端命令打开指南:
/ageratum <namespace> [file]
Examples:
/ageratum ageratum # Opens ageratum:en_us/index.md
/ageratum mymod guide # Opens mymod:en_us/guide.md
/ageratum mymod zh_cn/tutorial # Opens mymod:zh_cn/tutorial.md
支持命名空间和文件名的 Tab 补全。
开发者
注册自定义扩展
使用 NeoForge 文档中描述的注册方法:
DeferredRegister(推荐)RegisterEvent(高级用法)
public static final DeferredRegister<MDExtensionComponentFactory> EXT_COMPONENT_FACTORIES =
AgeratumRegistries.createExtensionComponentFactoryRegister("your_modid");
public static final DeferredHolder<MDExtensionComponentFactory, MDExtensionComponentFactory> CUSTOM =
EXT_COMPONENT_FACTORIES.register(
"custom", () ->
context -> new MyComponent(context.renderedContent(), context.params())
);
// In your mod constructor
EXT_COMPONENT_FACTORIES.
register(modEventBus);
注册自定义行内样式解析器
行内样式解析器通过 INLINE_STYLE_PARSER_REGISTRY_KEY 注册。MDComponent 查询该注册表,并按位置 + 解析器优先级解析匹配项。
package com.example.mymod.client.markdown;
import dev.anvilcraft.resource.ageratum.client.feat.markdown.component.MDInlineStyleParser;
import dev.anvilcraft.resource.ageratum.client.registries.AgeratumRegistries;
import net.minecraft.network.chat.Style;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import java.util.regex.Pattern;
public final class MyInlineStyleParsers {
// Use your own modid here, not ageratum
public static final DeferredRegister<MDInlineStyleParser> INLINE_STYLE_PARSERS = DeferredRegister.create(
AgeratumRegistries.INLINE_STYLE_PARSER_REGISTRY_KEY,
"mymod"
);
// Example tag: <rainbow>text</rainbow>
public static final DeferredHolder<MDInlineStyleParser, MDInlineStyleParser> RAINBOW =
INLINE_STYLE_PARSERS.register(
"rainbow",
() -> MDInlineStyleParser.create(
100, // smaller value = higher precedence at same position
Pattern.compile("<rainbow>"),
"</rainbow>",
(Style parentStyle, java.util.regex.Matcher matcher) -> parentStyle.withColor(0xFF55FF)
)
);
private MyInlineStyleParsers() {
}
}
在你的客户端初始化中注册:
public class MyModClient {
public MyModClient(IEventBus modEventBus) {
MyInlineStyleParsers.INLINE_STYLE_PARSERS.register(modEventBus);
}
}
Markdown 用法:
normal text <rainbow>colored text</rainbow> normal text
查看完整指南:docs/inline-style-parser-example.en.md。
添加文档
在资源包中创建:
assets/<namespace>/ageratum/<language>/index.md
assets/<namespace>/ageratum/en_us/index.md
assets/<namespace>/ageratum/zh_cn/index.md
许可证
- 代码除非另有说明,默认遵循我们的 LICENSE 文件(LGPL-3.0)
- 非代码资产(位于此处)遵循我们的 ASSET_LICENSE 文件(ARR)
正在加载版本记录…






正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。