Giter VIP home page Giter VIP logo

quilt-standard-libraries's Introduction

Quilt Standard Libraries (QSL)

Java 17 GitHub license Mod loader: Quilt Version

Essential standard libraries for the Quilt ecosystem.

The Quilt Standard Libraries gives modders Quilt-exclusive tools to add new and exciting features to their mods.

Note: At the moment, the Quilt Standard Libraries are in beta, meaning issues may arise and should still be treated as experimental. Please make an issue or talk to the QSL team on discord or on the forum before writing any PRs.

Repository structure

The repository has 2 main parts:

  • The library folder. This contains all the libraries that are part of the Quilt Standard Libraries.
  • The build-logic folder. This is an included build in Gradle and contains most of the buildscript used inside the libraries. This keeps the buildscripts inside the library folder as minimal as possible; definitions of data rather than logic.

Features

Here are multiple charts of features available in QSL which also serves as a comparison chart with Fabric API.

The charts are organized by QSL libraries.

Quick legend:

  • โœ” = Included
  • โŒ = Not Included/Not Yet
  • ๐Ÿ™… = No plans
  • ๐Ÿšง = Work In Progress

Core Library

Feature QSL Fabric API
Auto Test Server argument โœ” โŒ
Event API โœ” โœ”
Event API - Phases โœ” โœ”
Event API - Events as Entrypoints โœ” โŒ
Gametest API โœ” โœ”
Initializer Entrypoints โœ” โœ” (in loader)
Networking API โœ” โœ”

Crash Report

Feature QSL Fabric API
Crash report extra context โœ” โœ”
Crash report extra context API โœ” โŒ

Core - Lifecycle Events

Feature QSL Fabric API
Client Lifecycle Events โœ” โœ”
Client Tick Events โœ” โœ”
Client World Tick Events โœ” โœ”
Client Block Entity Events โŒ โœ”
Client Chunk Events โŒ โœ”
Common Lifecycle Events โŒ โœ”
Server Lifecycle Events โœ” โœ”
Server Tick Events โœ” โœ”
Server World Load Events โœ” โœ”
Server World Tick Events โœ” โœ”
Server Block Entity Events โŒ โœ”
Server Chunk Events โŒ โœ”

Core - Registry

Feature QSL Fabric API
Addition Events โœ” โœ”
Addition Events Helper โœ” โŒ
Registry Syncing โœ” โœ”
Registry Syncing - Exclude Specific Entries โœ” โŒ

Core - Resource Loader

Feature QSL Fabric API
Load mod resources. โœ” โœ”
Resource Loader Events โœ” โœ” (in lifecycle, non equivalent)
Built-in resource pack API โœ” โœ”
Programmer Art API โœ” โœ”
Group resource pack API โœ” ๐Ÿ™…
Resource Pack Provider API โœ” โŒ
Resource Reloaders โœ” โœ”
Resource Reloaders - Advanced Sorting โœ” โŒ
Virtual Resource Packs โœ” โŒ

Block Library

Feature QSL Fabric API
Extended Block Settings โœ” โœ”
Extended Material Builder โœ” โœ”
Block Render Layers API โœ” โœ”
All Block Constructors Are Public โœ” โœ”
Block Entity Type registration helper โœ” โœ”
Block Entity Type post-creation supported block editing โœ” ๐Ÿ™…
Block Entity Syncing Helper โœ” โŒ
Block Content Registry - Flammable โœ” โœ”
Block Content Registry - Flammable (data-driven) โœ” ๐Ÿ™…
Block Content Registry - Flattenable โœ” โœ”
Block Content Registry - Flattenable (data-driven) โœ” ๐Ÿ™…
Block Content Registry - Oxidation โœ” โœ”
Block Content Registry - Oxidation (data-driven) โœ” ๐Ÿ™…
Block Content Registry - Sculk Frequency โœ” โœ”
Block Content Registry - Sculk Frequency (data-driven) โœ” ๐Ÿ™…
Block Content Registry - Strippable โœ” โœ”
Block Content Registry - Strippable (data-driven) โœ” ๐Ÿ™…
Block Content Registry - Tileable โŒ โœ”
Block Content Registry - Tileable (data-driven) โŒ ๐Ÿ™…
Block Content Registry - Waxing โœ” โœ”
Block Content Registry - Waxing (data-driven) โœ” ๐Ÿ™…

Data Library

Feature QSL Fabric API
Advancement Criterion Registration Helper โœ” โœ”
Recipe API โœ” ๐Ÿ™…
Registry Entry Attachments โœ” ๐Ÿ™…
Client-fallback/Client-only tags โœ” โœ” (fallback only)
Client-fallback/Client-only tags - integration within Vanilla methods โœ” ๐Ÿ™…
Convention Tags โŒ โœ”
Data Generation ๐Ÿšง โœ”
Loot Table API โŒ โœ”
Resource Conditions โŒ โœ”
Component API (like CCA or Forge capabilities) ๐Ÿšง โŒ

Entity Library

Feature QSL Fabric API
EntityType registration helpers โœ” โœ”
Entity Events โœ” โœ”
Multipart Entity API โœ” โŒ
Point of interest helper โœ” โœ”
Status Effects API โœ” โŒ
Tracked Data Handler Registry โœ” โŒ
Trade offer API โœ” โœ”

GUI Library

Feature QSL Fabric API
Screen API โœ” โœ”
Item Tooltip Event โœ” โœ”
Tooltip Component - Event โœ” โœ”
Key Binds API ๐Ÿšง โœ”
Screen Handler API โŒ โœ”

Item Library

Feature QSL Fabric API
Item Extension - Bow โœ” โŒ
Item Extension - Crossbow โœ” โŒ
Item Groups โŒ โœ”
Item Settings โœ” โœ”
Item Settings - Custom Item Setting โœ” โŒ
Item Content Registry - Composter โœ” โœ”
Item Content Registry - Composter (data-driven) โœ” ๐Ÿ™…
Item Content Registry - Fuel โœ” โœ”
Item Content Registry - Fuel (data-driven) โœ” ๐Ÿ™…

Management Library

Feature QSL Fabric API
Commands โœ” โœ”
Client Commands โœ” โœ”
Game Rules โŒ โœ”
Entity Selector Options โœ” โœ”
Message API โœ” โœ”

Rendering Library

Feature QSL Fabric API
Renderer API โŒ โœ”
Data Attachment โŒ โœ”
Hud Render API โŒ โœ” (limited Event)
Built-in Item Rendering โŒ โœ”
Block Entity Renderer Registry โŒ โœ”
Armor Rendering โœ” โœ”
Color Provider Registry โŒ โœ”
Entity Renderer Registry โŒ โœ”
Entity Model Layer Registry โŒ โœ”
Living Entity Feature Renderer Registration Event โŒ โœ”
Data-driven Entity Models ๐Ÿšง ๐Ÿ™…
Data-driven Animations ๐Ÿšง ๐Ÿ™…
World Render Events โŒ โœ”
Fluid Rendering โŒ โœ”

Transfer Library

Feature QSL Fabric API
Transfer API โŒ โœ”

Worldgen Library

Feature QSL Fabric API
Biome Modifications API โœ” โœ”
Add Nether Biomes โœ” โœ”
Add End Biomes โœ” โœ”
Dimension API โœ” โœ”
Surface Rule API โœ” โŒ

Miscellaneous Library

Feature QSL Fabric API
Modded DFU API โŒ โŒ
API Lookup API ๐Ÿšง (through Component API) โœ”

quilt-standard-libraries's People

Contributors

alexiil avatar ampflower avatar cocona20xx avatar cypher121 avatar ennuil avatar i509vcb avatar juuxel avatar kichura avatar kroppeb avatar lambdaurora avatar lemmaeof avatar leo40git avatar lostluma avatar lukebemish avatar magneticflux- avatar maximumpower55 avatar moehreag avatar noahvdaa avatar nocomment1105 avatar oliver-makes-code avatar oroarmor avatar patbox avatar peaceheis avatar platymemo avatar pyrofab avatar silverandro avatar theglitch76 avatar tropheusj avatar virtuoel avatar williambl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

quilt-standard-libraries's Issues

Quilt Renderer API vs FREX - Request for Comments

Background
I intend to port the Fabric Rendering API to Quilt with some improvements. Some of those improvements will come from FREX. Currently, some important FREX interfaces inherit from Fabric API interfaces.

While Quilt is hopefully going to be more expansive I don't assume it will encompass all current and future features in FREX. Thus, FREX remains important to me as a separate library/API because I'm committed to maintaining separation of specification and implementation for Canvas and, someday, other renderers that want to support an open standard.

This means FREX will continue as a superset of both FRAPI and Quilt and needs to be compatible with either.

I plan to handle this by changing FREX so that it no longer inherits from either Fabric or Quilt but instead includes a wrapper for whichever is present for API consumers. For API implementations like Canvas the problem is a little messier, but I'll figure something out.

Questions to Be Answered

If FREX is a compatible superset of FRAPI and Quilt and offers features not available in either, it seems like the logical dependency to use for anyone who isn't skittish about 3rd-party libraries.

This creates some unfortunate redundancy, but many devs are skittish about "unofficial" libraries, so:

  1. Is it a correct assumption that Quilt should incorporate a non-dependent subset of FREX features, vs just directing people to use FREX?

  2. If so, what are the guiding principles for which features Quilt should have? For Fabric, one important guideline was that if it would require a very invasive change to implement, it should probably be out of scope. A similar heuristic is to avoid features that can't be readily implemented and maintained in the default renderer. (That puts the GLSL Shader API right out.)

  3. Should Quilt implement FRAPI compatibility even though FREX will be available for the same purpose? It means redundant work (that mostly falls on me) but seems necessary because of reluctance in the community to depend on "non-official" libraries and to simplify distribution and dependency management for anyone who just needs the core features.

Thank you in advance for your input.

TooltipComponentCallback causes a NPE if the mod order is not ideal

Info
Minecraft Version: 1.19
QSL Version: 2.0.0-alpha.2
Log: https://gist.github.com/alkyaly/9dcb2ad6ac1fa51f070728830ea4eaf5

Description
When trying to register a tooltip component via the event mentioned, a NPE occurs if a condition is met:

  • It's the first time a ClientEventAwareListener type of event is Event.created (Loading order)

With some knowledge-based speculation, some educated-guesses, and testing; this is due to the following order of events:
The registering-mod initializer classloads TooltipComponentCallback, its static initializer will attempt to initialize the EVENT field with Event.create, which calls the Event constructor, and subsequently the EventRegistry.register method at the bottom of it. register gets all the client_events entrypoints which loads the Quilt Tooltips API entrypoint QuiltClientTooltipMod, whose static initializer attempts to access the TooltipComponentCallback.EVENT field, which is still null since its init'ng what invoked the whole chain above and is waiting it to finish.

This does not occur when another ClientEventAwareListener is created before, due to all of the client_events entrypoints classes being loaded at the register method.

Enhancing ParameterInvokingEvent

From #9 some people had questions about the name of ParameterInvokingEvent, so this issue is here to facilitate discussion on how to enhance that marker interface.

Since I intended this to also be for static analysis, it may be worth having a way to specify which parameters are invoked upon so static analysis tools can do things like warn if a user is implementing a callback interface on a type which is not actually parameter invokable.

This could invoke adding an element specifying the indices of invokable parameters on the field or method return value for T or something else.
e.g.

@ParameterInvokingEvent(indices = {0, 2}) // The first parameter and 3rd

Plans on Key Binding API

Fabric's Key Binding API was okay, but it could have been much better with a bigger scope. While it does make key registration available, there's much more to key binds than merely registering them.
In my opinion, the key problems for a modded key bind experience are:

  • There aren't enough keys in a keyboard
  • With not enough keys, conflicting key binds are inevitable, but Vanilla only allows one key bind per key
  • And finally, with too many key binds, the key bind screen gets confusing, and when there's a conflict, it's not easy to look up what are the conflicting key

With those key problems in mind, I have planned out a key binding API which would be composed by two iterations, similarly to how the future of the classic Mac OS was split into Blue, a newer version of the preexisting OS with simpler upgrades, and Pink, which was going to be a completely new OS featuring major upgrades.

Quilt Key Bindings API v1 (Blue)

This is the simpler and more concrete iteration of the planned API, and the aim of PR #59. In fact, the PR's pretty much finished!
The features are:

Dynamic Disabling

This feature adds an active state to modded key binds, which is handled by the registry. This allows to hide a key bind from the game (๐ŸŽต options.txt being the exception ๐ŸŽต), effectively disabling it.
This feature will definitely help with the "too many keys" problems. With the ability of disabling key binds being made very practical (and being able to be done in-game), the hope is to have all mods that add non-essential key binds make them able to be disabled through their configuration.

Improvements to the Key Binds screen

The goal of the improvements is to improve the modded key bind experience, so the developers won't have to think about the possible hassles to do a certain thing; QSL will help the players.
Key bind conflicts were the target of two improvements: a textual indicator in addition to the red color, and a tooltip showing all the other conflicting keys. The former assists colorblind players and the latter assists pretty much everyone (who hasn't had some difficulty with finding the other conflicting keys in a modpack?)
And finally, the ability to middle click the bind button in order to unbind the key has been added. If you don't want a key, then you should actually be able to unbind it, not have a junk key where you deposit everything on it. I am a big dummy who somehow didn't see in the code itself that Vanilla already has a method for it. With Vanilla having a method for unbinding keys, this probably goes beyond the scope, and so, it was removed
All these improvements are mere nice-to-haves on a Vanilla context, but on a Modded one, they are going to be very important.

Getter methods for the Registry

a.k.a. getKeyBinding(translationKey), isEnabled(key), and getAllKeyBindings(includeVanilla)
The goal is to assist other mods with messing with the internals. Of course, there's GameOptions' allKeys field, however, with the extra properties managed by the registry, it might be useful to actually provide those methods through the API.

Questions:

  • Should it be getAllKeyBindings(includeVanilla) (for including the vanilla entries with the modded ones) or getAllKeyBindings(vanilla) (instead of returning modded entries, return vanilla ones)?
    • While the first is the one used by the PR, perhaps the latter would be preferable considering that the returned map is has a random order due to hash maps being hash maps; I don't know.

Quilt Key Bindings API v2 (Pink)

This is the iteration that will bring key bind utopia, the one that will do more significant changes in order to make modded key binds perfect, and hopefully, unlike the namesake, not a bloated monster that will inevitably die. But also, this is the one that's the least concrete, with only an outline being determined so far. This is the part where I'll need y'all's feedback.

config/quilt/keybinds.json

The real path is TBD, but the idea itself is simple: instead of storing the key binds at options.txt, they would be stored at a JSON file provided by Quilt. Why?
Well, messing with options.txt was already messy (the handling of disabled keys on them? not really ideal, and i needed an AW ;-;), but with the other features here, it would be even more messier. With a separate config file handled by this API, it would make the implementation of the following features (and of past ones) simpler.
Another TBD, however, is the overall schema of it, however, I think that it isn't much important to get it right now; It can be shaped later

Key Chording

A very simple concept: instead of having key binds accept only a single key, they would be able to accept combinations of them, so things like Ctrl + Shift + Space would do something in-game.
The implementation, however, will require more shenanigans, effectively replacing some of the internal key binding logic with Quilt's, but once again, considering that a keyboard doesn't have many keys, it will be an essential feature for modded key binds
"But your honor, Amecs ", you say. Well, my answer is " Death." that while Amecs is a really useful mod for key bind, it doesn't have the benefit of being a standard, and so, you can't really define a default that everyone would share. Theoretically, you could have a key sequence if Amecs is installed and have a plain one for the rest, but that would cause confusion. With a dominant standard for key chording, it wouldn't require a mod to be installed, you'll already have it installed in the first place.

Questions:

  • Should there be limits for the length of the key sequence? Of course, only one key would fit in a sequence due to how key binds work (so no A + A + A), but should 27-keys-long sequences be allowed? How would the key bind screen show them? Perhaps a scrolling title?
  • How would the registration of a key chord would even be done? Would a QuiltKeyBinding be needed, or would it be preferable to avoid it somehow?

Key Predicates

This was a suggested idea when I began development on the Blue part. The problem is simple: Vanilla only lets one key bind per key, and on Modded, you'll probably need multiple key binds per key, like having a certain button only work on in-world and another only on a specific screen, it would be fine to have them share the key, but with the game's rules, they would be forced to take different keys, and once again, the keyboard doesn't have many keys.
The proposed solution are key predicates, which would basically allow the mod to determine rules like "this key will only work on these specific situations" and instead of having the "one key bind per key" rule, it would be more like "one key bind per predicate per key", with conflict indicators following that rule, making conflicts something that should definitely be fixed.

An alternative solution to the same problem is also one provided by Amecs: have no rules, let many key binds share the same key, and while it does fix the problem in a way, it trivializes conflicts, making them just a little annoyance in the key binds screen. I see this as a big problem, because a conflict is a conflict, it shouldn't be happening at all! And considering the same scenario which key predicates would better work (one in-world key, another screen-specific key), having no rules and still say "it's a conflict!" makes the message ("it's a conflict!") into something that should be ignored, because "everything's fine". And so, key predicates would be the ideal solution to that problem.

While it's a really neat idea, it's also the least concrete one. What would exactly be the predicates? The suggested implementations were:

  • A collection of identifiers which would have some standarized ones (like in_world) but others were free to have their own. It's simple, but it might not describe some more complex scenarios
  • Literally predicates, as in those used by data packs. It would be able to cover those complex situations, but the system itself might be overly complex

Questions:

  • Everything Actually, yeah, pretty much everything

Is the split really necessary?

That has been something that I've been wondering once I got much of Blue done.
While it's a rhetorical question, the answer is "It was", since with that split, I managed to get the Blue feature set ready and the Pink one is now ready to be discussed in order to set it into stone. That was my way to move fast and yet still progress very far without being hindered by bikeshedding, but now, Blue's ready, but does it necessarily mean "ready for release"?
Perhaps the finishing of the Blue feature sets would be simply a milestone, while the real goal would be finishing Pink, and since QSL is still in active development, it wouldn't make much of a difference anyway.
About that, this is up to y'all to decide.

And yeah, that's it!

There has been some solid progress recently, and now it's time to make the future a bit less cloudy in order to actually get the full potential of the API, so if you wanna help, give your feedback! Share your opinion (constructive, by preference)! I wanna know what do people really need in order to make this the best as possible
So, yeah, that's all! (and sorry for rambling a lot)

Conventions for QSL

This issue is here to iron out the conventions for QSL that will eventually end up in the CONTRIBUTING.md file.

These conventions should dictate the standard to which QSL's codebase is to be developed by. A few examples of possible categories for conventions include:

  • naming conventions
  • big boo boos you should avoid
  • how to approach writing documentation
  • code structure
  • general styling guidelines (I intentionally chose general since we have no suitable autoformatter to enforce these guidelines).

Commenters should go into detail on conventions that should be considered or current conventions to be amended.

Fabric Client dosn't like Quilt Server

When I join my Quilt server from my fabric client (Fabulously Optimized) I get "Registry remapping failed: Received ID map for Minecraft:command_argument_type contains IDs unknown to receiver! - quilt_command:enum"

Recipe Book API

Why?

Recipe Book is one of Minecraft's greatest additions, it makes recipes more accessible, especially to new players.

Despite some people not liking it's UI, it's still an useful tool which should not be ignored.

Mojang's mistake

Currently, mods can register custom recipe types, which is great! Until you hit the recipe book.

Let's address the elephant in the room: RecipeBookGroup.
It's an enum, one of modders' worst nightmare.

When there's a recipe using a custom recipe type, the client will call ClientRecipeBook#getGroupForRecipe(Recipe). And it's an if-else chain! If it falls through the fallback else block, it'll log to the console that the recipe type doesn't have a recipe book category.

That's quite an amount of issues.

What should we do about it?

The proposal is simple: allow modders to register custom recipe book groups.
One of the challenging part is to replace the enum, which would require quite an uncomfortable amount of injections.
Hopefully a good solution for that can be figured out.

What's to do first?

Well, before even thinking how to implement this, let's think first if we should provide this API.
I invite anyone reading this issue to to indicate their opinions on whether to include this API in QSL, or not.

QSL Fat Jar

We don't currently have dependency detection set up for build tools, and it's doubtful that something will be available by April.
We should consider providing a "fat jar" of all the QSL modules (similar to Fabric API) for the Beta period, to be phased out by full release.

Include the core module of QSL into all quilt installations

this might be somewhat questionable, but including the "core" module of the qsl might be a good idea
in a default installation
not sure how they would get updated or anything, but that would help with issues like this one from fabricord:
https://media.discordapp.net/attachments/833879754070818866/847672731511029810/unknown.png
i believe this is because the server and/or client doesnt have the fabric api, so registry syncing doesnt really take place
and then players without the required mods arent allowed to join
this might be a way to always provide a mod list, as the builtin networking api could send the packet when client connects, not requiring any mods to be installed
The above quote was by me in the #qsl-general channel

I am making this issue here because it feels more at place here than in loader or installer.

The main reason for this addition would be mostly for servers to enforce mod lists. This is not solely for banning certain mods, the idea was developed as a way to prevent users from joining a server without all required mods. If a user joins a server without a mod that modifies the registries, this feature could be used as a packet sent to the client telling them they need to install the mods that are missing.

This would also have the crash report api be in all quilt installations, making it easier for users and those supporting them to help with mod compatibility and/or crashes.

Ability to exclude certain additions from registry sync

(Following up the #1.)

It'd also be nice to be able to disable certain stuff from registry sync, even if added to registry.

As stated there, having "forced" registry sync (like with Forge if I understood correctly) would mean that players with vanilla clients can't connect to a server if it has modded registries (contains new blocks, items, entites, etc.). This is fine in most use cases, but with some mods, it would be beneficial to mark certain additions in registry as "not needed on client".

Use cases?

It's the server-side mods that would benefit from that, as they can add new items / entites / etc. with unique abilities but show them as vanilla items / entities on clients.

Possible crash report info apis

At the moment the only thing crash report info does is add quilt mods to the system details log. However I see it as being useful to possible allow other mods to add to the system details via a public api.

Some immediate use cases that come to my head could be:

  • Mods with native libraries dumping information about said libraries.
  • Mods heavily modifying the rendering system such as Sodium and Blaze4D being able to dump info about the OpenGL capabilities/Vulkan extensions that are available/enabled.
  • Something like optifabric could insert info about the version of optifine in use.

Add event for adding to, removing, or otherwise modifying a structure's spawn override

The spawn overrides that structures have is made with records and immutable maps/lists to the point it's very difficult for a mod to add their mobs to a structure that isn't their own. For example, Pillager Outposts. Those use spawn overrides to spawn pillagers. If you want to add a Flamethrower Pillager to spawn over time in that structure, you'll want to get it into the spawn override.

Mixin into the initial spawn override map for outposts is not ideal because any mod or datapack that overrides the structure with a structure json file will override the mixin's changes. Think Savage and Ravage mod on Forge where they changed outposts to be better but did not change the spawn overrides. We would want a mod adding new mobs to outposts to work alongside mods that overhaul the outpost.

Forge already provides an event for adding to any structure's spawn override. It is called StructureSpawnListGatherEvent in 1.18 for any research purpose. They are also looking to migrate that event into their brand new biome modifier system but for structure overrides in 1.19 since 1.19 broke the event.

The discord convo that sparked this:

image
image

Add an event for block placement

Currently (unless I missed something) there is no equivalent to Fabrics UseBlockCallback. It would be nice if an equivalent existed in qsl for intercepting and acting upon block placement events.

Fat Javadoc Jar

A javadoc jar that has javadocs for all the modules in QSL. Will increase API discovery and easier to link to for basic docs

Block Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the block library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • BlockEntity Networking
  • Object Builder API (FabricBlockEntityBuilder)
  • #41
  • #142

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

DataFixerUpper API

Essentially, an API that allows mods to create and "install"/register their own DFU scripts.

This is extremely useful for one specific purpose - backwards compatibility. Instead of having to keep your old items/blocks/data structures/what have you around and needing to convert them manually, you can just let Minecraft itself handle it!

I already have a working API for this (that I stole from a closed FAPI PR by i5), and will most likely PR it once QSL is ready to receive PRs.

Worldgen Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the worldgen library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • Dimension API
  • Biome API
  • Structure API

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

Debug information clutter in modpacks

I've discovered after downloading the Fabulously Optimized modpack for Fabric that F3 screens have become far too cluttered, and information often gets pushed off of it at reasonable GUI scales.

Is there an approach QSL could take to allow mods to provide F3 debug information in a way that isn't so obtrusive and prone to being knocked off-screen? What would that look like?

Attached images

2022-01-30_15 51 42

2022-01-30_15 51 27

Redesign the Structure API's structure spacing section

This is more of a reminder for myself to PR the change once QSL is ready for PRs.

Basically, at the moment, structure spacing is a massive pain to do.

The first issue is that the Noise Settings are their own object that holes the structure spacing for a dimension. And multiple world's chunk generators can share the same Noise Setting instance across them all. While Mojang intended for the Noise Setting to be the proper way to allow/disallow a structures for that dimension (removal of structure spacing from it prevent the structure from spawning in that dimension), the current system prevents mods from removing a structure from the overworld without also affecting all other dimensions that uses the same overworld Noise Setting.

The solution I came up with is to make a deep copy of this Noise Setting for every dimension so they are all unique. I put this in my mod as it is necessary as a first step for proper dimensional allow/disallowing structures. So far, no complaints from anyone about this change breaking anything which make sense as not all dimension has a registered Noise Setting anyway (the Noise Setting can be embedded into the dimension's json file directly which makes it unregistered). Any possible issue with deep copying Noise Settings only would expose flaws in any mod's code that relies on registered Noise Settings when they should be accessing the Noise Setting directly itself instead.
https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/latest-released/src/main/java/com/telepathicgrunt/repurposedstructures/mixin/world/ChunkGeneratorMixin.java

https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/latest-released/src/main/java/com/telepathicgrunt/repurposedstructures/mixin/world/StructuresConfigMixin.java

https://github.com/TelepathicGrunt/RepurposedStructures-Fabric/blob/latest-released/src/main/java/com/telepathicgrunt/repurposedstructures/misc/NoiseSettingsDeepCopier.java

The second issue found is that Fabric API's Structure API will take the structure's spacing/separation that modders specify and add it to the dimension's Noise Setting in the ServerWorldEvents.LOAD event. While this works great for Fabric API, it also makes it much more difficult for my structure mod's disallow to function. Specifically, if I use ServerWorldEvents.LOAD to remove my structure spacing from a dimension to prevent spawning there, Fabric API's ServerWorldEvents.LOAD could run after mine and re-add the structure's spacing back which breaks my config. My solution was to delay the registration of my event so that it always fires after Fabric API's.

But a real proper solution for QSL would be something along this line instead:

  1. Create an internal hook just before ServerWorldEvents.LOAD that QSL uses to call a custom SetupStructureSpacings method that takes in the serverworld.

  2. Expose a new method in FabricStructureBuilder (or renamed to QSLStructureBuilder) called .allowableDimensions(<predicate>) and it requires a function that takes a serverworld and returns a boolean. By default, if you dont call allowableDimensions, the structure spacing will be added to all dimension. So if you wanted to hook up your dimensional config to allowableDimensions, you can with the predicate or hardcode it to only spawn in the end. The reason the server world is passed in instead of the registry key is in case people want to do other checks on the dimension itself. But it is understandable if this is switched only to give the world's registry key in fear of abuse in that predicate.

  3. In SetupStructureSpacings (which is ran for every serveworld), run allowableDimensions for each structure built with QSLStructureBuilder and adds the spacing to that dimension if that structure's allowableDimensions returns true (using putIfAbsent so player's specifying the spacing by datapack won't be overridden for that structure).

This now will standardized how to do dimensional allowing/disallowing for structures and prevent conflict between the API and the structure mods.

Thoughts?

The new registry sync format.

This issue pertains to discussion about the new registry sync format.

There have been a few issues with the registry sync fabric uses that causes it to reach the maximum packet size quickly.

A few of these issues include:

  • The overhead of the NBT format in serialization for the packet
  • The inclusion of the namespace inside all Minecraft namespaced identifiers.
  • The map structure of the packet using key -> value for every namespace and string takes up extra room.
  • Where a sequence of all identifiers inside the packet are of the same namespace, the namespace is included in the identifier.
  • Some registries get many more registrations than others, meaning just a few registries in the same packet fill up the entire payload of the packet.
  • Overloaded registries cannot be split if they hit the max payload size.

Given the above issues, I feel we can greatly reduce the size of the packet with some optimizations.

Musings on Soft Intermodule Dependencies

This discussion is relevant to both QSL and our eventual quilt-gradle plugin, but this seems like the best place to have such a discussion for now.

Currently, there is a hesitation to add intermodule dependencies to Quilt's standard libraries that is carried over from a similar mindset in Fabric API. In Fabric API, it makes a fairly small amount of sense, since Fabric API is packaged and distributed as a monolith in 99% of situations anyway. In QSL, on the other hand, avoiding inter-module dependencies makes a great deal of sense, as it allows dependency downloading to avoid downloading more niche modules that not many mods will need.

There are, however, situations where intermodule dependencies could be used to make modules easier to use. I will use a config API as an example. Let's say we were to break the config API into the following modules: qsl_config_base, qsl_config_screens, qsl_config_sync, and qsl_config_gamerules. qsl_config_base might provide a builder that makes it easy for mods to build a config tree:

Note: Any code shown is for illustration purposes only and is not necessarily representative of any actual config API.

public final class ConfigBuilder {
  <T> void addField(String name, Class<T> type, T defaultValue) { ... }
  Config build() { ... }
}

qsl_config_base should not have a hard dependency on any of the other three modules, but what if methods themselves could have dependencies?

public final class ConfigBuilder {
  <T> ConfigBuilder addField(String name, Class<T> type, T defaultValue) { ... }
  
  @Requires("org.quiltmc:qsl_config_screens:1.x")
  ConfigBuilder registerScreen() { ... }

  @Requires("org.quiltmc:qsl_config_sync:1.x")
  ConfigBuilder sync() { ... }

  @Requires("org.quiltmc:qsl_config_gamerules:1.x", "org.quiltmc:qsl_content_other_gamerules:1.x")
  ConfigBuilder addGameRules() { ... }

  Config build() { 
    if (checkOrThrow(this.registerConfigSceen, "qsl_config_screens")) { ... }
    if (checkOrThrow(this.isSynced, "qsl_config_sync")) { ... }
    if (checkOrThrow(this.registerGameRules, "qsl_config_gamerules")) { ... }

    ...
  }
  
  private static boolean checkOrThrow(boolean required, String module) {
    boolean present = QuiltLoader.isModLoaded(module);

    if (required && !present) {
      throw new SomeException();
    }

    return present;
  }
}

These annotations could be processed at build time by quilt-gradle to add dependencies to the built mod if the annotated methods are referenced in any way. Such an annotation could also be added to classes, such that extending or instantiating an annotated class would also indicate that a mod has a dependency on the indicated module(s). This could be used by other libraries as well, such as Cardinal Components having only their synced components require qsl_networking.

I'm not sure this is the best approach, but I thought it was a discussion worth having. I did ideate most of this while exhausted and falling asleep, so forgive me if anything is not entirely coherent.

Block Items don't get added to modded creative tabs.

This is how Expanded Storage looks on quilt, note the scroll bar is scrollable as if the slots are populated. However the slots where the chests / barrels should be are visually and actually empty.
image
In contrast this how the mod looks on fabric:
image

Edit: from discord this sounds like an issue with modded block items only.

Resource Reloaders improvements for ordering.

Resource reloaders currently are a bit limited, while they are identified, you only can depend on other reloaders,

This is an issue as you might want reloaders running before the Vanilla ones.

One of the goal is to allow to tell that another resource reloader should run after. This could be done by using a similar system as the phase ordering for events.

Entity Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the entity library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • Object Builder API (EntityType Builder, Trades, Villager professions and types)
  • #42
  • Interaction Events
  • Object Builder API (Point of Interest)

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

Multiple calls to `BlockRenderLayerMapImpl` will cause `NullPointerException`

public static void initialize(BiConsumer<Block, RenderLayer> blockHandlerIn, BiConsumer<Fluid, RenderLayer> fluidHandlerIn) {
// add pre-existing render layer assignments
blockMap.forEach(blockHandlerIn);
fluidMap.forEach(fluidHandlerIn);
// set handlers to directly accept later additions
blockHandler = blockHandlerIn;
fluidHandler = fluidHandlerIn;
// lose the maps, let the GC take care of them
blockMap = null;
fluidMap = null;
}

Probably fine, but could cause an issue

GUI Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the gui library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • Screen API
  • ScreenHandler API
  • (#59)

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

Resource load conditions

Fabric API has a resource load condition api for datapacks but qsl seems not.
It's great if qsl has one too.

Default resource pack not in resource pack list

This is caused by the resource loader module. This is also not an issue in Fabric's resource loader. I noticed this problem when users of Continuity reported it not working when used with Inspecto or Ok Zoomer, both of which bundle Quilted Fabric API.

Resource pack classes with Fabric API:

  • net.fabricmc.fabric.impl.resource.loader.FabricModResourcePack (Fabric mod resource pack)
  • net.fabricmc.fabric.impl.resource.loader.ModNioResourcePack (built-in pack)
  • net.minecraft.client.resource.DefaultClientResourcePack (default pack)

Resource pack classes with Quilted Fabric API:

  • org.quiltmc.qsl.resource.loader.impl.ModNioResourcePack (built-in pack)
  • org.quiltmc.qsl.resource.loader.api.GroupResourcePack$Wrapped (Quilt mod and vanilla resource pack)

MinecraftClient.getInstance().getResourcePackProvider().getPack() returns an object of type:

  • net.minecraft.client.resource.DefaultClientResourcePack

Continuity checks if the pack that contains a certain resource is equal (==) to the default pack, which is of type DefaultClientResourcePack. In Fabric, the check succeeds because this pack is in the list of the resource manager's packs, but in Quilt it fails because it is not.

To fix this incompatibility from Continuity's side, I would have to add dedicated support for Quilt Resource Loader and use mixins or reflection to access the basePack field of Wrapped and check it against the real default pack because this class is an API class and can appear multiple times in the pack list. I am not willing to add such dedicated support.

Specific code that fails because of this issue:
https://github.com/PepperCode1/Continuity/blob/1.18/dev/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java#L501

Specific use case:
Checking if a certain resource from the default pack but not mod resources (such as the glass texture) is the highest priority one (as in, no other pack overrides this resource).

Tags API

Tags API?

Tags API would replace Fabric API's tag-extensions API and go further with some new features:

  • Ability to define biomes tag (proof of concept can be seen in the LambdaFoxes mod.
  • Ability to define tags for any registry (minimal work is done, difference with biomes tag is biomes tags are already defined and needs some mixins to work properly with biomes datapack starting from 1.17.1).
  • Maybe more stuff?

Data Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the data library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • #35 Tags API (need rework since 22w06a)
  • #54
  • #140
  • Fabric datagen API (new since RFC)

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

EnchantmentTarget enum needs a proper fix

As we know, Mojang did a big thonk with EnchantmentTarget by making it be its own thing that never actually calls the enchantment's isAcceptableItem method. Due to that, overriding isAcceptableItem is not enough to make your enchantment be applied to the correct items in an Enchantment Table as the table never calls isAcceptableItem anywhere.

The current solution some people came up with is to set the EnchantmentTarget to BREAKABLE so it passes for all tools and then mixin to the return of EnchantmentHelper.getPossibleEntries and then remove your enchantment from the list if the conditions aren't right. This has its own set of problem of course in theory.

An idea for QSL to do was suggested by EMI here:
image

There is also a PR to Fabric API that tried to address this issue but that PR has died a while ago sadly. I don't know much about this area so I can't be of much help. But this issue report should help to make sure this doesn't get forgotten down the road. CHASM can help address enum issues iirc but having an API that deals with this specific enchantment issue may be nicer for modder to use instead

Item Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the item library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

Player Chat Events

Add events to simplify and and better compatibility mods wanting to listen to and/or modify chat.

Jetbrains annotations, warnings, and more visual tools for modders.

Ok, so randomly while porting to 1.19.1-rc3 I may have touched a function and was like "what about @Contract".
I don't know how that thought came but it sparked a discussion we all should have.

Static analysis

Static analysis is... cool! Honestly it's very nice and it's becoming something more and more important in development spaces (to the point of having languages doing as much at compile time).

For those who don't know, static analysis is stuff that runs at compile-time, or in this case is directly visible through warnings in Intellij IDEs. It's.. quite important tools.

QSL and static analysis

So far we've been using Jetbrains annotations with @ApiStatus and @Nullable, and some others.

But that's not the only annotations:

  • there's @NotNull that we haven't used since we consider stuff to be non null by default.
    But Kotlin modders claim that it would make Kotlin mods safer as lot of compile-time checks could then be executed.
  • there's @Contract which allows to:
    • mark a function as pure (no side effects)
    • mutates a parameter (experimental so might not stay in future versions of the library)
    • assign a contract clause to a function, which can be very rich like null, null -> null; _, null -> param1; null, _ -> param2; !null, !null -> new.

Said contract clause can generate warnings like:
image

Limitations

Most of those annotations are, sadly, only useful for Intellij IDEA users.

It does not affect Gradle, Eclipse does not recognize them, nor VSCode.

The Question

All of that is good and all, but so far those are not really used.

One of the main issue is: annotation hell
Using more these might make code harder to read or annoying to write, lots and lots of annotations due to Java's lack of native static analysis tools.

So the question is:

  • do the benefits outweights the con?
  • are tools like this what modders want?
  • should we start using those?

Improvements over the Crash Report API

While porting the API I noticed some issues with it, especially the CRASH_REPORT_CREATION event.

The event pass CrashReport, if you want to add a new section you'll do CrashReport#addElement, but it caused crashes due to its stacktrace trimming system. This has been solved with bound checks, but I'm lead to think we probably should have a context object instead to allow our own addElement logic.
Is this relevant?
Would this be actually useful?

Transfer Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the transfer library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • API Lookup API
  • Fluid API
  • Item Transfer API

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

Events and fallback priority

A discussion has risen from our initial event implementation about a fallback mechanism for how event invocation order is handled.

This is not in the initial event api, but should probably be discussed and an agreement made before releasing QSL

Other Content Library TODO

This is a list of the Fabric API modules that need to be ported to QSL for the content_other library. Feel free to make a PR for any module in this list, though consider discussing your port in the Toolchain Discord first.

  • Particles
  • #55

The new module should have the same core features as the Fabric equivalent, but refactors, reorganizations, or expansions in scope are allowed.

Please leave a comment if this list is incomplete or missing a Fabric API module that was added past when the original QSL RFC was written.

If you are interested in becoming a maintainer for this library, please contact the QSL Core team on the Toolchain Discord!

suggestion: Armor texture and model APIs

Armor textures and models are painful to setup the needed mixins for. APIs for these would simplify things quite a lot.
I might PR these myself if I find the time.

Dehardcoding "ItemStack.isOf" checks

As of Minecraft 1.16, the following items are special-cased using ItemStack.isOf calls (AKA ItemStack.getItem() == SPECIFIC_ITEM_INSTANCE):

  • Bows
  • Crossbows
  • Shields
  • Elytras

This essentially means adding a new variant of any of the above items is impossible without mixins.

I suggest that QSL should dehardcode these checks, to allow for custom bows/crossbows/shields/etc.

I'm not sure if this should be an API necessarily, AFAIK the main thing holding back custom bows/etc is the hardcoded checks.

What should the package structure of the apis be?

One discussion that has come up on discord has been how should we organize the package structure of the modules.

So far I've seen a some ideas for the package structure.

  • org.quiltmc.qsl.event.api (qsl.<module>.api)
  • org.quiltmc.qsl.api.event (qsl.api.<module>)

The purpose of this issue is to discuss which package structure should be used. If there are any other package structures, do comment your idea.

DataGenerator API

An API to create easy datagen using Minecraft's existing datagen system would be a very useful tool for modders. There could be default methods to create data for common things such as lang entries, loot tables, block states, recipes, models, etc.

Datagen is great because it removes a lot of the monotony of having to create very similar files over and over. While we currently have third-party datagen APIs like ARRP on fabric, it is so commonly used that I believe a datagen API should have a place in QSL.

QSL Versioning

What should QSL's versioning look like for the beta period of Quilt, before we are making stability guarantees?

We've already released modules as "1.0.0-SNAPSHOT", so we probably want to continue by using the prerelease system in semver.

However, the actual QSL meta-artifact is currently 0.1.0-SNAPSHOT, so we could continue bumping the minor version of it for the time being.

Whatever we decide on, we should formalize it in a document in this repository.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.