Suggestion Making NMS code static

Discussion in 'Community Feedback and Suggestions' started by Redempt, Jun 6, 2016.

  1. We all know that it's bad to use NMS code, but occasionally I find myself using it. Sometimes it's unavoidable. Spigot and Bukkit are, as far as I know, just dynamic wrappers for NMS code. They allow easier use of it without you needing to get your hands dirty. However, NMS code is unarguably extremely powerful. It is the core of the server, while Spigot and Bukkit sometimes only scratch the surface. I'm not sure if this is completely possible, but I think that NMS packages should be renamed and should be static instead of changing with every single minor update.
     
  2. There is only one NMS package: net.minecraft.server. The name never changes.

    Some of the more important methods have deobfuscated names, the rest you need to figure out for yourself (it is rarely hard). Mojang is responsible for obfuscating the server code, not the spigot devs. Likely this will change with the official modding API.

    Using NMS is not bad in any way, you just need to be able to deal with much messier code, and handle updating it every time a new major version is released - a lot of inexperienced programmers are not up to the task, and end up making buggy plugins.
     
  3. net.minecraft.server.v1_8_R3.EntityPlayer is one class I sometimes have to use
     
  4. MiniDigger

    Supporter

    we talked about removing the nms version number (v1_9_R2 for example) but this idea was declined.
    you can't rely on the method names staying the same after each update. you can rely on the classes being always there.
    having the versioned package names forces the plugin devs to create a module system (if they don't want to deal with reflection). Inexperienced devs, who should not be touching nms, can't do something like that so they keep thier fingers out of nms stuff till they know what they do.
     
  5. I think they should make the package names static, but maybe deprecate the classes to discourage using them for people who don't know what they're doing with it.
     
  6. Reflections would involve me scanning the entire Spigot jar for its packages that have NMS code and adding them to a list, then invoking their methods with Reflections (Unless there is a way to dynamically add imports with Reflections, which I highly doubt there is). Doing that takes so much longer processor wise than it would to just call the method without Reflection.
     
  7. The package version numbers are actually very useful and help to make plugins cross-version compatible unless you do it the lazy way with reflection.

    NMS field / method names change very often for the reasons which are already explained thoroughly. If you use
    Code (Text):
    net.minecraft.server.AnyClass.a();
    but the method gets a new name like
    Code (Text):
    net.minecraft.server.AnyClass.methodName();
    your IDE and compiler are not going to understand which class you're referring to, the new one, or the old one. If the package names are
    Code (Text):
    net.minecraft.server.v1_8_R3.AnyClass.a();
    and
    Code (Text):
    net.minecraft.server.v1_9_R2.AnyClass.methodName();
    you can easily define to which one you're referring.
     
    • Agree Agree x 1
  8. Well, that can be a difference in 2 different Spigot jars.
     
  9. In my opinion, changing method names is better than changing package names, which is better than changing class names, which would be just evil.
     
  10. Your opinion is either based on masochism or a lack of experience with NMS. As I said, changing just the method names, which happens anyways, will make it impossible to create a plugin with implementation specific code in a clean, reflectionless way.
     
    • Agree Agree x 1
  11. MiniDigger

    Supporter

    well, you should not have multiple nms versions in one module anyways. thats why you split it up into api and multiple implementations for every nms version.
     
  12. Technically you CAN (almost) do anything with either static package naming or version specific package naming. Even with static package naming, you could check for the availability of every single thing you are using, you could guard it by server/Minecraft versions and what not.

    With version specific package naming you have the more simple and reliable ways at hand, e.g. you could build implementations for some nms access easily within one project, without using maven modules or similar things, due to the version specific package naming, e.g. to support recent versions of Minecraft.

    If you want to use reflection or dynamic compilation of code at runtime, you can easily find out the version specific package name (get server, get handle) and then do all the necessary tests for availability of what you are using. While plugins that used named obc/nms methods hardly ever would break, the CraftBukkit/Spigot developers also have to account for all the other methods being used by other plugins (a, B, i, ...). I'd still be interested in how often such breakages actually happen for publicly available plugins ((!) full analysis over all past builds of CraftBukkit, methods changed name/signature, methods changing meaning keeping name+signature, of course disregarding inaccessible classes/methods, with colorful diagrams and all).

    I'd not want to switch back to static naming, because version-specific naming enables both simple and reliable concepts, such as 'organize imports' as well as 'maven module per MC/nms/-R123 version + done comparably simple'. It's been another discussion back when version specific package names had been added to CraftBukkit.
    It had not been advertised beforehand, in the middle between Minecraft updates, many server owners had been using the latest development builds of CraftBukkit due to lack of actual rc/beta releases, which in effect half-broke necks of a couple of more complex projects, because there just had not been any way to adjust instantly [note again: for no actual changes within obc/nms in the middle of nowhere] - on the other hand the support load being shifted from CraftBukkit to plugin developers was a fair thing in general, concerning obc/nms, as that used to be the most nasty issues with not/wrongly updated nms plugins.
     
  13. Well, many Spigot plugins will span across multiple minor versions of the server. However, with NMS code, you would need to make a release for every single minor version.
     
  14. I know that issue :). With my plugins breakages have been very seldom within the last ~ 4-5 years, however there have been breakages. The problem is that it can break for the general case, and i've seen methods change meaning, such as changing from testing a property to modifying blocks indirectly :).

    Concerning 'minor updates' the current spigot team is not just increasing the package version with each minor update of Minecraft (compare to 1.8.x...). So they're providing some optimum on that account, in my opinion.
     
  15. My guess is:

    NMS code is for advanced users only. In order to qualify for advanced developer, one has to know reflection. :D
     
  16. Or how to build your own nms wrapper with maven modules.
     
  17. MiniDigger

    Supporter

    which should be the preferred way for any plugin that should support multiple versions.
     
  18. So let's look at removing the version from the package name.

    Say I create a plugin that calls a method in some NMS class that stops the rain, called like i or something. Oh, new update to Minecraft and someone installs my now outdated plugin however in this decompilation, i forces a regeneration of the main world.

    So now, someone who once used my plugin to clear the rain has a new fresh world because the nms changed and their was nothing to stop my plugin from starting.

    (Yes I know there is a clear weather function in the Bukkit API)

    (And yes, I know there is many ways around the packaging)
     
    • Agree Agree x 1