Creating a custom syringe

A syringe is a liquid container. Most syringes consist of two components: the syringe behaviour and the liquid definition.

1. Creating a syringe spawnable

using UnityEngine; 

namespace Mod
{
    public class Mod
    {
        public static void Main()
        {
            // registering a custom item
            ModAPI.Register(
                new Modification()
                {
                    OriginalItem = ModAPI.FindSpawnable("Acid Syringe"), // derive from a syringe
                    NameOverride = "Nitroglycerin Syringe [mod name]",
                    DescriptionOverride = "Syringe full of nitroglycerin.",
                    CategoryOverride = ModAPI.FindCategory("Biohazard"),
                    ThumbnailOverride = ModAPI.LoadSprite("nitro syringe view.png"),
                    AfterSpawn = (Instance) =>
                    {
                        // destroy the existing syringe behaviour
                        UnityEngine.Object.Destroy(Instance.GetComponent<SyringeBehaviour>());

                        // add the new syringe behaviour (unless it already exists)
                        Instance.GetOrAddComponent<NitroglycerinSyringe>();
                    }
                }
            );
        }
    }

    // define the syringe behaviour
    public class NitroglycerinSyringe : SyringeBehaviour
    {
        // provide the liquid ID for this syringe
        public override string GetLiquidID() => Nitroglycerine.ID;
    }
}

All syringes have a unique behaviour associated with them. This isn't strictly necessary but it allows for other unique effects, mostly taken advantage of by the Pink Syringe.

2. Creating a custom liquid

In the above section, we created a syringe full of an existing liquid. You can define your own liquid, with its own effects, and use that instead.

Instead of a nitroglycerin syringe, let's add a syringe that makes limbs unbreakable. First, change the spawnable definition.

ModAPI.Register(
    new Modification()
    {
        OriginalItem = ModAPI.FindSpawnable("Acid Syringe"),
        NameOverride = "Durability Syringe [mod name]", // different name
        DescriptionOverride = "Syringe full of an enhancing serum that makes limbs unbreakable.", // different description
        CategoryOverride = ModAPI.FindCategory("Biohazard"),
        ThumbnailOverride = ModAPI.LoadSprite("durability syringe view.png"), //different thumbnail
        AfterSpawn = (Instance) =>
        {
            UnityEngine.Object.Destroy(Instance.GetComponent<SyringeBehaviour>());

            // different behaviour. we will make this in a moment.
            Instance.GetOrAddComponent<DurabilitySyringe>();
        }
    }

Then we change the syringe behaviour we created. Here's a convenient colour picker.

public class DurabilitySyringe : SyringeBehaviour
{
    // provide the liquid ID for this syringe
    public override string GetLiquidID() => DurabilitySerum.ID;

    // we can make it a nested class for extra localisation points
    public class DurabilitySerum : Liquid // if you wanted this effect to be temporary, you can derive from TemporaryBodyLiquid instead
    {
        // declare a globally unique ID for this liquid
        public const string ID = "DURABILITY SERUM [mod name]";

        public DurabilitySerum()
        {
            // assign the colour of the liquid. a pleasant yellow-green for this one
            Color = new UnityEngine.Color(0.69f, 1f, 0.35f);
        }

        //Called when this liquid enters a limb.
        //Note that this may be called quite often for the same container as liquid quickly moves in and out of it.
        public override void OnEnterLimb(LimbBehaviour limb)
        {
            //this is where syringes usually apply their effects.
            limb.BreakingThreshold = 10000;
        }

        //Called every second by every container for every liquid it contains.
        public override void OnUpdate(BloodContainer container)
        {
            //for syringe liquids, this is usually empty.
            //if you want a syringe effect to be continuously applied, you should implement the effects here instead.
            //make sure to check if the given container is actually a CirculationBehaviour.
            
            //do note that this has to call base.OnUpdate(container) if you are derving from TemporaryBodyLiquid
        }

        //Called when this liquid enters a container. Limbs are also containers. 
        //Note that this may be called quite often for the same container as liquid quickly moves in and out of it.
        public override void OnEnterContainer(BloodContainer container)
        {
            //for syringe liquids, this is usually empty.
        }
    
        //Called when this liquid exits a container. 
        //Note that this may be called quite often for the same container as liquid quickly moves in and out of it.
        public override void OnExitContainer(BloodContainer container)
        {
            //for syringe liquids, this is usually empty.
        }
    }
}

3. Registering a custom liquid

Before any liquid can be used, it has to be registered to the liquid registry. More information here.

In short, add ModAPI.RegisterLiquid(DurabilitySyringe.DurabilitySerum.ID, new DurabilitySyringe.DurabilitySerum()); before anything in your Main method, like so:

using UnityEngine; 

namespace Mod
{
    public class Mod
    {
        public static void Main()
        {
            ModAPI.RegisterLiquid(DurabilitySyringe.DurabilitySerum.ID, new DurabilitySyringe.DurabilitySerum());
            ...

4. Summary

In summary, this guide has shown how to:

Ultimately, this is what our file looks like now:

using UnityEngine; 

namespace Mod
{
    public class Mod
    {
        public static void Main()
        {
            ModAPI.RegisterLiquid(DurabilitySyringe.DurabilitySerum.ID, new DurabilitySyringe.DurabilitySerum());
            
            ModAPI.Register(
                new Modification()
                {
                    OriginalItem = ModAPI.FindSpawnable("Acid Syringe"),
                    NameOverride = "Durability Syringe [mod name]",
                    DescriptionOverride = "Syringe full of an enhancing serum that makes limbs unbreakable.",
                    CategoryOverride = ModAPI.FindCategory("Biohazard"),
                    ThumbnailOverride = ModAPI.LoadSprite("durability syringe view.png"),
                    AfterSpawn = (Instance) =>
                    {
                        UnityEngine.Object.Destroy(Instance.GetComponent<SyringeBehaviour>());
                        Instance.GetOrAddComponent<DurabilitySyringe>();
                    }
                }
            );
        }
    }

    public class DurabilitySyringe : SyringeBehaviour
    {
        public override string GetLiquidID() => DurabilitySerum.ID;

        public class DurabilitySerum : Liquid
        {
            public const string ID = "DURABILITY SERUM [mod name]";

            public DurabilitySerum()
            {
                Color = new UnityEngine.Color(0.69f, 1f, 0.35f);
            }

            public override void OnEnterLimb(LimbBehaviour limb)
            {
                limb.BreakingThreshold = 10000;
            }

            public override void OnUpdate(BloodContainer container) {}
            public override void OnEnterContainer(BloodContainer container) {}
            public override void OnExitContainer(BloodContainer container) {}
        }
    }
}

Attention!

This member is obsolete and should not be used. It is a remnant from the past.

bi bij bibi