Skip to content

Adding an Attribute

CleverNucleus edited this page Jun 22, 2021 · 1 revision

Adding an Attribute

In order to explain the full extent of the API, an example mod will be created. It is assumed that you are already familiar with Fabric.

Let us start with the main mod file, ExampleMod.java:

public final class ExampleMod implements ModInitializer {
    // Defining our modid
    public static final String MODID = "examplemod";
    // Defining access to our attribute
    public static final IAttribute MAX_MANA = PlayerAttributes.find(new Identifier(MODID, "max_mana"));
    
    @Override
    public void onInitialize() {
        
    }

In our mod's resources folder, we need to define our attribute's json file. We need to put it in data/examplemod/attributes and we need to call it max_mana.json. It is defined below:

{
    "type": "GAME",
    "uuid": "0407920b-bd3a-4743-96e8-ee23aa8f0528",
    "defaultValue": 10.0,
    "minValue": 0.0,
    "maxValue": 2147483647.0,
    "translationKey": "attribute.name.examplemod.max_mana",
    "properties": {
        "weight": 0.8,
        "minroll": 1.0,
        "maxroll": 10.0
    },
    "functions": []
}

We needed to generate a new UUID for our attribute, if you don't know how then this webpage may help (although if you need to read it you probably shouldn't be modding yet). We also need to define a name for our attribute in our language file:

{
    "attribute.name.examplemod.max_mana": "Max Mana"
}

We now have a fully functional attribute that we can play around with, congrats!

We want to add a way to increase the Max Mana when we skill Intelligence, much like how we increase our Max Health when we skill Constitution. To do this we need to define an Attribute Function somewhere, and we can do this one of two ways: using a datapack entry (see Datapacks and Attribute Functions); or hardcoding it. Since the aforementioned pages describe the first method, we will hardcode it.

In our ExampleMod.java:

...
@Override
public void onInitialize() {
    ExAPI.REGISTRY.get().registerFunction(new Identifier("playerex:intelligence"), new IAttributeFunction() {
        
        @Override
        public Identifier attributeKey() {
            return new Identifier("examplemod:max_mana");
        }
        
        @Override
        public Type type() {
            return Type.FLAT;
        }
        
        @Override
        public double multiplier() {
            return 1.0D;
        }
    });
}
...

Optionally it may be preferable to create an implementation IAttributeFunction to keep things tidy. The above will register an attribute function to Intelligence, so that for every change in Intelligence's value, the same change will apply to Max Mana.