Kzeroko KTM2

天赋运行时

天赋注册、抽取、修习公式、保存状态、同步与管理员工具。

更新于 2026/9/30 14 分钟阅读

玩家为每项天赋保存先天等级、隐藏潜力、熟练度与修习点,另有独立的显现组件。游戏效果读取修习后的有效等级;可见性只影响呈现,不限制加成或修习奖励。

它做什么

实现位于 internal.talent,消费辅助类位于 util.talents。没有 TalentAPI 门面,也没有天赋 JSON 加载器。这些内部类供仓库开发使用,不是稳定的外部 API。天赋 提供面向玩家的加成与目录。

isekaiexpansion:talent 与 isekaiexpansion:talent_reveal 是自动同步的玩家组件,重生均使用 ALWAYS_COPY。IsekaiTalents.init() 注册定义与服务端加入钩子。加入时调用 patchData(0.0F),不会自动读取玩家的幸运属性。

运行时模型

注册表、初始抽取与同类组

E/D/C/B/A/S 对应 0/1/2/3/4/5,数字转换会限制到该范围。当前共 36 项天赋:18 种近战武器、4 种远程武器、双持、星界能量容量、6 种常见元素与 6 种扩展法术学派。

定义分组E / D / C / B / A / S 权重幸运强度
星界能量容量15 / 20 / 30 / 25 / 8 / 20.35
双持34 / 26 / 22 / 12 / 5 / 10.25
常见元素10 / 20 / 30 / 25 / 10 / 50.45
扩展法术学派30 / 25 / 25 / 12 / 5 / 30.20
近战/远程武器17 / 23 / 30 / 17 / 10 / 30.30
新定义构建器默认值60 / 25 / 10 / 4 / 1 / 00.30

这些是规则应用前的权重,不是最终独立概率。等级索引 r 的调整权重为 max(0, round(base × (1 + luck × strength × r / 5)));基础权重为零时仍为零。调整后总权重非正则重试原始非负权重,仍为空时返回 E。

随机种子对 UUID 两部分、服务端世界种子和新取出的 player.getRandom().nextLong() 做 XOR,因此仅凭 UUID 与世界种子不能重现重掷结果。先抽取全部等级,再依次执行定义规则和全局规则。规则重复到无变化或达到 16 轮;达到上限会接受当前结果,不保证已收敛。外层允许 24 次尝试并提供全部 E 的后备,但现有规则上下文没有公开的判无效操作,当前规则也不设置其 invalid 标志。

初始规则结果
任一映射的元素/扩展学派为 S基础星界能量至少为 B。
任一映射的元素/扩展学派为 A基础星界能量至少为 C。
光/治疗或暗/奥术配对中有 S另一项至少为 A。
光/治疗或暗/奥术配对中有 A另一项至少为 B。
近战同类组中有 A / S全组至少为 C / B。
弓/弩组中有 A / S两项至少为 B / A。
枪/魔导枪组中有 A / S两项至少为 A / A。

近战分组为剑刃(sword、rapier、katana、dagger、greatsword)、长柄(spear、halberd、glaive、lance、scythe)、冲击(axe、mace、hammer、gauntlet)、投掷(chakram、boomerang)和魔法器具(wand、staff)。法术配对与武器同类组还共享一次潜力抽取,再分别产生组内偏差。元素对容量的前置关系不构成同类组。每项天赋保留最先注册的亲和组。修习与管理员改等级不会重新执行初始联动规则。

潜力与熟练度公式

潜力 p 限制为 0–99,基础抽取在该整数区间均匀分布。幸运生成 lean = clamp(luck × 0.25, −1, 1);非负值将抽取结果推向 99,负值推向 0,随后舍入并限制范围。同类组成员在共同抽取值上独立增加 −12–12 的整数偏差,再限制范围;独立天赋各自抽取。

潜力最多修习阶数尚未考虑 S 空间时的熟练度上限
0–2100
22–6514
66–9929

设 L 为熟练度、i 为先天等级索引,t 为潜力允许阶数与 L 已达到阶数的较小者(4 前为 0,4 起为 1,9 起为 2)。有效等级为 clamp(i + t, 0, 5),实际获得阶数也不能超过 5 − i。个人熟练度上限依据 min(allowed tiers, 5 − i) 分别为 0、4 或 9。

每步代价公式如下:

gift = clamp(p, 0, 99) / 99
grind = 1.35 - (1.35 - 0.65) * gift
toll = 1 + (1.5 ^ effectiveRankIndex - 1) * grind
base = 90 * (max(0, L) + 1) ^ 1.55
stepCost = max(10, round(round(base * toll) / 10) * 10)

expCap 在 L ≥ 9 时返回 0,但不会因较低的个人上限而自行返回 0;判断能否修习应使用 canStillGrow()。cumulativeExp 累加到公共等级上限以内的每步代价。TalentProficiencyLeveler 将个人上限交给 IsekaiCore 的 LevelingHandler 处理溢出进度;适配器在没有成长空间时清空修习点。处理器缓存索引为先天等级 × 100 + 潜力,最多 600 项。

修习、消费与可见性

TalentProficiencyService.award 只接受 ServerPlayerEntity、非 null 天赋 ID、正数点数、非创造/旁观模式、已有进度条目且仍可成长的情况。奖励原值入账,不乘潜力系数,也不检查显现。熟练度等级变化立即同步,并在相关时刷新派生能量;仅计数变化则走节流同步。

钩子奖励与归属
近战天赋伤害修正对伤害标记的近战武器类型奖励 8;当前双手武器符合双持条件时,双持再奖励 8。直接伤害来源必须是玩家。
远程天赋伤害修正对标记的远程武器类型奖励 11;通过弹射物所有者/远程攻击者解析归属。
进度 > 0.30 的法术 RELEASE对映射学派奖励 10,对基础星界能量奖励 4。
单独的法术 CHANNEL此钩子不奖励修习。

伤害奖励发生在修正函数求值阶段,不检查正伤害、不等待最终生命损失,也不按每次挥动去重。双持不要求两只手分别成功命中。法术在符合条件的释放后奖励,不要求正数能量扣费,也包括引导法术的释放路径;学派无映射时可能只有储备奖励,没有学派奖励。

近战、远程与法术加成读取有效等级。攻速刷新在服务端生物 tick 执行,将双手近战增量与一次双持增量相加,使用 EntityAttributeModifier.Operation.ADDITION。当前 UI 的百分比格式不改变该运算。DualWieldTalentUtil.offHandMultiplier 存在,但当前仓库没有调用者,因此其额外副手倍率没有接入现有伤害流程。

映射学派的绑定和施法受天赋检查约束,创造模式跳过。施法时间缩放仅用于原始时长为正的非引导玩家法术。能量消耗将法术基础消耗与天赋、其他消耗修正相乘后舍入。容量修正以 attribute base × (rank multiplier − 1) 替换 UUID 435f53d1-e0fd-4307-bc5d-df7fc035c78b 的修正项,并在加入/修补、设置等级与熟练度变化时刷新。

显现钩子独立:有目标的近战攻击动作显现武器天赋及符合条件的双持天赋;射击进度 ≥ 1 显现远程天赋。水晶隐藏组有辅助方法与管理员命令,但没有物品使用调用点。法术修习不显现天赋。开启全部显现会清空显式解锁列表;单独关闭全部显现不会额外清除显式条目。lockAll 只关闭标志,reset 命令还会调用 clearUnlocked。

约定

注册与修改

入口约定
TalentDefinition.builder(id)内部构建器;权重下限为 0,幸运强度限制为 0–2。构建时复制权重与规则列表。
TalentRegistry.register(def)同 ID 替换,不拒绝重复,也没有线程同步。
registerRule(id, rule)在保持插入顺序的存储中替换同 ID 全局规则。
registerAffinityGroup(group, members)每项天赋最先加入的组生效。
TalentRules.minIf/maxIf条件等级下限/上限;自定义规则同步执行,没有异常隔离。
TalentsComponent.get(id)有效等级,缺失时返回 E。
innate(id)先天等级,缺失时返回 E。
progress(id)返回可变实时进度;缺失时创建 E/潜力 0,拒绝 null ID。
set(id, rank)修改先天等级并同步,保留潜力、熟练度与修习点,不验证注册表成员身份。
forceReroll(luck)重新抽取并替换全部天赋进度,不重置显现状态。
TalentRevealer.unlock/unlockAll增加可见性,不检查注册表、不改变等级;批量操作合并同步。
TalentRevealComponent.patchData()移除过时的显式解锁 ID;加入钩子没有调用该方法。

在公共初始化阶段一致注册,早于玩家加入或客户端目录捕获。玩家进度应在服务端线程修改。内部 setter 不检查侧别,也不维护全部跨字段约束;直接修改熟练度/潜力后应调用适当的组件刷新。不要将这些内部类当作受支持的附属模组门面。

保存字段与修补

字段类型默认值作用
hasGen布尔值false是否完成初次抽取;false 时修补会重新抽取并替换已有条目。
talentsCompound空天赋标识符字符串到进度 compound 的映射。
talents.<id>.rank整数0先天等级,限制为 0–5。
talents.<id>.potential整数0隐藏潜力,限制为 0–99。
talents.<id>.level整数0熟练度,限制为 0–9,不限制到个人上限。
talents.<id>.exp整数0修习点下限为零;读取时不按每步代价封顶。
revealAll布尔值false独立显现组件标志;为 true 时读取忽略显式列表。
unlocked字符串列表空合法 ID 成为显式解锁,重复合并、无效项跳过。只在非全部显现且列表非空时写出。

这里没有载荷版本或旧整数等级转换。非 compound 条目按 compound 读取时使用 getter 默认值,不保留其旧数字等级。合法但未注册的 ID 会保留到原始读取结束,再由天赋修补移除;非法标识符键直接跳过。

初次生成会抽取全部条目、同步并应用容量。后续加入会移除过时天赋 ID;若缺少条目,则进行一次完整新抽取,但只填入缺项,保留原有记录。因此新增天赋的抽取联动可能依赖那些被丢弃的、现有天赋的重掷值;修补不会依据当前规则重新协调整个存档角色。

同步与呈现

修习计数最多每 40 ticks(2 秒)世界时间同步一次。检查发生在下一次奖励到来时,没有定时补发;节流窗口内的最后一次奖励可能直到其他同步或重连才可见。等级变化立即同步。

isekaiexpansion:player_talent_growth 按 identifier/VarInt/VarInt 携带天赋 ID、熟练度和有效等级,仅在实际获得天赋阶数时提示,不对每个熟练度等级提示。isekaiexpansion:player_talent_unlocked 只携带显现 ID。两个数据包都不替代组件状态。

客户端界面打开时捕获固定的 TalentSnapshot。隐藏条目遮蔽名称、加成和熟练度,但同步组件仍含进度与潜力,因此不显示数字是 UI 约定,不代表客户端拿不到数据。已显现统计使用与游戏效果相同的加成辅助方法。卡片修习条使用个人可达空间,档案的已得阶数分母则使用潜力最多阶数;先天 A 且潜力深厚时,可能只有一阶可练,但潜力分母仍为两阶。

天赋名称键为 talent.<namespace>.<path>,描述追加 .desc;纹理位于 assets/<namespace>/textures/talent/<path>.png。描述翻译缺失时使用界面后备文本,隐藏卡片使用 isekaiexpansion:textures/talent/locked.png。界面不暂停游戏,左键选择、右键打开模态档案;Escape 先关闭档案,再关闭界面。

扩展方式

在公共初始化时新增定义,提供双语条目与图标,并显式接入游戏效果或修习钩子。仅注册不会创建新的伤害类别、学派映射或训练来源。下面是内部使用示例,导入来自 internal.talent、Minecraft Identifier 与 ServerPlayerEntity:

public static void registerExampleTalent() {
    TalentRegistry.INSTANCE.register(
            TalentDefinition.builder(new Identifier("example", "craft"))
                    .weights(60, 25, 10, 4, 1, 0)
                    .luckStrength(0.30F)
                    .build());
}

public static void awardExamplePractice(ServerPlayerEntity player) {
    TalentProficiencyService.award(
            player, new Identifier("example", "craft"), 8);
}

玩家必须在注册后完成进度修补,奖励才可能成功。仅在目标服务端动作发生时发放;若动作还应显现天赋,需要另外调用显现辅助方法,奖励不等于显现。

验证

以下命令均要求权限等级 2。<target> 接受玩家选择器,显式天赋参数必须指向已注册定义。

/ise talent 下的命令效果
reroll <target> [luck]幸运默认 0,命令只接受非负浮点数。重置全部等级/潜力/修习,保留显现。
set <target> <talent> <rank>等级 0–5,仅改变先天等级。
proficiency level <target> <talent> <level>等级 0–9;清空修习点,但不限制到个人上限。
proficiency potential <target> <talent> <potential>潜力 0–99;保留等级与修习点,刷新派生效果。
proficiency grant <target> <talent> <amount>正整数,遵守正常奖励检查;创造/旁观/已封顶目标可能没有获得修习,但仍计入反馈人数。
proficiency inspect <target> <talent>报告先天/有效等级、熟练度、修习点/代价、原始潜力、潜力阶数与当前负担倍率。
reveal unlock <target> <talent>显现一项。
reveal crystal <target>显现 13 项容量/学派条目。
reveal all <target>开启全部显现并清空显式解锁。
reveal reset <target>关闭全部显现并清空显式解锁。

测试潜力边界 21/22、65/66,熟练度 4/9 的升阶,先天 A/S 的空间,大额修习奖励,以及超过个人上限的保存值。验证隐藏天赋仍能修习、显现不改等级、重掷保留显现。对照双手平加攻速与界面百分比。检查映射/无映射学派、引导与释放、零消耗法术、新定义加入时修补、重生,以及节流窗口内最后一次奖励后不再触发奖励的情况。

等级/潜力 setter 是管理员工具,不是普通游戏过程,可能保留超过上限的等级或旧修习总量。应检查结果,不要假设全部字段已共同归一化。

相关页面

  • 天赋 — 完整玩家加成与目录。
  • 法术集成 — 施法准入与支付生命周期。
  • 持久状态 — 世界存储,与这些玩家组件不同。