{"action":"closed","issue":{"url":"https://api.github.com/repos/SpongePowered/SpongeAPI/issues/364","labels_url":"https://api.github.com/repos/SpongePowered/SpongeAPI/issues/364/labels{/name}","comments_url":"https://api.github.com/repos/SpongePowered/SpongeAPI/issues/364/comments","events_url":"https://api.github.com/repos/SpongePowered/SpongeAPI/issues/364/events","html_url":"https://github.com/SpongePowered/SpongeAPI/issues/364","id":53326334,"number":364,"title":"Implementation dependent modules","user":{"login":"modwizcode","id":369772,"avatar_url":"https://avatars.githubusercontent.com/u/369772?v=3","gravatar_id":"","url":"https://api.github.com/users/modwizcode","html_url":"https://github.com/modwizcode","followers_url":"https://api.github.com/users/modwizcode/followers","following_url":"https://api.github.com/users/modwizcode/following{/other_user}","gists_url":"https://api.github.com/users/modwizcode/gists{/gist_id}","starred_url":"https://api.github.com/users/modwizcode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/modwizcode/subscriptions","organizations_url":"https://api.github.com/users/modwizcode/orgs","repos_url":"https://api.github.com/users/modwizcode/repos","events_url":"https://api.github.com/users/modwizcode/events{/privacy}","received_events_url":"https://api.github.com/users/modwizcode/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/SpongePowered/SpongeAPI/labels/input%20wanted","name":"input wanted","color":"fbca04"},{"url":"https://api.github.com/repos/SpongePowered/SpongeAPI/labels/major%20feature","name":"major feature","color":"bfd4f2"}],"state":"closed","locked":false,"assignee":{"login":"modwizcode","id":369772,"avatar_url":"https://avatars.githubusercontent.com/u/369772?v=3","gravatar_id":"","url":"https://api.github.com/users/modwizcode","html_url":"https://github.com/modwizcode","followers_url":"https://api.github.com/users/modwizcode/followers","following_url":"https://api.github.com/users/modwizcode/following{/other_user}","gists_url":"https://api.github.com/users/modwizcode/gists{/gist_id}","starred_url":"https://api.github.com/users/modwizcode/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/modwizcode/subscriptions","organizations_url":"https://api.github.com/users/modwizcode/orgs","repos_url":"https://api.github.com/users/modwizcode/repos","events_url":"https://api.github.com/users/modwizcode/events{/privacy}","received_events_url":"https://api.github.com/users/modwizcode/received_events","type":"User","site_admin":false},"milestone":null,"comments":14,"created_at":"2015-01-04T05:49:37Z","updated_at":"2015-04-11T03:45:56Z","closed_at":"2015-04-11T03:45:56Z","body":"In light of the decision to not provide a packet API and the difficulties that implementation specific code (which while unfortunate, does need to exist for some functionalities that would never belong in an api), I have come to the conclusion that a simple fix is possible.\r\n\r\nWhile most will see this as excessive at bast and insane at worst, the inclusion of an actual system for loading these implementation specific classes at runtime strikes me as a good tradeoff between making things ridiculously complicated for plugins, and opening the cage of packet API's.\r\n\r\nThe system relies on both stable version information (snapshot or release, version number, possibly an implementation number, and a implementation specific identifier string), and the definition of a non dependent API + fallback implementation. This system is inspired by the handling of nms in Bukkit, but with the goal of making it cleaner and more dependable. \r\n\r\nAnd example use of this API might go like this\r\n\r\n```java\r\n\r\npublic interface API {\r\n    void setUUIDServer(String hostname);\r\n}\r\n\r\npublic class SpongeForgeImpl implements API {\r\n    public void setUUIDServer(String hostname) {\r\n        // ... Actual implementation would go here.\r\n    }\r\n}\r\n\r\npublic class FallbackImpl implements API {\r\n    public void setUUIDServer(String hostname) {\r\n        throw new ImplMissingException(\"Sorry this SpongeAPI implementation isn't supported by Plugin Foo, seek support from developer Xyz\");\r\n    }\r\n}\r\n\r\npublic class MyPlugin {\r\n   @Inject\r\n   ImplManager implManager;\r\n   public void onInit(ServerInitializationEvent event) {\r\n       implManager.registerAPI(API.class, new Fallback()); // Fallback must exist for clarity reasons\r\n       ImplHandler spongeHandler = new HandlerBuilder(new SpongeForgeImpl(this), // pass the plugin reference to the instance\r\n                                                      setProtocolRange(52, 52).\r\n                                                      setAPIMin(\"1.6.20\").\r\n                                                      setImplName(\"Sponge\"). // Either name, or class, or both. Need at least one\r\n                                                      setImplClass(\"org.spongepowered.sponge.mod.SpongeMod\").build());\r\n       implManager.addHandler(API.class, spongeHandler);\r\n    }\r\n}\r\n```"}}