-
Notifications
You must be signed in to change notification settings - Fork 2
Java API GroupDefinition
This page explains the full GroupDefinition object, how display names work, how icons are configured, and how to move from simple examples to more advanced ones.
- You already understand
GroupFilterand are ready to create actual group objects - You want to see how
id, display name, icon, andfiltercome together - You want Java examples you can copy and adapt
-
GroupDefinitionis the complete Java-side group object - construction automatically runs normalization, validation, and compilation
- the
String nameoverload is convenient for quick setup; for formal built-in groups,GroupDisplayName.Localizedis usually clearer
GroupDefinition includes:
iddisplayNameenabledfiltericonIds
When you create a GroupDefinition, the mod automatically does three things:
- normalizes the filter
- validates the filter
- compiles
compiledFilter
That means:
- you do not need to manually shape the filter into its final form first
- invalid filters fail early at construction time instead of failing silently later
The authoritative name is not just a plain string. It is GroupDisplayName.
Important facts:
-
displayName()is the authoritative source -
name()is only the resolved display text in the current language - the current implementation type is
GroupDisplayName.Localized
GroupDefinition currently includes overloads that accept String name, for example:
new GroupDefinition(
"mypack:barrel",
"Barrel",
true,
Filters.itemId("minecraft:barrel")
)That does not simply store a string and stop there. Under the hood, it still becomes:
- an auto-generated translation key based on the group ID
- the string you passed in as the fallback name
So:
- use the
Stringoverload when you want a quick, convenient definition - use
new GroupDisplayName.Localized(key, fallback)when you want full control over the key and fallback
GroupDefinition barrels = new GroupDefinition(
"mypack:barrel",
new GroupDisplayName.Localized(
"group.collapsible_groups.mypack.barrel",
"Barrel"
),
true,
Filters.itemId("minecraft:barrel")
);This is usually the clearer form for formal built-in groups and long-term integrations.
GroupDefinition supports an icon ID list, but it is optional.
iconIds tends to be useful when:
- a group contains many entries and you want faster visual recognition
- the group concept is abstract and the name alone is not enough
- you are building formal built-in groups and want a more polished result
If you do not need icons, omit them. If you do, pass a List<String>.
GroupDefinition barrel = new GroupDefinition(
"mypack:barrel",
"Barrel",
true,
Filters.itemId("minecraft:barrel")
);GroupDefinition utilityBlocks = new GroupDefinition(
"mypack:utility_blocks",
"Utility Blocks",
true,
Filters.any(
Filters.itemId("minecraft:barrel"),
Filters.itemId("minecraft:crafting_table"),
Filters.itemId("minecraft:chest")
)
);GroupDefinition vanillaLogs = new GroupDefinition(
"mypack:vanilla_logs",
"Vanilla Logs",
true,
Filters.all(
Filters.itemTag("minecraft:logs"),
Filters.itemNamespace("minecraft")
)
);GroupDefinition planksExceptOak = new GroupDefinition(
"mypack:planks_except_oak",
"Planks Except Oak",
true,
Filters.all(
Filters.itemTag("minecraft:planks"),
Filters.not(Filters.itemId("minecraft:oak_planks"))
)
);GroupDefinition woodFamilyMixed = new GroupDefinition(
"mypack:wood_family_mixed",
"Wood Family Mixed",
true,
Filters.any(
Filters.all(
Filters.itemTag("minecraft:logs"),
Filters.itemNamespace("minecraft")
),
Filters.all(
Filters.itemTag("minecraft:planks"),
Filters.itemNamespace("create")
)
)
);If you already have an encoded stack string:
String encodedPotionStack = "{\"id\":\"minecraft:potion\",\"count\":1,\"components\":{...}}";
GroupDefinition onePotion = new GroupDefinition(
"mypack:one_specific_potion",
"One Specific Potion",
true,
Filters.exactStack(encodedPotionStack)
);If you have an ItemStack instead, use the corresponding overload:
ItemStack stack = ...;
GroupFilter filter = Filters.exactStack(stack);Both forms resolve to the same ExactStack node. The difference is input type, not meaning.
Notes:
-
ExactStackcurrently only supports item - The JSON equivalent uses the encoded string form
- fluid and generic types do not have an equivalent exact-stack node
Some mods, such as Apotheosis, use the same item ID with different Data Component values to distinguish variants. ExactStack requires every component to match exactly. If you only want to filter on one component value, use HasComponent.
Single value:
GroupDefinition ballastGems = new GroupDefinition(
"mypack:apotheosis_ballast_gems",
"Ballast Gems",
true,
Filters.itemComponent("apotheosis:gem", "apotheosis:core/ballast")
);Multiple values with Any:
GroupDefinition gemsByType = new GroupDefinition(
"mypack:apotheosis_ballast_or_breaker",
"Ballast or Breaker Gems",
true,
Filters.any(
Filters.itemComponent("apotheosis:gem", "apotheosis:core/ballast"),
Filters.itemComponent("apotheosis:gem", "apotheosis:core/breaker")
)
);The encodedValue format depends on the component type:
- ResourceLocation-style components: plain string, e.g.
"apotheosis:core/ballast" - Numeric components: JSON numeric literal, e.g.
"3"or"1.5" - Object components: full JSON, e.g.
"{\"level\":5}"
Notes:
-
HasComponentcurrently only supports item - If the component ID does not exist or has no codec, the match always returns
false - Groups that include
HasComponentare read-only in the player editor
If the field you want to match is not the whole component value but a specific nested field inside it, use Filters.itemComponentPath().
Iron's Spellbooks stores spell data inside irons_spellbooks:spell_container, with the spell ID at data[0].id. HasComponent compares the whole component value and cannot reach into that structure. ComponentPath can:
GroupDefinition bloodNeedlesScrolls = new GroupDefinition(
"mypack:blood_needles_scrolls",
"Blood Needles Scrolls",
true,
Filters.all(
Filters.itemId("irons_spellbooks:scroll"),
Filters.itemComponentPath(
"irons_spellbooks:spell_container",
"data[0].id",
"irons_spellbooks:blood_needles"
)
)
);The itemId pre-filter is recommended here: it narrows candidates through the item index before the more expensive component-path inspection runs.
DefaultGroupProvider provides a convenience helper that bundles both:
DefaultGroupProvider.itemWithComponentPath(
"irons_spellbooks:scroll",
"irons_spellbooks:spell_container",
"data[0].id",
"irons_spellbooks:blood_needles"
)Path grammar:
| Pattern | Meaning |
|---|---|
field |
top-level key |
parent.child |
nested key |
array[n] |
nth element of an array |
array[n].field |
a field inside an array element |
Notes:
-
ComponentPathcurrently only supports item - Groups that use it are read-only in the player editor
- Use
HasComponentwhen the component value is flat and directly comparable; useComponentPathwhen the value you need is nested inside the component's structure
Exact ID:
GroupDefinition hydrogen = new GroupDefinition(
"mypack:hydrogen",
"Hydrogen",
true,
Filters.genericId("mekanism:chemical", "mekanism:hydrogen")
);Tag and namespace variants:
GroupDefinition mekanismChemicals = new GroupDefinition(
"mypack:mekanism_chemicals",
"Mekanism Chemicals",
true,
Filters.genericNamespace("mekanism:chemical", "mekanism")
);Use this when a JEI ingredient type other than item or fluid exists and you want it inside the same group system.
Continue reading:
Players
Modpack Developers
Mod Developers
Localization