{"action":"created","issue":{"url":"https://api.github.com/repos/SpongePowered/Sponge/issues/232","labels_url":"https://api.github.com/repos/SpongePowered/Sponge/issues/232/labels{/name}","comments_url":"https://api.github.com/repos/SpongePowered/Sponge/issues/232/comments","events_url":"https://api.github.com/repos/SpongePowered/Sponge/issues/232/events","html_url":"https://github.com/SpongePowered/Sponge/pull/232","id":67469953,"number":232,"title":"[WIP] Unify Forge and Vanilla implementation","user":{"login":"Minecrell","id":3035868,"avatar_url":"https://avatars.githubusercontent.com/u/3035868?v=3","gravatar_id":"","url":"https://api.github.com/users/Minecrell","html_url":"https://github.com/Minecrell","followers_url":"https://api.github.com/users/Minecrell/followers","following_url":"https://api.github.com/users/Minecrell/following{/other_user}","gists_url":"https://api.github.com/users/Minecrell/gists{/gist_id}","starred_url":"https://api.github.com/users/Minecrell/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Minecrell/subscriptions","organizations_url":"https://api.github.com/users/Minecrell/orgs","repos_url":"https://api.github.com/users/Minecrell/repos","events_url":"https://api.github.com/users/Minecrell/events{/privacy}","received_events_url":"https://api.github.com/users/Minecrell/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/SpongePowered/Sponge/labels/input%20wanted","name":"input wanted","color":"fbca04"},{"url":"https://api.github.com/repos/SpongePowered/Sponge/labels/major%20feature","name":"major feature","color":"bfd4f2"},{"url":"https://api.github.com/repos/SpongePowered/Sponge/labels/needs%20team%20review","name":"needs team review","color":"eb6420"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-04-09T23:12:34Z","updated_at":"2015-04-19T13:31:38Z","closed_at":"2015-04-18T19:47:47Z","pull_request":{"url":"https://api.github.com/repos/SpongePowered/Sponge/pulls/232","html_url":"https://github.com/SpongePowered/Sponge/pull/232","diff_url":"https://github.com/SpongePowered/Sponge/pull/232.diff","patch_url":"https://github.com/SpongePowered/Sponge/pull/232.patch"},"body":"**This is a continuation of #222 - based on @Mumfrey's feedback it was splitted into 3 repositories now instead of a single one with subprojects.** (Feel free to skip the next part if you've already read this on the previous PR)\r\n\r\nOur Forge implementation and our Vanilla implementation are both using MCP, which means they share the same mappings and provide a very similar Minecraft environment to work on. Because we're using mixins to implement our SpongeAPI interfaces directly on the Minecraft classes, we can copy most of the mixins simply from the current Forge implementation to our Vanilla implementation.\r\n\r\nCopying everything from the one project to the other project results in a lot of work, and keeping the copied (and slightly modified) files up to date with the original files means even a lot more work, and certain changes (e.g. bug fixes) may get even forgotten which would result in bugs in the Vanilla implementation.\r\n\r\nBeing able to copy a lot of code from one implementation to another means we would be also able to share code directly between the projects using a shared subproject. Often only minor changes are needed in the Forge implementation for Forge integration and only a few other small changes in the Vanilla implementation.\r\n\r\nUnifying both projects will get us more maintainable code and will save a lot of time required for copying everything over to Granite in the long term.\r\n\r\n#### Project structure\r\n\r\nThe project consists out of 4 parts now: [SpongeAPI](https://github.com/SpongePowered/SpongeAPI/tree/feature/unify), Sponge (the Common module holding the shared code of the implementations), [the Forge implementation](https://github.com/Minecrell/SpongeForge) and [Granite](https://github.com/SpongePowered/Granite/tree/feature/unify) (the Vanilla implementation).\r\nTo provide an unified Gradle setup in all these projects, the Gradle project setup was split into reusable files in SpongePowered/SpongeAPI#557 which is used for SpongeAPI itself, as well as Sponge and our two implementations.\r\n\r\n#### TODO\r\n- [X] Setup project structure\r\n  - [ ] Merging SpongePowered/SpongeAPI#557 requires making the implementation compile for all the API changes first, especially the changes for the Data API and game registry.\r\n- [X] Move most independent code into the Sponge module (Thanks to @Voltasalt for help with this)\r\n- [ ] Integrate/update with changes from [`4af541517c03`...`master`](https://github.com/SpongePowered/Sponge/compare/4af541517c03...master)\r\n  - [ ] Add world creation changes\r\n- [x] Figure out the best way to share as much (Mixin) code as possible in the Sponge module and implementations (see below)\r\n- [x] Create new repository for Forge implementation (Currently at [Minecrell/SpongeForge](https://github.com/Minecrell/SpongeForge))\r\n- [x] \\(Update README)\r\n\r\n#### Sharing code between the implementations\r\nWhile there is an huge part of our implementation that does not depend (nor reference) Forge/FML _at all_, some parts reference FML/Forge for smaller things like getting a list of worlds or saving custom NBT data for entities. Splitting this code out completely into the Forge module would fix the issue _itself_  but would again lead to a lot of **code duplication**, with just a single/few method calls as difference.\r\nBecause of this we need to find ways to keep as much code in Common as possible while still keeping direct Forge integration for the Forge implementation.\r\n\r\n- For methods in Forge classes I've added an [`SpongeImpl`](https://github.com/SpongePowered/Sponge/blob/common/src/main/java/org/spongepowered/common/SpongeImpl.java) interface implemented by the implementation modules which provides unified access while still maintaining Forge integration. Of course this interface would grow more and more together with our implementation..\r\n\r\n- For methods/fields added by Forge in Minecraft classes ([example: this is currently breaking Granite at runtime](https://github.com/SpongePowered/Sponge/blob/common/src/main/java/org/spongepowered/common/mixin/core/entity/MixinEntity.java#L134-L135)) maybe we could add the used fields and methods added by Forge in the Vanilla implementation (using mixins) before the Common mixins are applied. (Not completely sure if that would even work, @Mumfrey will probably know if it would)\r\n\r\n- We'll probably need to split the methods/fields of some mixins so implementation-specific part of the mixins get separated out into extra mixins in the implementation module itself. This could of course lead to some confusion when you just want to find the implementation of a specific method in an implementation because you would need to look in multiple locations.\r\n\r\n- ... @Mumfrey As the author of the Mixin system you know it best, so maybe you have some good ideas how we can set this up. =)\r\n\r\n### (Still) known problems\r\n- Currently a temporary ForgeGradle extension is used until we have native support for Vanilla (hopefully coming with 2.0)"},"comment":{"url":"https://api.github.com/repos/SpongePowered/Sponge/issues/comments/94277245","html_url":"https://github.com/SpongePowered/Sponge/pull/232#issuecomment-94277245","issue_url":"https://api.github.com/repos/SpongePowered/Sponge/issues/232","id":94277245,"user":{"login":"halvors","id":620303,"avatar_url":"https://avatars.githubusercontent.com/u/620303?v=3","gravatar_id":"","url":"https://api.github.com/users/halvors","html_url":"https://github.com/halvors","followers_url":"https://api.github.com/users/halvors/followers","following_url":"https://api.github.com/users/halvors/following{/other_user}","gists_url":"https://api.github.com/users/halvors/gists{/gist_id}","starred_url":"https://api.github.com/users/halvors/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/halvors/subscriptions","organizations_url":"https://api.github.com/users/halvors/orgs","repos_url":"https://api.github.com/users/halvors/repos","events_url":"https://api.github.com/users/halvors/events{/privacy}","received_events_url":"https://api.github.com/users/halvors/received_events","type":"User","site_admin":false},"created_at":"2015-04-19T13:31:38Z","updated_at":"2015-04-19T13:31:38Z","body":"@Minecrell That's nice. But what i was trying to say was just that you should rename Sponge to SpongeForge and create a new repo called Sponge for the common stuff :)"}}