TagCore
A unified tagging API for items, blocks, and entities, enabling cross-mod compatibility
| Last updated | 2 days ago |
| Total downloads | 10 |
| Total rating | 0 |
| Categories | Mods Release Plugins |
| Dependency string | AzureDoom-TagCore-1.1.3 |
| Dependants | 1 other package depends on this package |
README
TagCore
TagCore is a Hytale server mod/plugin that adds a simple, reusable tag system for game content.
It lets you define named groups of IDs such as items, blocks, entities, biomes, effects, fluids, and damage types, then query those groups through a clean Java API.
Features
- Define tags in JSON
- Support for these tag types:
itemblockentitybiomeeffectfluiddamage_type
- Reference one tag from another with
#namespace:path - Resolve fully flattened tag contents at startup
- Detect invalid values, missing references, wrong-type references, and circular references
- Load tags from:
- bundled classpath resources under
tags/ - external
.zipand.jarpacks from the servermods/directory
- bundled classpath resources under
- Easy-to-use
TagServiceAPI for other mods/plugins
Installation via Gradle
Add the AzureDoom Maven repository and dependency to your build.gradle.kts:
repositories {
maven("https://maven.azuredoom.com/mods")
}
dependencies {
implementation("com.azuredoom.tagcore:TagCore:1.0.0")
}
For Groovy DSL:
repositories {
maven {
url = uri("https://maven.azuredoom.com/releases")
}
}
dependencies {
implementation("com.azuredoom.tagcore:TagCore:1.0.0")
}
Maven browser/index: https://maven.azuredoom.com/#/
How Tag IDs Work
Tag IDs use a namespace:path format.
Examples:
hytale:logstagcore:starter_weaponsmymod:undead
If a tag ID is written without a namespace, TagCore normalizes it to the default namespace:
hytale
So a bare tag like:
starter_weapons
is treated as:
hytale:starter_weapons
Defining Tags
Tag files are JSON files placed under a tags/ directory.
A tag definition contains:
id- the tag IDtype- the tag typevalues- a list of concrete IDs and/or tag references
Example item tag
{
"id": "tagcore:starter_weapons",
"type": "item",
"values": [
"Weapon_Sword_Wood",
"Weapon_Shortbow_Crude",
"#tagcore:starter_ammo"
]
}
Example block tag
{
"id": "tagcore:logs",
"type": "block",
"values": [
"Wood_Amber_Trunk",
"Wood_Ash_Trunk",
"Wood_Aspen_Trunk"
]
}
Example entity tag
{
"id": "tagcore:undead",
"type": "entity",
"values": [
"Zombie",
"Skeleton",
"#tagcore:boss_undead"
]
}
Referencing Other Tags
You can include one tag inside another by prefixing the referenced tag ID with #.
{
"id": "tagcore:all_logs",
"type": "block",
"values": [
"#tagcore:logs",
"#tagcore:modded_logs"
]
}
Rules:
- referenced tags must exist
- referenced tags must be the same type
- circular references are rejected
Where Tags Are Loaded From
TagCore loads tags from two places, in this order:
- Classpath resources under
tags/ - External
.zipor.jarpacks in the servermods/directory
External packs can override built-in tags with the same ID.
Using the API
TagCore exposes a shared TagService for querying tags.
Get the shared service
import com.azuredoom.tagcore.api.TagService;
var tagServiceOptional = TagService.getTagService();
if (tagServiceOptional.isEmpty()) {
return;
}
TagService tagService = tagServiceOptional.get();
Check whether a tag exists
boolean exists = tagService.hasTag("tagcore:starter_weapons");
Resolve a typed tag
var result = tagService.resolveItemTag("tagcore:starter_weapons");
if (result.isSuccess()) {
for (String itemId : result.value()) {
System.out.println(itemId);
}
} else {
System.out.println("Failed to resolve tag: " + result.status());
for (var issue : result.issues()) {
System.out.println(issue.detail());
}
}
Check membership in a tag
var result = tagService.isInItemTag("tagcore:starter_weapons", "Sword_Wooden");
if (result.isSuccess() && result.value()) {
System.out.println("Sword_Wooden is in the tag.");
}
Resolve a block tag
var logs = tagService.resolveBlockTag("tagcore:logs");
if (logs.isSuccess()) {
System.out.println("Resolved block IDs: " + logs.value());
}
Generic membership check
var result = tagService.isInTag("tagcore:starter_weapons", "Sword_Wooden");
if (result.isSuccess()) {
System.out.println("Contained: " + result.value());
}
Understanding Query Results
Most TagCore API calls return a TagQueryResult<T>.
This gives you:
status()- overall outcomevalue()- returned valuedefinition()- matching tag definition, when availableissues()- validation or resolution issues
Common statuses:
SUCCESSEMPTYNOT_FOUNDWRONG_TYPEINVALID_TAG_IDINVALID_CONTENTCIRCULAR_REFERENCE
Example:
var result = tagService.resolveBlockTag("tagcore:logs");
switch (result.status()) {
case SUCCESS, EMPTY -> {
System.out.println("Resolved values: " + result.value());
}
case NOT_FOUND -> {
System.out.println("Tag not found.");
}
default -> {
System.out.println("Tag resolution failed: " + result.status());
for (var issue : result.issues()) {
System.out.println(issue.type() + ": " + issue.detail());
}
}
}
Recommended Folder Layout
Example bundled resource layout:
src/main/resources/
└── tags/
├── items/
│ └── starter_weapons.json
├── blocks/
│ └── logs.json
└── entities/
└── undead.json
The exact subfolder structure under tags/ is flexible. What matters is that the files are discoverable under the tags/ root.
Example Pack Override
You can ship a default tag in your mod, then override it from an external pack in mods/.
Bundled tag:
{
"id": "tagcore:starter_weapons",
"type": "item",
"values": [
"Sword_Wooden"
]
}
External override:
{
"id": "tagcore:starter_weapons",
"type": "item",
"values": [
"Sword_Wooden",
"Bow_Basic",
"Dagger_Rusty"
]
}
Notes
- Values must be valid IDs for the declared type.
- References must point to tags of the same type.
- TagCore resolves references eagerly so configuration problems show up early.
- Bare tag IDs are normalized to the default namespace
hytale.
License
MIT