Hello all. This post will discuss medium-term plans for Quark, namely the following two points
- Cross-platform support (Forge/Fabric and derivatives)
- 1.20 Port
The main point in case is cross-platform support, which is currently in a planning stage internally. We expect to begin development around October to match my previous update. No ETA is available.
Cross-Platform
As you might know, AutoRegLib and Quark are both highly tied to Forge's systems, and porting them is a significant amount of work. To help visualize how we plan to go about doing this, I've made a few diagrams to help illustrate the steps of what I call Project Zeta. (the name doesn't really mean anything, I just think it sounds cool)
Figure 1: The current status of the mods
You can read the black arrow as "depends on", therefore, "Forge depends on Minecraft", "Quark depends on Forge". I'll be ommitting all the additional arrows coming out of Minecraft for now, since they don't really serve a purpose, as we all know Quark is a Minecraft mod. The white rhombus lines can be read as "contains", such as "Quark contains Quark Forge Mod".
For transparency, all the diagrams in this post are simplified and not fully accurate. They only show the information that's relevant to get the point across of what we're doing.
This image doesn't tell you anything you don't know yet, because it's known both Quark and AutoRegLib have hard dependencies on Forge at the moment, but it's there to show the current status so you can compare to how we'll be changing it from here on out.
Figure 2: Merger and rename
Our first step is a temporary and intermediate one. We'll be essentially deleting AutoRegLib and moving all of its code into Quark. We'll take the chance to rebrand it as "Zeta" (more on this later), and to change package names.
Additionally, as this is temporary, code from the Zeta package will be blocked from referencing code in the Quark package. This temporary change will allow us to develop the two simultaneously for faster iteration.
Figure 3: Quark project structure as of f2
Zooming in a bit on the Quark project, we can see what the mod's structure is at this point.
The main takeaway here is that everything is tied up with Forge's systems - this being our main issue. Quark's Game Modules in particular are tied in a somewhat insidious way, in that each module has several instances of Forge's event system, so to fully decouple the "content", we'd need to decouple all of them.
Figure 4: Zeta-Quark merger
The first order of business here is to make the "Zeta Registry System" and the Quark Module Loader into just one component.
The end goal here is for Zeta to be a separate library, (think "AutoRegLib ++"), which will allow modders to quickly access the same code paths and development flow that we use for Quark to create modular and configurable mods super fast without having to deal with any of the boilerplate. Essentially it's us splitting off all the base code from ARL and Quark into its own thing other mods can just hook into, similarly to how Patchouli was a spin-off of the Alquimia mod at the time.
The second order of business is to create an abstraction layer between the module loader and the actual modules, this is represented by the blue element "«Zeta Module Loader»"". The «» around the name signify this element doesn't actually contain any code per se, but just the promise that code will exist there.
The white arrow coming out of that block to the left can be read as "is a", as in "Zeta-Forge Module Loader is a «Zeta Module Loader»". The "Zeta-Forge Module Loader" block, therefore, fulfils the promise by providing the needed code. This split will naturally be relevant once we add in a Fabric one.
The point of this is to essentially "untie" the Quark Game Modules from Forge, as they'll be speaking to the «Zeta Module Loader», which itself can be written in Forge or Fabric, but the game modules themselves don't really care, as long as it provides the needed functionality.
The biggest part of this transition will be to implement an event system similar to Forge's, so that we can just pass each Forge event over to a "wrapper" (that doesn't reference any Forge code) and then run the events to our game modules. As Fabric uses a different event system, once we make the Fabric version, we can then just pass the Fabric events to the same wrappers.
So, instead of using Forge's net.minecraftforge.event.LivingTickEvent
, for example, we write our own org.violetmoon.zeta.event.LivingTick
, which looks essentially the same, and when Zeta's forge implementation sees a Forge LivingTickEvent
happen, we pass the details over to a Zeta LivingTick
event and send that to our game modules, essentially decoupling them from Forge.
There's a few other details that need to be taken care of here, such as the @SideOnly
issue with subscriptions, but that's beyond the scope of this post.
Figure 5: Loader decoupling
With the modules decoupled, we now need to make changes to the moduler loader components themselves so that only the bare minimum is Forge dependent.
The orange "Zeta Common Module Loader" component will contain all of the code that isn't intrinsically tied to Forge, whereas the "Zeta Forge Impl" will contain only the code that is, while also containing all of Common code.
In the future, you can visualize a "Zeta Fabric Impl" block also existing, with the same inclusions of "Zeta Common Module Loader" and "«Zeta Module Loader»" but communicating with Forge instead of Fabric.
At this point, no Fabric code exists yet, but the Zeta code is compartmentalized in a way that any code that isn't tied to Forge is put aside, so that when we do have to write Fabric code, it'll be a lot less.
Figure 6: Zeta split
With AutoRegLib destroyed, Quark's module loading code genericized and moved into the new Zeta, and both mods' codebases reformatted to be less tied to Forge, we split off the Zeta mod into its own project once again.
Zooming back out to a higher level, we see there's fewer components tied to Forge. The Zeta and Quark projects still require Forge to load, but the code inside is mostly platform agnostic.
While there is still no Fabric code yet, comparing to our initial structure, the Forge-dependent code will have been minimized, and now we can write code for other loaders, as long as those loaders can fully implement the Zeta Common Module Loader and any additional Quark specific features it may require.
At this point, private testing will happen in our supporter community to ensure this split didnt break the entire mod horribly, which has a reasonable chance to happen here.
Figure 7: Fabric implementation
This one looks somewhat large and scary, but in simple terms:
- Any remaining forge-centric needs in Quark are split off into a common package the same way we did for Zeta in Figure 5
- Fabric implementations are made for Zeta and Quark
This step is non-trivial, as we'll have to re-implement all the Forge events Quark requires using mixins on the Fabric side in a way that they function in the same way. A lot of testing will have to happen here.
Once again, a lot of private testing will happen in our supporter community before we're confident in the results, as there will surely be a lot of minor idiosyncracies to both loaders we'll have to take in consideration at the time.
On 1.20
Our current plan is to finish Project Zeta in the 1.19.2 codebase before we begin the 1.20 port. However, due to us wanting to focus on stability for 1.19.2 for now, Zeta and Quark-Fabric will only be publicly available for 1.19.2 as an Alpha distribution that will be exclusive to Modrinth.
The main reasoning for this being that CurseForge sucks for multiple loaders in one project, and having a "Quark (Fabric)" version available there implies it's supported and safe to use, which we can not guarantee in the 1.19.2 branch in a way that won't needlessly delay the 1.20 update.
Either way, once we're confident its at least reasonably playable and won't explode on contact, we intend to release Zeta and Quark-Zeta for 1.19.2 on Modrinth as an Alpha, for those who might want it, and then immediately begin on getting the full stack on 1.20.
Zeta for Modders
In order to get the user facing mod available ASAP, Zeta's documentation and modder-facing extra components will happen after the 1.20 release is ironed out.
The end goal is for Zeta to be a structural piece that anyone who wants to develop a modular and heavily configurable mod like Quark for both loaders can easily just grab and start writing the game pieces instead of being mired in implementation. Alas, the mod players will come first here, so anyone wanting to use the platform will have to wait a bit for us to ensure it at least works with Quark for everything else to come in place.
Q&A
Aren't you supposed to be on hiatus? Why are you here making UMLs?
A: I'm on hiatus from developing, I've been in contact with everyone behind the scenes making sure stuff runs well. We've been in talks about doing this for a while now, and someone had to chart the path, so I ended up doing that.
Why announce this now when it's still over a month away?
A: I finished the internal document, so I thought it would be a good time to share. We're also aware of the team of developers working on their own Quilt version of the mod, so we decided it would be best to just let everyone know this will be happening rather than hold our hands close and risk buring their time for no reason if they'd rather wait on this.
Any idea when this will be ready? When can I play Quark on Fabric?
A: No clue, please don't ask, it's too early to know.
Why release a public version in 1.19.2 if you're not going to support it?
A: Whether we support it or not, due to the way we're developing it, that version will exist either way, so if our choices are to have nothing at all or something rickety that players can opt-in to use if they want to, that second one at least gives them the option.
Who's working on this?
A: Wiresegal, Kamefrede, and myself (soon)-