Quilt's (EXTREMELY LATE) November Update
September 28, 2023
It's been quite a while since the last proper development update here, with the last one being our 2021 October update. In this fairly enormous post, we'll be covering all the biggest developments since entering beta! We'll be going through Quilt Standard Libraries, Quilt Loader, Quilt Mappings, Quilted Fabric API, Chasm, Quilt Kotlin Libraries, Cozy, and a few other things. Taking the crown for the new longest blog post, I hope you enjoy seeing what we've been working on!
Quilt Standard Libraries
QSL has received just over 30 new APIs in the time since we last posted about QSL development on the blog. We're making the executive decision that that reflects on how amazing its contributors are at making APIs, and not how slow us over in the writing team are with releasing our blog posts. Before you start thinking about just how long it's been, let's get into the updates!
Starting off with April of 2022, we saw the initial version of the Registry Entry Attachment API, or REA for short. This is a pretty unique API that allows developers to associate arbitrary values with any objects managed by registries, such as items or blocks. If you are familiar with Java's collections, this functions as a
Map, connecting registry objects to values, like how tags function as a
List of items with a certain property. We'll see later how this is useful by taking a look at a few of the APIs that rely on it. It has continued to get updates, and is now incredibly powerful. It's not limited to simply registering through code, and supports datapacking so that more than just mod developers can make use of it! REA forms the basis for quite a few other Quilt APIs, such as the API for adding enchantment table boosters, flammable blocks, and compostable items.
In May, we added an API for registering new resource pack providers. This allows mods to use code in place of making their own static resource packs in the files, which lets developers do neat things like generating textures at runtime, and then zipping them up into a resource pack that can be applied and removed in-game at the user's will! As always with a unified API, this also means fewer conflicts between mods all trying to do the same thing with the same mixins.
Not stopping with the new APIs, we added our own Block Entity API, which gives developers the ability to register their own block entities, sync their data from server to client, and use the same block entities on multiple blocks! An essential for a full Minecraft modding API, this is an important step towards making standalone development with QSL possible for big mods. In addition, we shipped two other big updates:
- Caching for mod-provided resource packs, which was quite a big improvement to resource reload performance! It reduced the startup time of the Blanketcon 2022 modpack by seven seconds, according to some simple benchmarks.
- Added a configuration option to disable Minecraft's "Here be dragons!" warning screen, since it's pretty much impossible to avoid triggering it when making mods that touch world generation.
Speaking of world generation, in July we introduced another unique new API in the form of the Surface Rule API. This is a neat little system for injecting new types of surface world generation into the three vanilla dimensions. You may know this from the iconic Trans Ground test mod, demonstrates the power of this API by turning the ground into a beautiful, pastel transgender flag. In addition, we shipped the Item Content Registries API, allowing you to attach compostability and custom fuel times to your items!
August brought yet more uses of the REA system, with the Block Content Registries API! Just like Item Content Registries giving us data driven fuel times and compostability, Block Content Registries gives us control over stripping, waxing and flammability in our datapacks! But if you'll believe me, that's one of the smaller APIs in terms of code this month. We also got:
- Registry sync! This is yet another critical step towards standalone QSL development. Registry Sync is short for registry synchronisation, which makes sure that both your Minecraft client and the server you're connected to have the same sets of items, blocks, entities, and other things. It's necessary in order to have content mods working QSL-only.
- The Multipart Entity API, an API for creating your own huge, complex entities. The "multipart" in the name comes from the fact that this is support for entities with multiple sub-parts, like the Ender Dragon. The dragon has multiple hitboxes, and now you can too!
- Alas, a sad story. The QSL DataFixerUpper (DFU) API was a short-lived feature that allowed developers to register their own Datafixers, the same system that Mojang uses to upgrade worlds between versions. This API ran into a critical problem: DFU wasn't built with a heavily modded game in mind, and it had issues, namely with trying to update the IDs of items in modded containers. Press F to pay respects, and other gamer-y things here. I write more code nowaways than I play video games. Sad.
- To finish off this amazing month, we introduced the Bow and Crossbow APIs, making it simple to add your own bows and crossbows in your mods. Nice!
In September of 2022 we had another massive month (two in a row!) with 4 cute new APIs. These include:
- A fully featured Virtual Resource Pack API, building off the work done in the Resource Pack Provider API in order to provide more goodies like in-memory resource packs, events, and better ways to add resources to packs.
- A big set of entity-related events, allowing mods to easily react to events like entities being killed, entities being loaded, entities moving between dimensions, and more!
- A pile of entity object builders to simplify setting up points of interest, vehicles, villager trades, and (again) more!
- The Recipe Remainder API, allowing you too to leave buckets behind when making recipes for your custom cakes. Someone more creative would have come up with something cool to suggest doing with this API. I am not that person. We are looking on suggestions to help with a duplication issue for the API, so give your advice!
Next month we finally calmed down for the winter, introducing a new set of events for registry manager setup and loading, and fixing a small pile of bugs. A nice October.
In November, we added the Entity Selector Options API, allowing modders to better integrate their features with Minecraft's commands system via meshing into the way entities are filtered for autocomplete. Additionally, we added a big API: the Status Effect API! Using it, mods will be able to easily add status effects, and customise things such as whether the effect will be cleared when drinking milk. Amazing!
Moving on to 2023, In January we added an API for listening to and modifying chat, highly useful for server mods! After that, we added the Armor Rendering Registry API, allowing registration of, as the name implies, different types of rendering for armor that are associated with certain armors. It's since been updated with support for layers, and is quite powerful!
In February we shipped one big new API: Quilt Game Tests. This is a helpful API for using Minecraft's fantastic Gametest system, which is the way that Mojang themselves test the game before releasing updates. It lets you easily create tests by building structures in-game, and then writing code that uses that structure and defines a test with an expected result. For example, you could write a test that uses a rail structure, places a minecart on it, and tells the game that after 10 seconds the minecart should reach the other end of the track. Neat! Using this API is the perfect way to help make sure that your mod is bug-free. Which admittedly us developers are pretty bad at. But if you are one of the rare folks who has the patience to write tests, this is the perfect API for you!
Rapid fire API time! Let's go through March and April why don't we.
- March brought a couple new entity-related events to help you out with writing reactive code. Cool!
- April gave us the Dynamic Registry Registration API, which, well, allows you to register your own dynamic registries. This means that you can hook into Minecraft's registry system and define your own data to be loaded from datapacks, allowing users to heavily customise your mod without touching any code.
- Registry Sync V2. This is an enormous update to Quilt's registry sync, which we talked about a while ago in this post! First, it adds a system for protocol versions, which allows you to define what's compatible with what, instead of registry sync deciding for you. Secondly, we released validation of block and fluid states, which enables more reliable sync. But we weren't done! This update also adds more configuration, such as disabling sync outright, an API for checking what optional entries the client has, and much better error messages.
- Entity Spawn Data API. This is a helpful little API that allows you to add more context to entity spawns, making creation of entities with different variants easier! For example, this could be used to outdo my own mod and make the best rainbow entity system out there!
- Finally, keeping in line with Quilt's excellent support for datapacks, we added the Data Callback API, which allows making events controlled by datapacks! This API allows you to make separate "event" files to modify data-driven values.
Since May, we've been cleaning up code, fixing bugs, and mostly adding minor features. QSL is becoming a super solid collection of APIs, and I'm not sure I realised just how solid it was until writing this post. We'll be right back after I port my mods.
Loader has seen an incredible amount of innovation, from going, to quote the team, "stable-ish" in May of 2022 to the beginnings of loader plugins early this year. Let's get right into it with the first release:
0.16.0 came to us with a massive amount of bug fixes, to make sure we were ready to uphold our promise of stableishness. It didn't have many flashy updates, but was important to make sure loader was ready for the big features that were to come, the first of which being support for Fabric loader internals! While using internals is still heavily discouraged by both us and Fabric, this means that we can have better compatibility for mods whose developers who haven't yet had a chance to update their code.
Next month, we (or, well, Glitch and Alex. For some reason when you develop for Quilt you end up considering yourself part of a hivemind. undiagnosable) shipped quite a big new feature: the initial version of our unified configuration library, Quilt Config. This library aims to finally resolve the ancient modding issue: "every mod JiJs nightconfig aughhghhhhhhhhghhh" by making sure every developer has access to configuration utilities right in the loader. By default, Quilt Config supports TOML and JSON5 reading and writing, and has the capacity to be extended for more file formats if you'd like to toss us a contribution! It's consistently being updated, with new goodies like the
ReflectiveConfig API having arrived earlier this year.
In August of 2022, the mod table was delivered to the world. This is a new way of showing mods in logs that has a couple important innovations over the old tree-esque design. It allows us to:
- Show far more information in the log files, providing critical details for the tireless helpers in our Discord, forum, and elsewhere to use when fixing issues. Neat!
- More easily parse the log for ✨automation✨! If you hang around the aforementioned Discord server, you may have noticed our adorable bot Cozy searching through logs and helping (quite literally) hundreds of users. Cozy has the ability to detect Quilt-incompatible Fabric mods, analyse which mods are erroring, and provide tons of other help via parsing logs.
The Loader team wasn't done yet though, and came back in October with their biggest update ever,
0.18.0. This release, along with having more beta versions than I had previously thought possible, introduced new annotations, better errors, and subfolder mod loading! Let's run through what those mean.
- Our own
@DedicatedServerOnlyannotations. These replace Fabric's
@Environmentannotations, and allow mods to avoid pesky sidedness errors. Lovely!
- Better solver errors. Solver errors are the "the game can't load with this mod!" things you'll see in the window that opens if the game crashes when launching. We cleaned up quite a few things and updated some particularly nasty ones to make most readable by those who haven't invested more time into developing for Quilt than they have playing the game.
- Loading mods from subfolders! This update gives you some amazing control over the way your mods are loaded, with a few handy tricks outside the main feature of searching all subfolders of the
modsdirectory for more delicious mods to load. For one, all folders that start with a digit will be checked against the current Minecraft version, and only loaded if it matches! This means that you can name a folder, for example,
1.18, and mods in that folder will only be loaded if the current game version is
1.18. You can also specify greater than or lesser than by naming your folders
<[version]respectively. To cap things off, folders starting with a dot (
.) will be ignored entirely.
In November we swapped over to a new standard called FlexVer by Unascribed that helps us more cleanly sort versions and extends the SemVer
major.minor.patch convention used by... well... most everything in the open-source world. In particular, this helps us out with mods who use versioning schemes that can't be translated into the
1.2.3 world of SemVer without a major rethinking of some things. Which is exactly what FlexVer does! The team also wrote up a fantastic GitHub wiki and added per-game-instance configuration of Quilt loader settings, which are, predictably, documented on that wiki!
Not stopping for a minute, Alex and Glitch then gave us a December present in the form of dependency overrides! This is a clever feature that will let you change things about mods' dependencies without having to go to the bother of recompiling them. For example, this is useful if a mod has a hard dependency on a Minecraft version, but you want to test if it works on the bleeding edge of block games. Dependency overrides let you change the mod's Minecraft dependency to whatever you want, letting you try it out on other versions! Do note that if you're messing with dependency overrides you can't expect mod developers to support you at all. Mods can't be expected to always work on other versions of the game, but if you're lucky you might find some!
After spending a month restraining themselves from releasing more versions,
0.19.0 came in February of 2023! This brought initial support for one of the big features we set out to make with Quilt: loader plugins! This is a system that allows an all-new type of mod to be created: a mod for the loader itself. Some examples of things that you could do with loader plugins are hooking into mod loading to add support for different programming languages, mods from different modloaders (in fact, Fabric support is implemented internally via a plugin!), and other delightful nonsense like pre-launch GUIs. As of writing, support remains behind the
-Dloader.experimental.allow_loading_plugins=true JVM flag, but progress is continuing on refining plugins and adding functionality for their full release. This release also brought support for another flagship Quilt feature: Chasm, our replacement for Mixin! Chasm allows for more compatibility in between mods modifying the same Minecraft code. Currently, Chasm support remains more proof-of-concept than anything as Chasm hasn't yet reached a fully featured release. In order to try it out, use the
-Dloader.experimental.enable_chasm=true flag! To finish things off, Quilt loader solved the age-old of mods breaking randomly due to internal changes by heavily restricting access to its internal classes. Although it's a bit more complicated than that. To avoid breaking existing mods with dependencies on internals, this will only apply to new internal classes. The same system can also be used via the
@ModInternal annotation, which modders can put on their own classes to seal them off from tampering!
In June, we shipped yet another big version of loader! This one further improved solver messages, as well as adding some new features:
- A per-instance cache for storing sorta-persistent files. This comes with a nice API for developers to use!
- A new API that developers can use to open up custom error dialogs, the same way loader does for version mismatch errors and whatnot. This API also allows the developers to implement buttons to help the user fix the issue. Neat!
- Finally, a bunch of internal file system things were reworked and rewritten in order to make loading mods faster and lighter, using much less memory and much less time.
Just next month, the loader team gave you better dependency overrides, as well as a global configuration and cache! As with all good things, the dependency override format is defined in the loader wiki so you can get straight to overriding.
To finish things off, last month's updates delivered:
- Yet more memory usage and speed improvements, helping you to play more Minecraft and spend less time waiting! Send your local loader team some love today.
- Mod validation! This is a helpful tool that our developers can use to check for bugs in Quilt loader, and that means it'll help us fix more of them!
Quilt Mappings has had an amazing year, and it's not even because I made my debut on the mappings team! This post isn't going to cover name updates, only tooling updates, since name changes are going on constantly in the background and if we tried to name every PR we'd be here all day. Speaking of tooling, we've introduced an absolutely critical feature allowing mappings on loom, improved linting, completely overhauled our mapping editor, and added more automatic mapping! Starting with June 2022, let's take a look.
To start off our post-beta bettering, we moved over the functionality of Fabric's Stitch tools into our own in-house Enigma plugin, which makes the structure of mappings as a whole quite a bit cleaner. Neat!
Next, in July, we upgraded our newly created plugin with a new feature: automagic mapping for simple fields. This allows Enigma, the tool we use to make mappings, to derive names for fields and parameters out of a manually written file. For example, since in most classes there's only one
Codec field, it will automatically be named
CODEC by the plugin. Lovely! This allows our mappers to do less work, and is generally really cool.
Moving on to October, we introduced the single most important addition to QM: intermediary publishing! Those who aren't deep into modding are probably asking: what in the name of Pineapple does that mean? Good news: I'll tell you. Quilt uses our own system called Hashed Mojmap, which takes Mojang's official names and scrambles them into copyright-free hashes for us to use at runtime, making sure that we're not violating the terms of Mojang's official mappings while decreasing the chance that names will change with Minecraft updates. A Quilt mapping looks like this:
FIELD f_abcdefg MAX_APPLES F
Its type, followed by its hashed name, followed by its mapped name, followed by its class. Contrarily, a Fabric mapping will use something more like
field_783462 in place of the hashed name, using a specification they call Intermediary. We introduced Hashed to fix a couple issues with Intermediary: namely, Hashed allows for the mappings to be automatically generated instead of manually like Intermediary. So why does any of this matter? Well, Fabric's Loom tool that's used to compile mods only understands Intermediary mappings, and doesn't understand how to apply Hashed mappings to Minecraft. This means that Quilt Mappings in its base form is incompatible with Loom. We've patched this in our version of Loom, but it means that Quilt Mappings can't be used to develop Fabric mods. Intermediary publishing solves this, by providing both a Hashed-based and Intermediary-based version of Quilt Mappings for you to use, allowing development using QM on Fabric!
In December, we saw an arguably more important toolchain update: to quote my notes, "SAY HELLO TO IX0RAI BAYBEE WE'RE SLAYING IT'S MAPPING TIME" (I joined the team. This is important because it's my blog post and I can do whatever I want). We also introduced more checks to be run on pull requests, such as making sure that mappers haven't accidentally left mappings in the default
net/minecraft/unmapped package. Cute!
Continuing with improving our mapping lint action in 2023, we added a new check for spelling issues, simultaneously resolving dozens of typos all around the codebase! The final count resolved to about 100 typos that slipped through the cracks, and our check prevents this from happening again. Still in January, we focused on Enigma's GUI element for a little bit, fixing some major problems to help mappers work faster. First off, our most sly and mysterious mappings team member, Iota, had already given you decompilation via the incredible Vineflower decompiler, making the code you're mapping easier to understand. Of course, being the queen she is, she only announced this enormous feature to one single channel on the Discord. That's not even to mention the superb keybind system she introduced even before that. But going back to the present day, we gave you the ability reorganise and the right and left panels as well as close them, giving more personalization as well as more space for your code! We also introduced a merged class tree panel letting you see both obfuscated (unmapped) and deobfuscated (mapped) classes together in one place. Moving away from Enigma, we also added a helpful feature for PR review: comments on your commits to show the code difference, which gives critical context for the actual impact of a rename.
In February we kept working on enigma, implementing new, clear notifications, which trade off the Red Triangle of Bad UI Design in favour of the bubble style used by most everything. Longtime mappers will know what this means. We also cleaned up quite a bit of code and added restoration of recent projects, bringing Enigma closer to being a more standalone app! No, we're not trying to be more like JADX. We'd never do such a thing.
Over the next few months, we kept improving mapping linting (validating mappings for issues before a release), adding more tests, and packing Enigma with more features! The biggest addition to Enigma was cute little icons next to each class in the tree, letting you tell at-a-glance what needs work and what's complete. We also implemented some new features into the plugin, including an extremely cool feature which will automatically map getters and parameters for a field when you name it. The mappings team is always looking for more members, so if you'd like to contribute to our tooling or improve our mapping coverage, make sure to let us know!
Finally, we have quite a few ongoing projects, including:
- Quilt Mapping Tools, our new unified backend for mappings tooling. This will help simplify the web of projects that contribute to each and every release of Quilt Mappings, and consequently take some load off your local QM wizards via allowing mere mortals to understand how all this works.
- Yet more updates for Enigma, including migrating to the aforementioned Quilt Mapping Tools. Enigma
2.0will be more than just that though, and work is continuing in the background on it. You can check out the milestone on GitHub to see what's planned so far.
Quilted Fabric API
Despite QFAPI being one of the less flashy cogs in the Quilt machine, it still requires quite a bit of love. Luckily, our fantastic QFAPI team, having expanded by two members just recently, is up to the task! While most of the work is simply updating to new Fabric and Minecraft versions, there have been quite a few changes to its internals! Of course, with this project always needing to keep up with FAPI, contributions are very welcome.
Firstly, we've Quiltified four Fabric APIs! This is an admittedly silly name for the process of taking an API from Fabric API and turning all its methods into overloads of QSL APIs, simplifying the project overall. Every API Quiltified is one less API relying on Fabric code! The APIs ported over the last while are:
- The Screen API
- Fabric's Registry Sync
- Entity Load Events
- Block Content Registries
Finishing off our 2022, we introduced a helpful safeguard against mod errors that Ennui has previously posted a devlog about on our Discord. To summarise quite a long post, since QSL's APIs for attaching properties like flammability to items and blocks is based on Registry Entry Attachments, attachment of those properties can only be done on items that are already registered. Fabric's APIs take a more static approach, which means they lacks that kind of validation. Since we of course can't expect mod developers to change their code for compatibility, we came up with a clever solution: Deferred Queues. To simplify it a little, when a mod tries to register properties for an item or block that is not yet in Minecraft's registries, QFAPI will intercept it and only apply the property once addition to registries is complete. With that, we perfectly replicate the behaviour of Fabric's APIs without relying on them in QFAPI!
Chasm: Collision Handling ASM
Chasm has improved a lot in the last year! It's been going through constant planning, prototyping, and testing, and has seen two big events in what I've dubbed the Chasm Timeline. Firstly, Chasm and its tooling hit version
0.1.0 in July of 2022! This update had three key points.
- Firstly, quite a bit of the backend was reorganised and rethought from the prototype in order to create a much faster system! A must for the end goal of using CHASM as the new backend powering Mixin.
- The internal library used to parse compiled transformations into something ready to be applied has been moved from Antlr4 to an alternative called JavaCC21. This allows CHASM to be used as a standalone JAR, without any runtime dependencies.
- The specification for Chassembly files, or the compiled transformations Chasm will read when the transformations are to be applied, has changed quite a bit! It's now a more or less stable format, with no more major changes planned.
And now, the flashier point: our old project lead, CheaterCodes, managed to use Chasm to modify Minecraft! Here's the obligatory iconic screenshot of Minecraft's splash text overridden via Chasm.
Finally, since the Chasm team can't actively work on the project for various reasons (mostly lack of motivation), we're looking for folks who can take it to the finish line! You can talk to the old team in the Discord if you're interested on getting this unique tool into production.
Quilt Kotlin Libraries
From its introduction in June of 2022, to its stable release in December, to today, Quilt Kotlin Libraries has been being updated, QFAPI-esque, to new Fabric Language Kotlin versions by its tireless team. Despite that, they've still managed to find time for quite a few updates! This includes a huge set of builders, or easily ways to instantiate objects, for commonly used Minecraft classes:
- Various recipe classes
- Registry attachments
- Commands with Brigadier
We've also introduced two DSLs, or Domain Specific Languages, for working with the aforementioned Brigadier and with registries. These are sort of mini scripting languages that make it both easier and faster to work with their target system. As an example, here's two different ways to register blocks with the Registry DSL:
TEST_BLOCK withName "test_1"
TEST_BLOCK withName "test_2"
TEST_BLOCK withName "test_3" toRegistry Registry.BLOCK
This keeps a more natural language order as well as concise grammar, and just makes your code prettier!
There's also a veritable grab bag of miscellaneous other utilities, such as a Kotlin wrapper around event registration, overloads on math operations for vectors and positions, and Kotlin serialization around Codecs. The Kotlin team has also set up a few wrappers to make working with QSL's Java syntax nicer.
Moving away from Minecraft for a minute, what have we been doing with our in-house Discord bot, Cozy? Unlike the bots I made back in my Phase (we don't talk about how I learned to code), it's been getting consistent updates! Let's run through the big ones.
- Cozy now has a command that gives you a self timeout, meaning it'll prevent you from sending messages, but you'll still be able to read messages. This is nice for when you need to make an exit from a heated discussion, or just need to force yourself into taking a break from Discord for a bit.
- We've implemented our own AMA, or Ask Me Anything module, to use during our usually-monthly development updates. On the first Saturday of every month, we poke our developers to escape their IDEs for a couple hours and talk about what they've done the previous month, so that the community can stay caught up with what's going on in the World Of Quilt. Cozy's AMA system helps us with the end of the meeting, where we open ourselves up to questions and let everyone ask the developers, as the name implies, (almost) anything!
- All Cozy modules have been published on our Maven server, for use as libraries in your Kord projects. Neat!
- Finally, the thing that all Quilters know Cozy for: log parsing. This is an absolutely incredible feature that detects when Minecraft logs are posted in the Discord, and analyses them to see if there's a simple solution. Cozy's log parsing can detect Mixin failures, out-of-date first-party libraries (QFAPI and QKL), mods that will have broken features, Fabric mods with Quilt replacements, and mods that are incompatible with Quilt! The list of incompatible mods is open-source on our website repository, so please open a pull request or tell us on the forum post if you find any new ones!
Finally, let's throw in a few miscellaneous updates. This isn't an exhaustive list, but these developments caught my eye!
- We've cleaned up and improved the specifications of our Meta server, giving it a fancy new OpenAPI coat of paint as well!
- The Community and Toolchain Discords servers have been merged into one monolithic server, where both the developers and the community will be able to live together in harmony until the Fire Nation attacks.
- Quiltflower, our decompiler project, has become Vineflower! Moving out of the umbrella of a Minecraft-centric project means that the Vineflower team can simply deal with the decompiler, and not worry about the rest of the project, which many of them didn't have a large hand in. While we're sad to see the team leader Jasmine and the rest of the developers go, it's amazing to see something incubated in Quilt becoming an even bigger project! You can read more about this change in its dedicated blog post.
- The Quilt Wiki, your favourite resource on how to mod with Quilt, is finally gaining some steam thanks to a rewrite! We've just merged a huge PR to outline the planned structure of the wiki, add a couple critical articles, and clean up the look of the rewrite. If you'd like to contribute, we're always looking for writers!