Each potion effect is handled differently, but the important thing to note is storage size.
Internally the amplifier is stored as an integer (minimum of -2,147,483,648, maximum of 2,147,483,647), but when writing the amplifier to NBT it gets saved as a byte (minimum of -128, maximum of 127). If the value provided is outside of that range, it will be forced back into that range.
As such, when attempting to set the amplifier via NBT (e.g. with /give
or /summon
), you are restricted to that range and trying to exceed 127 will cause it to overflow to negative values (128 becomes -128). You cannot achieve an amplifier of 128 with NBT.
But the /effect
command doesn't go through NBT to assign an effect. It directly sets the amplifier (which is stored as an integer) and is allowed to exceed the maximum. However, if the entity is saved to NBT, the effect is saved which will cause the value to overflow appropriately, potentially changing what the effect does due to the negative value.
When attempting to use /effect
to apply a higher amplifier than 127 on a player, the client is sent an amplifier typecasted to byte via the SPacketEntityEffect
packet, which reduces the amplifier into the byte range. The client and server are fighting over what the value is meant to be.
For example, with the following:
/effect @p minecraft:levitation 1 255
The server says "255" (since it's saved internally as an integer) but the client is saying "0" (since it's sent via packet as a byte). The result is the client seeing itself not moving. Some issues come as a result, such as taking damage will cause the player to shoot high into the air in an attempt to resync.
This is what causes oddities with players, but this doesn't work the same way with non-player entities. Their amplifier is internally stored as an integer and no packets are interfering, allowing the server full control. If the entity is saved to NBT, such as by chunk unloading, the effect will then overflow into byte range:
/effect @e[type=Creeper,c=1] minecraft:levitation 1 255