promotional bannermobile promotional banner

HyBaubles

Baubles for Hytale, with API Support

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.

image

image

image

Compatible with RPG Leveling and Stats/Skills:

image

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:


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

  1. Drop HyBaubles-1.0.0.jar into your server's mods/ folder.
  2. Restart the server.
  3. Players run /baubles in 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.baseSpeed and 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 list prints 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 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 of Apply.


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 register from setup() 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.

  1. HyBaubles registers an asset store with id path HyBauble/Baubles, keyed by file name, and declared to load after items.
  2. 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.
  3. Definitions naming a missing Item or Slot are 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.

The HyBaubles Team

profile avatar
  • 2
    Followers
  • 12
    Projects
  • 18.3K
    Downloads

More from Gameboy612View all