HyBaubles
Eight accessory slots for your Hytale server — rings, necklaces, bracelets and talismans — with a data-driven system for granting stats and passive effects. Built to be depended on.



Compatible with RPG Leveling and Stats/Skills:
What it does
HyBaubles adds eight "bauble" slots to every player, opened with /baubles (or Alt + 9):
| # | Slot | Family |
|---|---|---|
| 0 | RING_1 |
Ring |
| 1 | RING_2 |
Ring |
| 2 | NECKLACE |
Necklace |
| 3 | BRACELET |
Bracelet |
| 4 | TALISMAN_1 |
Talisman |
| 5 | TALISMAN_2 |
Talisman |
| 6 | TALISMAN_3 |
Talisman |
| 7 | TALISMAN_4 |
Talisman |
Slots are family-locked: a necklace can never be placed in a ring slot. Talismans are mutually exclusive within their family, so you cannot wear the same talisman twice.
Equipment persists across sessions, applies its effects on equip, and cleanly reverses them on unequip.
Unlike most cosmetic accessory mods, the slots here do something: every bauble declares its effects in JSON, and HyBaubles resolves them into real stat and damage modifiers.
Compatible Mods:
RPG Leveling And Stats/Skills (Keybind compatible)

Accessories (Accessories can be equipped as HyBaubles)

RecipeTooltips (non-overlapping tooltips)
Built-in items
Twelve items ship with the mod. They exist to demonstrate the framework — every value is configurable, and you can add your own without touching HyBaubles' code.
| Item | Slot | Rarity | Effect |
|---|---|---|---|
| Bloodleaf Ring | Ring | Common | Heals 1% of max health per second |
| Storm Ring | Ring | Rare | Restores 2% of max stamina per second |
| Copper Bracelet | Bracelet | Common | +3 Damage |
| Iron Bracelet | Bracelet | Uncommon | +5 Damage |
| Thorium Bracelet | Bracelet | Rare | +7 Damage |
| Adamantite Bracelet | Bracelet | Rare | +9 Damage |
| Mithril Bracelet | Bracelet | Epic | +11 Damage |
| Onyxium Bracelet | Bracelet | Epic | +13 Damage |
| Silk Necklace | Necklace | Uncommon | +10 Mana |
| Cindercloth Necklace | Necklace | Rare | +15 Mana |
| Speed Talisman | Talisman | Uncommon | +20% Speed |
| Defense Talisman | Talisman | Rare | +5% Physical Resistance |
Every item is craftable, and rarities follow their vanilla metal counterparts — the Copper Bracelet is Common because copper tools and armour are Common, Mithril is Epic because mithril gear is Epic, and so on. All twelve have custom 3D models and hand-tuned textures.
Crafting
| Item | Bench | Materials |
|---|---|---|
| Bloodleaf Ring | Alchemy | Blood Petals x8 |
| Storm Ring | Arcane | Stormsilk Bolt x2 + Gold Bar x2 |
| Copper Bracelet | Workbench | Copper Bar x4 |
| Iron Bracelet | Workbench | Iron Bar x6 |
| Thorium Bracelet | Workbench | Thorium Bar x6 |
| Adamantite Bracelet | Workbench | Adamantite Bar x6 |
| Silk Necklace | Workbench | Silk Bolt x2 + Cobalt Bar x2 |
| Cindercloth Necklace | Arcane | Cindercloth Bolt x2 + Adamantite Bar x2 |
| Mithril Bracelet | Arcane | Mithril Bar x8 + Voidheart x1 |
| Onyxium Bracelet | Arcane | Onyxium Bar x8 + Voidheart x3 |
| Defense Talisman | Armour | Iron Bar x6 + Life Essence x4 |
| Speed Talisman | Alchemy | Life Essence x6 + Silver Bar x2 |
Commands
| Command | Description |
|---|---|
/baubles |
Open the baubles screen |
/baubles list |
List your equipped baubles and their effects |
The screen is an ordinary Hytale container window, so items move in and out with the usual inventory controls. You can also click a bauble to unequip it, or click an inventory item to equip it.
For mod authors
This is a library mod. It is designed to be depended on, and comes with a documented public API and a fully data-driven definition format.
Add a bauble by shipping two files — an item asset and a definition:
// Server/HyBauble/Baubles/My_Ring.json
{
"Item": "MYMOD_Amethyst_Ring",
"Slot": "Ring",
"Apply": "None",
"Effects": [
{ "Type": "STAT_ADD", "Stat": "Intelligence", "Amount": 5 },
{ "Type": "REGEN_PERCENT", "Stat": "Health", "Amount": 1 }
]
}
No Java required for ordinary stat and passive effects. Custom effect types are supported too, via BaubleEffectProvider.
See API.md for the full definition schema, the effect type reference, the public API surface, and worked examples.
Requirements
| Hytale server | 0.6.8 or later |
| Server-side only | Players do not need to install anything |
| Java | 25 |
Installation
- Drop
HyBaubles-1.0.0.jarinto your server'smods/folder. - Restart the server.
- Players run
/baublesin game.
The mod ships its own asset pack (items, models, textures, icons and localisation), so there is nothing else to install.
Notes and limitations
Documented honestly rather than left for you to discover:
- Movement speed is applied as a reversible delta. The bonus is folded into
MovementSettings.baseSpeedand undone on unequip, rather than storing each player's original configuration. - Resistances are capped at 95%, so stacked resistance baubles can never make a player immune.
/baubles listprints in English. The command help lines are localised; the list output is not yet.- Mining speed is deliberately not implemented. An earlier gathering talisman was removed because a block-break event identifies the block and tool but never the player swinging it, so a bonus could not be attributed reliably.
Compatibility
HyBaubles is server-side and self-contained. It adds its own slots and does not modify vanilla inventory, so it does not conflict with storage or inventory mods.
If you are building on HyBaubles, declare the dependency in your manifest:
"Dependencies": { "HyBaubles:HyBaubles": "^1.0.0" }
Support
Found a bug, or want to add a bauble? Open an issue with your server log and the item or definition you were using.
Adding HyBaubles support to your mod
HyBaubles adds eight accessory slots to every player. Your mod does not need to depend on it at compile time to put items in those slots - drop a small JSON file into your asset pack and the item becomes a bauble.
- Which approach should I use?
- Approach A - asset files (no code)
- The definition schema
- Effects reference
- Talisman families
- Custom effects
- Approach B - programmatic API
- Full worked example
- How loading works
- Troubleshooting
Which approach should I use?
| Approach A: asset files | Approach B: code | |
|---|---|---|
| Compile-time dependency | none | HyBaubles jar |
| Language | JSON | Java |
| Best for | most mods | generated items, conditional definitions, overriding another mod |
| Overrides Approach A? | - | yes, code always wins |
Start with Approach A. It requires no dependency and no code, and it is what HyBaubles itself uses for all fourteen of its own baubles.
Approach A - asset files (no code)
HyBaubles registers an asset store at the path HyBauble/Baubles, so files in your pack under that same path are loaded automatically alongside its own:
YourMod/
Server/
HyBauble/
Baubles/
MyMod_AmuletOfHaste.json <-- your definition
You do not need HyBaubles as a dependency for this, and you do not need to register anything - the files are discovered when the asset store loads. The only requirement is that your mod is loaded and that HyBaubles is present.
Your item still needs to exist
The definition decorates an item; it does not create one. Ship the item itself in the normal way:
YourMod/Server/Item/Items/Baubles/MyMod_AmuletOfHaste.json
and make sure both files agree on the item id.
The definition schema
{
"Item": "MyMod_AmuletOfHaste",
"Slot": "Talisman",
"TalismanFamily": "Haste",
"Apply": "None",
"Effects": [
{ "Type": "SPEED_PERCENT", "Amount": 15 }
]
}
| Key | Required | Type | Meaning |
|---|---|---|---|
Item |
yes | string | The item id this definition applies to |
Slot |
yes | string | Which slot family the item may occupy |
TalismanFamily |
no | string | Mutual-exclusion group for talismans (see below) |
Apply |
no | string | How the equipment bonus is applied. Default NONE |
Effects |
no | array | Dynamic behaviours HyBaubles runs for this item |
Slot values
The slot layout is fixed and ordered. Slot names the family, not an individual slot - HyBaubles places the item in the first free slot of that family.
Slot value |
Slots available | Notes |
|---|---|---|
"Ring" |
2 | |
"Necklace" |
1 | |
"Bracelet" |
1 | |
"Talisman" |
4 | subject to the family rule below |
A value that is not one of these four makes the item un-equippable; HyBaubles will reject the placement and tell the player why.
Apply values
| Value | What happens |
|---|---|
"None" |
HyBaubles applies nothing at equip time. Use this when the item's own JSON carries its bonus, or when you are using Effects only. |
"VanillaArmor" |
Your item JSON declares the bonus in its vanilla Armor block (StatModifiers, DamageResistance, …). The server applies and removes it natively; HyBaubles only enforces the slot. Most compatible option for stat bonuses. |
"Code" |
HyBaubles applies the bonus itself from your Effects list. |
Values are case-insensitive.
Note. Some effects are not entity stats at all - flat damage, movement speed, resistances. Those are always driven by
Effects, regardless ofApply.
Effects reference
Each entry in Effects is { "Type": ..., "Stat": ..., "Amount": ... }. Stat is required only for the effect types marked below; DamageCause is used by RESISTANCE_PERCENT.
Type |
Needs Stat |
Needs DamageCause |
Meaning |
|---|---|---|---|
STAT_ADD |
yes | no | Flat bonus to a stat's maximum. "Mana", Amount: 10 = +10 max mana |
STAT_PERCENT |
yes | no | Scales a stat's maximum. Amount: 20 = +20% |
REGEN_FLAT |
yes | no | Restores a flat amount of a stat every second, clamped to its maximum |
REGEN_PERCENT |
yes | no | Restores a percentage of the stat's maximum every second. Amount: 1 = 1%/s |
DAMAGE_FLAT |
no | no | Flat damage added to every hit the player deals |
DAMAGE_PERCENT |
no | no | Scales damage dealt. Amount: 10 = +10% |
SPEED_PERCENT |
no | no | Scales movement speed. Amount: 20 = +20% |
RESISTANCE_PERCENT |
no | optional | Reduces incoming damage of a matching cause. Amount: 50 = 50% reduction. With no DamageCause, applies to physical-class damage |
CUSTOM |
yes | no | Delegates to a provider you register in code. Stat is the provider name. See Custom effects |
Type is case-insensitive. An unrecognised Type is skipped (with the entry ignored) rather than failing the whole definition.
{
"Item": "MyMod_Bulwark_Talisman",
"Slot": "Talisman",
"Apply": "None",
"Effects": [
{ "Type": "STAT_ADD", "Stat": "Health", "Amount": 25 },
{ "Type": "RESISTANCE_PERCENT", "DamageCause": "Fire", "Amount": 50 }
]
}
Talisman families
Four talisman slots are available, but HyBaubles forbids equipping two talismans of the same family at once. This prevents stacking four identical copies of one item.
TalismanFamily |
Behaviour |
|---|---|
| omitted | The item's own id is the family, so the same talisman can never be equipped twice. This is the usual choice. |
"Haste" |
All talismans declaring "Haste" conflict with each other. Use this to model a tier chain where only the best one is active. |
The rule applies only to talismans. Rings, necklaces and bracelets have no equivalent restriction beyond the number of slots.
Custom effects
The built-in effect types cover stats, damage, speed and regeneration. For anything else, register a provider and reference it from your definition. This needs a compile-time dependency on HyBaubles.
1. Register a provider
import com.hybaubles.effect.BaubleCustomEffect;
import com.hybaubles.effect.BaubleEffectProvider;
import com.hybaubles.effect.BaubleEffects;
// In your plugin's setup() or later:
BaubleEffects.register("MyMod_Glow", new BaubleEffectProvider() {
@Override
public void onApplied(UUID player, BaubleCustomEffect effect,
Ref<EntityStore> ref, Store<EntityStore> store) {
// Start the effect. effect.amount() is the amount from your JSON.
}
@Override
public void onRemoved(UUID player, BaubleCustomEffect effect,
Ref<EntityStore> ref, Store<EntityStore> store) {
// Stop it and release anything you allocated. This is the only guaranteed teardown.
}
});
2. Reference it from a definition
{
"Item": "MyMod_Glowing_Ring",
"Slot": "Ring",
"Apply": "None",
"Effects": [
{ "Type": "CUSTOM", "Stat": "MyMod_Glow", "Amount": 3 }
]
}
Stat is the provider name. An effect whose provider name is unknown is inert rather than an error, so a definition can reference a provider from a mod that is not installed.
Lifecycle guarantees
HyBaubles reconciles your effects on every equipment change, and this is the part worth relying on:
| Situation | Callback |
|---|---|
| Bauble equipped, effect newly active | onApplied |
Amount or DamageCause changed (swapped to a stronger bauble) |
onUpdated (defaults to remove + apply) |
| Bauble unequipped, or effect no longer present | onRemoved |
| Player disconnects, or all baubles cleared | onRemoved for every active effect |
Effect instances are identified by a stable id derived from the slot, the item id and the provider name. That diffing is why your callbacks are not called repeatedly on every recompute — only genuine changes reach you.
Implement onRemoved as if it is the only teardown you get. It is called on unequip and on disconnect, but nothing guarantees a callback after a crash, so avoid leaking anything that outlives a session. Implementations must also tolerate being called more than once — never assume a single apply/remove pair.
If your provider throws, HyBaubles logs the failure and continues with the player's other bonuses,
so a bug in one provider cannot break unrelated baubles.
Approach B - programmatic API
Add HyBaubles as a dependency if you need to register from code, or to override another mod's definition. Code registrations always take precedence over parsed asset definitions, so this is also how you patch a definition you do not own.
import com.hybaubles.bauble.BaubleApplyMode;
import com.hybaubles.bauble.BaubleDefinition;
import com.hybaubles.bauble.BaubleEffect;
import com.hybaubles.bauble.BaubleEffectType;
import com.hybaubles.bauble.BaubleRegistry;
// In your plugin's setup() or start():
BaubleRegistry.get().register("MyMod_RingOfHaste", new BaubleDefinition(
"Ring", // slot family
null, // talisman family (null = derive from item id)
BaubleApplyMode.CODE, // how bonuses are applied
new BaubleEffect[] {
BaubleEffect.of(BaubleEffectType.SPEED_PERCENT, 10)
}));
Registry methods
| Method | Purpose |
|---|---|
register(itemId, definition) |
Register or override a definition. Takes precedence over asset files |
unregister(itemId) |
Remove a code registration, restoring any parsed definition |
definitionOf(itemId) |
The definition, or BaubleDefinition.NONE when the item is not a bauble |
isBauble(itemId) |
true when the item is handled by HyBaubles |
talismanFamilyOf(itemId) |
The mutual-exclusion family key for a talisman |
knownItemIds() |
Every known bauble id, parsed and code-registered |
Effect factory methods
| Call | Use |
|---|---|
BaubleEffect.of(type, amount) |
Effects needing no extra field |
BaubleEffect.stat(type, stat, amount) |
Effects keyed on an entity stat |
BaubleEffect.cause(type, damageCause, amount) |
RESISTANCE_PERCENT |
Call
registerfromsetup()or later. Registering from a static initialiser can run before the mod is loaded.
Full worked example
A talisman that grants +15% movement speed and registers itself from code.
1. The item - YourMod/Server/Item/Items/Baubles/MyMod_AmuletOfHaste.json
{
"TranslationProperties": {
"Name": "server.items.MyMod_AmuletOfHaste.name",
"Description": "server.items.MyMod_AmuletOfHaste.description"
},
"Icon": "Icons/ItemsGenerated/MyMod_AmuletOfHaste.png",
"MaxStack": 1,
"Quality": "Rare"
}
2. The definition - YourMod/Server/HyBauble/Baubles/MyMod_AmuletOfHaste.json
{
"Item": "MyMod_AmuletOfHaste",
"Slot": "Talisman",
"TalismanFamily": "Haste",
"Apply": "None",
"Effects": [
{ "Type": "SPEED_PERCENT", "Amount": 15 }
]
}
3. The icon - YourMod/Common/Icons/ItemsGenerated/MyMod_AmuletOfHaste.png
4. Optional text - YourMod/Server/Languages/en-US/server.lang
items.MyMod_AmuletOfHaste.name = Amulet of Haste
items.MyMod_AmuletOfHaste.description = A humming talisman that quickens your step.
Note the key does not include the server. prefix: the domain comes from the file name. The item's TranslationProperties should reference the full key including server..
That is all that is required. No code, no dependency.
How loading works
Understanding this helps when something does not appear.
- HyBaubles registers an asset store with id path
HyBauble/Baubles, keyed by file name, and declared to load after items. - When that store loads, every definition is parsed and the runtime registry is built from the complete set. The set is replaced, not merged, so deleting a JSON file also removes the bauble.
- Definitions naming a missing
ItemorSlotare skipped with a warning in the log.
Because the store is path-based and global, your files are picked up without any registration on your side - but it also means the item must be loaded before the definition is read, which the declared load order handles.
Troubleshooting
The item will not go into a slot. Check the log for a line naming your asset. The usual causes are a Slot value that is not one of Ring, Necklace, Bracelet, Talisman, or an Item id that does not match your item exactly (ids are case-sensitive).
"Only a ring can go in RING 2" or similar. Your definition was not loaded, so every slot rejects the item. Verify the file is under Server/HyBauble/Baubles/ and that the store loaded - HyBaubles logs registered N bauble definition(s). at startup, and N should include yours.
The effect does nothing. If Apply is "Code", the effect must be one HyBaubles can express. Stat effects also require the named stat to exist; check the stat name against the game's stat assets. If Apply is "VanillaArmor", the bonus must be in the item's own Armor block - HyBaubles will not apply it.
Two talismans conflict unexpectedly. You omitted TalismanFamily, so each talisman is its own family and duplicates are blocked. Set an explicit family if you want a tier chain where only one is active.
Editing a file has no effect. Asset stores are read at startup or on reload. Restart, or trigger an asset reload.


