What does it do?
Creates a third class of resource, "static data", which lets mods search each other and their environment in an easy, structured way for compatibility and interop information.
For instance, a mod might register a slope-shaped block based on a set of vanilla blocks, but also offer to register new slopes based on modded blocks. Tags aren't available early enough for this! Static data is.
Responsibility for mod interop data isn't locked into one particular place. Static data relating to mod B, queried by mod A, can be supplied by mod A, mod B, a third mod, or even a static datapack. Data from all these sources can be mixed and used additively.
Why do we need static data?
Static data is static
Datapack and Resource-pack reloads do not affect static data and static datapacks. The same data is available, and its source mod (if any) identifiable, through the entire lifecycle of your mod. You'll never have to call any entrypoints for this data, you don't have to care what loader the mod is from, the data is just already there. You'll never have to worry if connecting to a server has changed the data, static data doesn't change so you can initialize once with confidence.
Static data is available early
As soon as the first entrypoint runs anywhere in the loader - whether that entrypoint is quilt-loader, qsl, qfapi, or a mod integration entrypoint, if your mod has been asked to initialize something, static data is already ready.
You can use it to trigger registrations
Since ordinary datapacks change over time, it's a can of worms to use them to change frozen registries. Since static data does not change, and is available before registries are frozen, you can register blocks and entities using information you get from static data. This is the primary reason for its existence - to allow mods to communicate feature information to each other in a way that vanishes if the other mod is gone, but doesn't rely on the mods having the same modloader.
How can I provide staticdata?
Mods provde staticdata like other kinds of data
Static data is placed in a staticdata
directory alongside the assets
and data
directories, and items are namespaced within the staticdata folder. So if the mod "architecture_extensions" is looking for files in the "blockgroups" path, and you provide an integration called "obsidian.json", the full path of this file would be
src/main/resources/staticdata/architecture_extensions/blockgroups/obsidian.json
Note that you do not use your own namespace at all - your modId is already provided by placing the data inside your mod.
Players and Pack-Makers can provide static datapacks
A zip file whose root folder is named "staticdata" is a valid static datapack. This works exactly like a resource pack except for static data. To provde the same file as the previous section, the file's path inside the zip would look like:
/staticdata/architecture_extensions/blockgroups/obsidian.json
Having a pack.mcmeta and pack.png inside the root directory is optional, and these files are currently ignored.
Static datapack zips can be loaded from two places:
- from within mods, in the root
src/main/resources/staticdata/
folder - from the root
.minecraft/staticdata/
folder, which will be created if not present when any mod requests static data
Static datapacks placed within subdirectories will not be accessible.
Raw files can be placed in the staticdata folder
These files still need to be namespaced, but again using the above example:
.minecraft/staticdata/architecture_extensions/blockgroups/obsidian.json
As long as the files are placed in the correct namespaced folder, they will contribute to data searches.
How can I use static data in my mod?
First, depend on staticdata. This requires a gradle modImplementation
entry and a quilt.mod.json depends
entry. See the source repository for current version and maven/gradle details.
Second, it is recommended to add an include
to your gradle so that the library ships inside your jar. For some reason this doesn't seem to imply modImplementation
so you'll probably need both lines.
Third, during your modInitializer, you can do something like
// You could use quilt-json5 or jankson here instead
Gson gson = new GsonBuilder().create();
// Get all the static data in this folder and subfolders
List<StaticDataItem> dataItems = StaticData.getDataInDirectory(
new Identifier(MODID, "bees"), //Search for mymod:bees
true // Yes, do a recursive search through subfolders
);
for(StaticDataItem dataItem : dataItems) {
// MyDataObject here is the class that represents the data you want
MyDataObject dataObject = gson.fromJson(item.getAsString(), MyDataObject.class);
// This is just a suggestion - staticData is most useful if you
// load the data conditionally!
String requiredMod = dataObject.only_if_present;
if (requiredMod != null && !requiredMod.isBlank()) {
// Should only be loaded when the indicated mod is present
if (!QuiltLoader.isModLoaded(requiredMod)) continue;
}
//And now you're ready to use the data!
doSomethingWithTheData(dataObject);
}
(Assuming that the MyDataObject class looks something like)
public class MyDataObject {
public String only_if_present;
//other data goes here in public fields
}
How do I use the mod in my modpack?
This is a jar-in-jar mod which commonly comes embedded within other mods, and the nature of the mod enables configuration-free mod interop. So you can gain the base benefit of static data by just downloading mods which take advantage of it and playing them together.
However, if you want to dive deeper, consider making a static datapack and shipping it with your modpack! Each mod approaches interop differently, so consult the mod's documentation to find out more.
External resources
Project members
falkreon
Owner