
BLZYの自定义进度
将原版进度界面替换为基于画布的高度自定义成就系统,支持7种条件类型,包括NBT物品匹配、前置链、维度锁定、批量编辑、原版浏览以及实时服务器同步。
查看大图Advancement Overhaul 是一款面向 Minecraft 1.21.1(NeoForge)的进度系统全面重构模组。它完全替换原版进度界面与底层逻辑,提供可自由缩放、拖拽、编辑的无限画布 UI、10 种条件类型、前置依赖链、维度锁定、原版进度管理、完整的 /adv 命令树以及 KubeJS 和 FTB Quests 深度兼容。模组同时面向生存玩家和整合包/地图作者,支持在游戏中实时创建、编辑、导入导出自定义进度。
一、主要功能
1.1 原版成就的禁用与管理
本模组允许对原版(及其他模组)的成就进行精细控制:
- 默认禁用:配置项
vanilla.defaultEnabled默认为false,所有原版成就在首次安装时默认禁用,需要手动启用。 - 按命名空间白名单:通过
mods.enabledMods配置自动启用的模组命名空间列表(如["minecraft", "create"]),该模组下所有成就自动创建分类并启用。 - 单个启用/禁用:
/adv vanilla enable <id>//adv vanilla disable <id>对单个原版成就进行开关。 - 批量操作:
/adv vanilla enableall//adv vanilla disableall一键启用或禁用所有原版成就。 - 运行时过滤:通过
AdvancementManagerMixin在进度加载阶段将禁用的原版进度从运行时 Map 中移除,禁用进度完全不可见、不可触发。 - 玩家登录检查:玩家登录时自动撤销所有已被禁用的原版进度,防止残留完成状态。
- 服务端拦截:即使某些途径(如命令)触发了被禁用的原版进度,
ServerEventHandler也会立即撤销。
工作流程:
服务器启动 / reload
└── AdvancementManager.apply()
├── [Mixin HEAD] 缓存原版 JSON → 注入自定义进度
└── [Mixin RETURN] 过滤禁用的原版进度 → 仅保留启用的
└── filterDisabledVanillaFromMap()
├── defaultEnabled = false → 移除所有不在启用列表中的
└── defaultEnabled = true → 仅移除明确禁用的
1.2 自定义画布 UI 与父子成就树形显示
模组提供全新的无限画布 UI,完全取代原版进度界面:
- 无限画布:支持鼠标滚轮缩放(以光标为中心)、中键/拖拽平移,带平滑惯性动画。
- 成就卡片:每个进度以卡片形式在画布上展示,包含图标、名称、完成状态指示和条件进度条。
- 树形依赖连线:
- 采用直角树状图风格绘制成就之间的前置依赖关系:父级竖线 → 水平线段 → 子级竖线,拐点处有圆角连接点。
- 自动识别三种依赖来源:自定义进度前置条件、原版 parent 关系、原版进度关联的自定义前置条件(VanillaAdvMeta)。
- 连线颜色区分状态:普通连线、已完成连线(绿色高亮)、选中项的前置/后继连线。
- 选中某个成就时,其直系前置和直系后继卡片分别以不同背景色高亮显示。
- 树形布局:通过 BFS 遍历原版进度的 parent 关系计算每个进度的树深度,按层分组排列。
- 自动布局(
AutoLayout):基于 DAG 拓扑排序的三阶段布局算法——Phase 1 自顶向下重心启发式 → Phase 2 自底向上父节点居中 → Phase 3 最终重叠修正,支持同时布局自定义和原版进度。 - 标签页系统:支持多标签页切换、拖拽排序、重命名、创建/删除,可将不同进度分类组织。
- 空间网格索引:将卡片按世界坐标分桶到 480px 的网格单元,渲染时仅处理视口范围内的单元格,支持千级卡片流畅渲染。
1.3 猫爪成就牌匾
当玩家完成一个成就时,屏幕顶部会出现一个带有猫咪元素的精美牌匾 HUD 动画:
- 视觉设计:
- 深紫色背景(
#24163E/#362058)搭配薰衣草色边框(#E8C0FF) - 金色标题文字 "✦ 成就达成 ✦"
- 左右对称的完整小猫爪印(1 个主肉垫 + 4 个趾垫扇形排列,浅粉色
#FFB6C1) - 分隔线两侧各有迷你猫爪装饰
- 底部脚印轨迹(成对的迷你爪印)
- 四角星星闪烁点缀
- 深紫色背景(
- 动画效果:
- 滑入阶段(400ms):
easeOutBack回弹缓出曲线,从屏幕上方优雅落位 - 停留阶段(2400ms):完全显示
- 淡出阶段(300ms):
easeInQuad渐隐
- 滑入阶段(400ms):
- 队列系统:同时完成多个成就时自动排队依次展示,不会重叠
- FTB 任务完成:FTB Quests 任务完成时也会触发牌匾显示
- 通过 HUD Overlay 实现,无论当前打开什么界面都能显示
二、维度管理
通过维度锁定系统,可以在玩家完成指定成就之前阻止其进入特定维度:
- 锁定维度:
/adv dimension lock <dim>阻止玩家进入指定维度 - 解锁维度:
/adv dimension unlock <dim>解除锁定 - 设置解锁条件:
/adv dimension setcondition <dim> <advId>绑定一个成就作为解锁条件 - 移除解锁条件:
/adv dimension removecondition <dim>移除条件(维度保持锁定但无需成就解锁)
工作机制:
- 玩家尝试传送至被锁定的维度时,
ServerEventHandler.onEntityTravelToDimension()拦截传送事件 - 检查目标维度的
DimensionLock:如果disabled = true且玩家未完成unlockAdvancementId指定的成就 - 取消传送事件,将玩家传送到当前维度的安全位置(优先重生点,其次传送门周围地面)
- 向玩家发送提示消息
- 1 秒冷却防止同一 tick 内多次弹出消息
数据存储:维度锁配置持久化在 ServerDataStore 中,以 JSON 格式存储。
三、自定义图片
在无限画布上可以自由添加 PNG 图片作为装饰或背景:
- 图片存放目录:
config/advancement_overhaul/images/(手动放入 PNG 文件) - 持久化文件:
config/advancement_overhaul/image_elements.json(保存图片位置和属性) - 格式限制:仅支持
.png,最大 16MB - 操作方式:
- 右键空白画布 → 上下文菜单 → "创建图片" → 从 images/ 目录选择文件
- 图片可拖动移动位置
- 图片可缩放(放大 1.25x / 缩小 0.8x),缩放范围 0.1x ~ 5.0x
- 图片可锁定防止误拖动
- 右键图片可删除
- 渲染:使用
DynamicTexture+NativeImage加载为 Minecraft 纹理,注册到 TextureManager
四、Config 设置
配置文件路径:config/advancementoverhaul-common.toml(NeoForge COMMON 类型,服务端+客户端共享)
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
interface.hideVanilla |
boolean | false |
是否用自定义 Canvas UI 替换原版进度界面 |
permission.editPermissionLevel |
int (0-4) | 2 |
编辑命令所需的最低权限等级(2 = OP 级别) |
toast.duration |
int (ms) | 3000 |
Toast 通知显示时长(500-30000ms) |
performance.playerDataSaveInterval |
int (ticks) | 6000 |
玩家数据定期保存间隔(约 5 分钟) |
vanilla.defaultEnabled |
boolean | false |
原版/模组进度的默认启用状态(false = 默认禁用) |
mods.enabledMods |
List<String> | [] |
自动启用的模组命名空间白名单(如 ["minecraft", "create"]) |
五、指令系统
主命令为 /adv,支持权限分级和 Tab 补全。
玩家操作
| 命令 | 说明 |
|---|---|
/adv complete <id> [player] |
强制完成成就(跳过前置条件检查) |
/adv reset <player> <id|all> |
重置玩家单个或全部进度 |
/adv give <id> [player] |
授予成就 |
/adv revoke <id> [player] |
撤销成就 |
/adv check <id> |
查看进度状态(完成/待定/进度百分比) |
CRUD 操作
| 命令 | 说明 |
|---|---|
/adv delete <id> |
删除自定义成就 |
/adv batchdelete <ids,...> |
批量删除 |
/adv setname <id> <name> |
设置名称 |
/adv setdescription <id> <desc> |
设置描述 |
/adv seticon <id> <icon> |
设置图标(物品/实体/方块 ID) |
/adv togglehidden <id> |
切换隐藏状态 |
/adv setprereq <id> <ids,...> |
设置前置条件(含循环依赖 BFS 检测) |
/adv createjson <json> |
通过 JSON 创建成就 |
/adv updatejson <json> |
通过 JSON 更新成就 |
工具命令
| 命令 | 说明 |
|---|---|
/adv import |
从 import/ 文件夹扫描 JSON 文件导入数据 |
/adv export |
导出所有数据到 export/ 文件夹 |
/adv autolayout |
对当前标签页执行自动布局 |
/adv reload |
重载所有数据并重新同步 |
维度管理
| 命令 | 说明 |
|---|---|
/adv dimension lock <dim> |
锁定维度 |
/adv dimension unlock <dim> |
解锁维度 |
/adv dimension setcondition <dim> <advId> |
设置解锁条件 |
/adv dimension removecondition <dim> |
移除解锁条件 |
标签页管理
| 命令 | 说明 |
|---|---|
/adv tab add <name> |
创建新标签页 |
/adv tab delete <name> |
删除标签页 |
/adv tab order <name1,name2,...> |
设置标签页排序 |
原版成就管理
| 命令 | 说明 |
|---|---|
/adv vanilla enable <id> |
启用单个原版成就 |
/adv vanilla disable <id> |
禁用单个原版成就 |
/adv vanilla enableall |
启用所有原版成就 |
/adv vanilla disableall |
禁用所有原版成就 |
/adv vanilla setpos <id> <x> <y> |
设置原版成就在画布上的位置 |
/adv vanilla settab <id> <tab> |
将原版成就分配到指定标签页 |
/adv vanilla cleartab <id> |
清除原版成就的标签页分配 |
/adv vanilla save <id> |
保存原版成就的当前配置 |
六、KubeJS 兼容
模组通过 kubejs.plugins.txt 自动注册为 KubeJS 插件,提供两类集成:
6.1 脚本 API(Bindings)
在 KubeJS 脚本中通过 AdvancementOverhaul 对象直接调用:
// 查询
AdvancementOverhaul.getAllIds() // 获取所有自定义成就 ID
AdvancementOverhaul.getName("my_adv") // 获取成就显示名称
AdvancementOverhaul.isCompleted(event.player, "my_adv") // 是否已完成
AdvancementOverhaul.getProgress(event.player, "my_adv") // 进度百分比 (0-100)
// 操作
AdvancementOverhaul.complete(event.player, "my_adv") // 强制完成
AdvancementOverhaul.reset(event.player, "my_adv") // 重置
// 创建(链式构建器)
AdvancementOverhaul.builder("my_adv")
.name("我的成就")
.description("描述")
.tab("默认")
.pos(100, 200)
.hidden(false)
.condition("kill_entity", "minecraft:zombie", 10)
.conditionNbt("kill_entity", "minecraft:skeleton", 20, "{}")
.prerequisite("other_adv_id")
.register()
6.2 事件监听
在 KubeJS 脚本中监听模组事件:
// 成就完成事件
AdvancementOverhaul.completed(event => {
console.log(`Player ${event.player.name} completed ${event.advancementId}`)
console.log(`Achievement name: ${event.advancementName}`)
})
// 进度更新事件
AdvancementOverhaul.progress(event => {
console.log(`${event.advancementId}: ${event.progress}/${event.total}`)
if (event.completed) {
// 完成时 progress >= total
}
})
// 成就重置事件
AdvancementOverhaul.reset(event => {
console.log(`${event.advancementId} was reset for ${event.player.name}`)
})
七、FTB Quests 兼容
模组与 FTB Quests 实现深度双向集成:
7.1 FTB 任务作为成就条件
- 条件类型
FTB_QUEST_COMPLETE允许将 FTB 任务完成作为自定义成就的前置条件 - 通过 Architectury 事件监听(实时)和 Tick 轮询(每 20 tick 兜底)两种方式检测任务完成
- 任务完成时自动触发条件评估和级联释放
7.2 FTB 成就奖励的条件检查
- 当 FTB 任务将自定义成就作为奖励时,
AdvancementRewardMixin在claim()方法执行之前拦截检查 - 如果成就是自定义成就且条件未满足,直接取消
claim()调用——不会先授予后撤销 - 条件满足才放行,让 FTB 正常授予,后续事件同步到自定义系统
7.3 KnownServerRegistries 同步
- 自动将自定义成就 ID 注册到 FTB 的
KnownServerRegistries,确保 FTB 团队界面能正确显示成就完成状态 - 客户端连接时自动同步,FTB 模组未加载时静默降级
- 通过反射获取 FTB Quests 版本号并输出日志
7.4 属性变更通知
- 当成就的名称、图标、描述、隐藏状态等属性变更时,自动调用
ServerQuestFile.markDirty()通知 FTB 存盘
八、技术信息
| 项目 | 说明 |
|---|---|
| MC 版本 | 1.21.1 |
| 模组加载器 | NeoForge |
| Java 版本 | 21 |
| 配置类型 | COMMON(服务端 + 客户端共享) |
| 数据存储格式 | JSON(分别存储在 advancements/、players/、tabs/、vanilla/ 目录下) |
| 条件类型 | 10 种(KILL_ENTITY / CRAFT_ITEM / GET_ITEM / BREAK_BLOCK / PLACE_BLOCK / CHANGE_DIMENSION / DEAL_DAMAGE / TAKE_DAMAGE / FISH_ITEM / FTB_QUEST_COMPLETE) |
| 条件逻辑 | AND(所有条件均满足才算完成) |
| 评估模式 | Instant(一次性检测)/ Progress(累积进度追踪)/ Stack-aware(GET_ITEM 背包追踪) |
| NBT 匹配模式 | IGNORE / CONTAINS / EXACT / NONE_EMPTY |
| 级联完成 | BFS 栈遍历,64 层上限,防循环依赖 |
| 网络同步 | 全量同步(GZIP 压缩)+ 增量同步(实时进度更新) |
| C2S 安全 | 命令白名单 + 频率限制(5条/秒)+ 服务端权限二次校验 |
新增自定义资源替换系统
资源文件夹
启动时自动在 config/advancementoverhaul/resources/ 创建文件夹和 README.txt 说明文件。
可替换资源
| 资源 | 文件名 | 格式 | 说明 |
|---|---|---|---|
| 牌匾纹理 | plaque.png | PNG,推荐 240×56 | 替换牌匾背景,文字叠在上面 |
| 完成音效 | chime.wav | mp3 PCM | 完全替换默认紫水晶旋律 |
正在加载版本记录…

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