Skills/nms/nms-attribute-modifier/SKILL.md
透過 NMS AttributeMap/AttributeModifier 動態修改實體屬性(MAX_HEALTH、ATTACK_DAMAGE 等),比 Bukkit API 更精確(Paper NMS + Mojang-mapped)/ Dynamically modify entity attributes via NMS AttributeMap/AttributeModifier
npx skillsauth add MrPippi/MPS nms-attribute-modifierInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
nms-attribute-modifier
透過 NMS AttributeMap、AttributeInstance、AttributeModifier 精確控制實體屬性,支援加法、倍乘、基底值修改,實現 RPG 裝備加成、Buff/Debuff 系統。
| 參數 | 範例 | 說明 |
|------|------|------|
| package_name | com.example.rpg | 產出類別所在 package |
| class_name | AttributeUtil | 工具類名稱 |
AttributeUtil.java — 屬性讀寫工具ModifierBuilder.java — AttributeModifier 建立器參見 Skills/paper-nms/PLATFORM.md。關鍵依賴:
dependencies {
paperweight.paperDevBundle('1.21.1-R0.1-SNAPSHOT')
}
AttributeUtil.javapackage com.example.rpg;
import net.minecraft.core.Holder;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import org.bukkit.craftbukkit.v1_21_R1.entity.CraftLivingEntity;
import org.bukkit.entity.LivingEntity;
import java.util.Optional;
@SuppressWarnings("UnstableApiUsage")
public final class AttributeUtil {
private AttributeUtil() {}
/** 取得屬性實例(若實體不支援該屬性則回傳 empty)。 */
public static Optional<AttributeInstance> getInstance(
LivingEntity entity, Holder<Attribute> attribute) {
net.minecraft.world.entity.LivingEntity nms = ((CraftLivingEntity) entity).getHandle();
return Optional.ofNullable(nms.getAttribute(attribute));
}
/** 讀取屬性最終值(含所有 modifier 計算後)。 */
public static double getValue(LivingEntity entity, Holder<Attribute> attribute) {
return getInstance(entity, attribute)
.map(AttributeInstance::getValue)
.orElse(0.0);
}
/** 讀取屬性基底值(不含 modifier)。 */
public static double getBaseValue(LivingEntity entity, Holder<Attribute> attribute) {
return getInstance(entity, attribute)
.map(AttributeInstance::getBaseValue)
.orElse(0.0);
}
/** 設定屬性基底值。 */
public static void setBaseValue(LivingEntity entity, Holder<Attribute> attribute, double value) {
getInstance(entity, attribute).ifPresent(inst -> inst.setBaseValue(value));
}
/** 新增 AttributeModifier(若相同 id 已存在會先移除)。 */
public static void addModifier(LivingEntity entity, Holder<Attribute> attribute,
AttributeModifier modifier) {
getInstance(entity, attribute).ifPresent(inst -> {
inst.removeModifier(modifier.id());
inst.addPermanentModifier(modifier);
});
}
/** 移除指定 id 的 AttributeModifier。 */
public static void removeModifier(LivingEntity entity, Holder<Attribute> attribute,
java.util.UUID id) {
getInstance(entity, attribute).ifPresent(inst -> inst.removeModifier(id));
}
/** 移除指定 id 的 AttributeModifier(ResourceLocation 版)。 */
public static void removeModifier(LivingEntity entity, Holder<Attribute> attribute,
net.minecraft.resources.ResourceLocation id) {
getInstance(entity, attribute).ifPresent(inst -> inst.removeModifier(id));
}
/** 移除全部 modifier(僅保留基底值)。 */
public static void clearModifiers(LivingEntity entity, Holder<Attribute> attribute) {
getInstance(entity, attribute).ifPresent(inst ->
inst.getModifiers().forEach(m -> inst.removeModifier(m.id())));
}
// ─── 常用屬性常數快捷 ───────────────────────────────────────────
public static double getMaxHealth(LivingEntity e) { return getValue(e, Attributes.MAX_HEALTH); }
public static void setMaxHealth(LivingEntity e, double v) { setBaseValue(e, Attributes.MAX_HEALTH, v); }
public static double getAttackDamage(LivingEntity e) { return getValue(e, Attributes.ATTACK_DAMAGE); }
public static void setAttackDamage(LivingEntity e, double v) { setBaseValue(e, Attributes.ATTACK_DAMAGE, v); }
public static double getMovementSpeed(LivingEntity e) { return getValue(e, Attributes.MOVEMENT_SPEED); }
public static void setMovementSpeed(LivingEntity e, double v) { setBaseValue(e, Attributes.MOVEMENT_SPEED, v); }
}
ModifierBuilder.javapackage com.example.rpg;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
/**
* AttributeModifier 建立器。
*
* Operation 說明:
* ADDITION — 加法:baseValue + amount
* MULTIPLY_BASE — 乘基底:baseValue + baseValue * amount
* MULTIPLY_TOTAL — 乘總值:totalValue * (1 + amount)
*/
public final class ModifierBuilder {
private ModifierBuilder() {}
/** 建立加法 modifier(e.g. +5 攻擊力)。 */
public static AttributeModifier addition(String namespace, String path, double amount) {
return new AttributeModifier(
ResourceLocation.fromNamespaceAndPath(namespace, path),
amount,
AttributeModifier.Operation.ADD_VALUE
);
}
/** 建立乘基底 modifier(e.g. +10% 攻擊力)。 */
public static AttributeModifier multiplyBase(String namespace, String path, double multiplier) {
return new AttributeModifier(
ResourceLocation.fromNamespaceAndPath(namespace, path),
multiplier,
AttributeModifier.Operation.ADD_MULTIPLIED_BASE
);
}
/** 建立乘總值 modifier(e.g. 全部計算後再 ×1.1)。 */
public static AttributeModifier multiplyTotal(String namespace, String path, double multiplier) {
return new AttributeModifier(
ResourceLocation.fromNamespaceAndPath(namespace, path),
multiplier,
AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL
);
}
}
src/main/java/com/example/
├── MyNmsPlugin.java
└── rpg/
├── AttributeUtil.java
└── ModifierBuilder.java
AttributeInstance 操作必須在主執行緒呼叫(NMS 實體狀態非執行緒安全)ModifierBuilder 的方法為純資料建立,可在任意執行緒呼叫Skills/_shared/nms-threading.md| 錯誤 | 原因 | 解法 |
|------|------|------|
| getInstance 回傳 empty | 實體不支援該屬性 | 確認 EntityType 支援(如 Slime 無 ATTACK_DAMAGE) |
| modifier 無效果 | Operation 選擇錯誤 | 參考 Operation 說明選擇正確計算方式 |
| 屬性值被重置 | 實體死亡/重生後 modifier 消失 | 在 EntitySpawnEvent 重新套用 modifier |
| addModifier 拋 IllegalArgumentException | 相同 ResourceLocation 已存在 | 呼叫前先 removeModifier() |
development
透過 NMS Scoreboard/Objective/Team API 操作 sidebar、tablist 顯示名稱與計分板(Paper NMS + Mojang-mapped)/ Operate sidebar, tablist, and scoreboard via NMS Scoreboard/Objective/Team API
research
操作 GameProfile 進行 skin 注入,用於 NPC 外觀設定與假玩家實體(Paper NMS + Mojang-mapped)/ Manipulate GameProfile for skin injection used in NPC appearance and fake player entities
tools
透過 ClientboundLevelParticlesPacket 實現進階 NMS 粒子效果:客戶端專屬、大量粒子、自定義參數(Paper NMS + Mojang-mapped)/ Advanced NMS particle effects via ClientboundLevelParticlesPacket with per-client and bulk support
documentation
直接操作 CompoundTag 讀寫物品、實體、方塊實體的 NBT 資料(Paper NMS + Mojang-mapped)/ Read and write NBT data on items, entities, and block entities via CompoundTag