性能(BurstDrive):跳过未注册特效的每 tick 查询
Build / build (push) Successful in 20s

根因:
BurstDrive 对每把 SlashBlade 的服务器更新都会读取状态并调用通用特效查询;没有 BurstDrive 注册项的刀也会走到该路径,通用查询还会懒创建空的 SB.SEffect 复合标签。

改动:
在保留根 NBT 获取后,先检查 SB.SEffect 复合标签及 BurstDrive 键。未注册或空标签直接返回;已注册的键继续调用既有 isEffective、损坏状态、粒子和攻击代码。

契约:
已注册的 BurstDrive 仍由原有通用特效 API 决定有效性,包含零值、异常数值类型、玩家状态和后续攻击时序。未注册或空特效标签本来只能得到 None;现在不再为其调用通用查询,也不再写入语义为空的 SB.SEffect 子标签。

性能:
静态计数:未注册刀每个服务器更新从 1 次通用 isEffective/getSpecialEffect 查询及其潜在空子标签写入,降为 2 次 NBT 键存在性检查后返回。已注册刀路径不变。未进行实际服务器性能测量。

验证:
通过 tests/regression/burst_drive_effect_registration_regression.py,检查过滤顺序及空、已注册和异常数值键的分流;通过 ./gradlew --no-daemon compileJava reobfJar --console=plain 与 git diff --check。未在 Forge 多人运行时验证粒子与攻击体验。

Refs: #2
This commit is contained in:
Kim committed 2026-09-14 02:06:37 +08:00
1 parent 27199534f4
commit 7b31dd5ab8
2 files changed
+60

No files matched your search

@@ -46,6 +46,7 @@ import net.minecraft.world.World;
public class BurstDrive
implements ISpecialEffect {
static final String EffectKey = "BurstDrive";
private static final String SPECIAL_EFFECTS_TAG = "SB.SEffect";
private boolean useBlade(ItemSlashBlade.ComboSequence sequence) {
if (sequence.useScabbard) {
@@ -66,6 +67,13 @@ implements ISpecialEffect {
EntityPlayer player = (EntityPlayer)event.entity;
ItemStack blade = event.blade;
NBTTagCompound tag = ItemSlashBlade.getItemTagCompound((ItemStack)blade);
if (!tag.hasKey(SPECIAL_EFFECTS_TAG, 10)) {
return;
}
NBTTagCompound specialEffects = tag.getCompoundTag(SPECIAL_EFFECTS_TAG);
if (!specialEffects.hasKey(EffectKey)) {
return;
}
if (ItemSlashBlade.IsBroken.get(tag).booleanValue()) {
return;
}
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""Regression checks for BurstDrive's registration prefilter.
This is a source-level guard test: Forge 1.7.10 event dispatch is not available
in the build environment. It protects the intended ordering and the two
semantics that matter for the fast path: absent or empty effect data cannot
activate BurstDrive, while registered data still reaches isEffective().
"""
from pathlib import Path
SOURCE = Path(__file__).parents[2] / (
"src/main/java/mods/flammpfeil/slashblade/kirisaya/specialeffect/BurstDrive.java"
)
def registration_prefilter(effect_data):
"""Mirror the new guard, where None denotes a missing/non-compound tag."""
if effect_data is None:
return False
return "BurstDrive" in effect_data
def main():
source = SOURCE.read_text(encoding="utf-8")
compound_guard = 'if (!tag.hasKey(SPECIAL_EFFECTS_TAG, 10))'
effect_guard = 'if (!specialEffects.hasKey(EffectKey))'
broken_read = 'if (ItemSlashBlade.IsBroken.get(tag).booleanValue())'
effectiveness = 'switch (SpecialEffects.isEffective('
assert compound_guard in source
assert effect_guard in source
assert source.index(compound_guard) < source.index(broken_read)
assert source.index(effect_guard) < source.index(effectiveness)
# Both cases historically resolve to SpecialEffects.Result.None; neither
# may reach the broken-state, effect lookup, particles, or attack path.
assert not registration_prefilter(None)
assert not registration_prefilter({})
# A present key deliberately continues through the existing API, including
# its handling of zero, malformed numeric data, and player/equipment state.
assert registration_prefilter({"BurstDrive": 0})
assert registration_prefilter({"BurstDrive": 1})
assert registration_prefilter({"BurstDrive": "unexpected-type"})
print("burst-drive-registration-prefilter-regression-ok")
if __name__ == "__main__":
main()