I slept, calmed down, and now let me respond: # The idea of a common protocol: In practice we would like a client of mod loader X and server mod loader Y to be able to connect. This requires at least some cooperation between each other, because the sending party will need to know if it can expect a response, or if the payload that it wants to send runs into nothingness, and it should rather do something else. This can trivially be achieved by telling the other party what channels currently are available, and this is what `minecraft:register` and `minecraft:unregister` achieve. If this is all that is needed, then we all go home. Dinnerbone did this work already, it is an established standard and there is nothing we can and need to do. This has worked for nearly 15 years, is simple, easy to implement and stable. ## Unsuiteability However, several parties involved have indicated that this, limited exchange of information, is not sufficient to provide a proper mechanic that ensures the different loaders can work together. Minecraft has changed. Its network protocol has gotten more advanced with new phases, the ability to configure the client from the server, and now coming down the line custom codecs, as well the ability to change the server using a simple packet. Additionally mojang, in its infinite wisdom, requires that the client and server have the same information. Mods make this assumption as well. Great examples of this are registry ids being used to compress packets instead of using the relatively large names. So the parties which previously indicated that the old protocol was not sufficient came together and discussed what they needed. ## Fabrics proposal Fabric proposed a protocol which initially uses the dinnerbone protocol at the beginning of the config phase to setup the available channels, and then at the end runs a custom protocol, which in it self is versioned (yeay upgrade protocol support), for the payloads in the play phase. Additionally the protocol lets the client decide everything, which version of the protocol to use, which channels are acceptable for the play phase, etc. Fabric implemented this after some discussion, but without full approval and review from the neoforge team. The neoforge team committed to do its best to implement this protocol as closely as it could but the contents of the protocol where only half accepted, because there was a major lack of documentation and testing. ## Neoforge 20.4.70-beta The 70-beta implementation looked at the deficioncies in the fabric protocol, noteably: - The ability of the client to determine both protocol version and the available channels - The actuall versioned negotiation only happened for the play phase, not for the configuration phase - The complete lack of support for registry sync and other components. It was decided that the first two problems should be tackled with that PR, while retaining as many features of what makes neoforge neoforge to begin with. We always had a larger API and better mod support build in, without using external libraries or mods. PacketSplitting was standard for us, large modpacks blew the vanilla limit regularly back then, even on vanillas own packets. However, we are human, and we made mistakes, we mis interpretted some work in the past and some design goals, partially because we did not know better, partially because of time pressure, partially because of lack of documentation, and we implemented the protcol wrongly. Now Neoforge had a very fancy new protocol that works very well for the features that it needs but does not work with anybody else. ## This rebuild Once we figured were we went wrong, several people, including @xfacthd , @covers1624, @minecraftschurli and I, but with input from modmuss, player and others started on a large document to figure out what we could do to improve. This document can be found here: <https://hackmd.io/SYCaVQyMQZaaBAp6oGqfSg?view>. It might be a bit opinionated in different areas but in a good amount of cases it treats all existing protocols fairly and objectively. The endgoal was to build a protocol that would allow 2 mod loaders to connect, while allowing the basic communication and the actual game to work without bugs and without undefined behaviour. This meant for us that we need to again follow what fabric did in the beginning: We performed the `minecraft:register` exchange right from the get go, however then we drop immediately into the same versioned channel exchange side-channel communication that fabric only does for the play phase. This was discussed with modmuss, and agreed upon that this needed to happen. Next this change we determined that Forge has extra features on its networking API. We researched usages of versioned channels (Modularized mods, Mods with Plugins etc.) and considered this to be a feature that can be easily added to the protocol, while allowing a mod loader that does not support this to simply mark all channels as unversioned, and optional and call it a day. This same process was performed for the one other feature that both Minecraft as well as Dinnerbone offered: Sided channels, by default in both cases it is not possible to send the same payload in both directions, unless explicitly stated. Fabric did not follow this concept, a packet flow is foreign to it, yet it was and is something NeoForge wanted to supported. Examples of why this is useful are plentyfull, exchange and negotiation packets, dealing with menu packets etc. However again we realised here that this needed to be optional, there were sufficient examples of where mods send the same packets in both directions, and fabric simply did not have the notion of a packet flow. So we again decided that the default value for a flow can be determined implicitly by the `minecraft:register` packet exchange, or if not included in there by stating that the payload is bidirectional. Again making it possible for mod loaders to implement this part of the protocol without much trouble. ### Registries Minecraft uses registry ids everywhere in networking. When it does this, it assumes that the client and server have the same id for the same object. All mod loaders however already know from experience that this is not the case when mods are involved, and will send the registry ids over. Fabric does this in a highly optimized version of the payload, neoforge is a bit more lazy at the moment, and I agree that we need to move to the fabric protocol asap and will implement it in the new protocol. But the need for a common registry id sync protocol can not be understated. Any mod that touches anything at all in minecrafts registries, mixes in to any blockstate or other component which gets turned into a network id that is based on context requires such a protocol. It is not really optional! ### PacketSplitting: Neoforge out of experiences required this in the past. It happened regularly that in large modpacks, the recipe and tag packets grew to large. Whether we like it or not, it is something we need to deal with. However it can be optional if a ModLoader does not want to support it is fine. But we should agree on a common scheme as to how it works. #### Configurations Configs are complicated, in our eyes there are an essential part of what makes a mod a mod, and can be involved in networking, an example would be a maximum speed or operating range that is configured by the server owner of a machine, this needs to be known to client. and as such we considered it as an optional part of the protocol, it currently does a very stupid filecontent sync, in the same way forge does it. I think we can all agree that this is a bad design, but right now we do not have anything better. Maybe we never will, who knows. We added it because it can majorly influence the payload processing of incoming packets, and as such consider it needed for the proper working on a cross mod loader connection (regardless of what mods are loaded) ## Reasons for all these features. We explicitly did not look at what the mod loaders currently support as a major idea, there were guidance points. The protocol and specifically its newer extensions (registry, channel definition extensions, and configs) are made from the perspective of a modder, and user. What do they need to make great mods. That simply work. But without forgetting that sometimes not all mod loaders can support everything so we made compromises were we thought we could affort them from that perspective. ## Changes that will be added to the protocol: 1) We will update the registry sync protocol to be based on fabrics. However we will not propose its packet splitting. 2) We will make the packet splitting optional. Given that fabric can easily patch this in (the code is really easy and can be done with 2-3 mixins at most). If they are so concerned about packet size, like they seem to be with their registry id sync payload, then they can simply add it and make it work for all packets, vanilla, modded and the like. No discrimination easier modding, everybody wins! But we won't enforce it. 3) We will update the state id sync component of the registry id sync to follow a similar pattern, there are reasonable compression gains that can be made following the same kind of style. 4) We will add a 4 initialization step: Mod List Sync were the server ask the client for a list of its mods. This is needed because server owners have requested the ability to reject hacking mods from the server, or mods of which they know that a particular version is broken. ## What won't we change 1) We will not make the registry sync optional 2) We will not allow the client to determine the version number, or selected channels. ## What if Fabric does not agree Then I think the idea of a common protocol is dead. And we should fallback to `minecraft:register` , as I said above it suffices for the basic need of functionality that is then left over. And we will turn all c:* packets currently proposed into neoforge:* packets. Clients and Server will still connect across loaders, but with several reduced functionality. Broken registy syncing, possibly broken worlds, and severe undefined behaviour. I hope to have addressed all the points that are open. Greets, Marc