Modding Terraria – Part 4 Adding a mount

Modding Terraria is a fun method to add and adjust features in a playful way and learn more about programming. In this part, we add a custom mount!

This post has been updated to work with tModLoader v2023.9.3.0

We will continue where we left off in the previous part. If you haven´t read that one yet, you can find it here.

Custom mount in Terraria

This time, we will create a custom hot air balloon mount with which you can fly around in the magical lands of Terraria.

Let’s get started!

Open up tModLoader and your Visual Studio project.

Creating our mount summon item

Just like in part 2 of the modding Terraria series, we will start with our Items directory. However, this time it will be inside a sub-directory called Mounts In Terraria, mounts require an item to be summoned.

Let’s get into the coding part. Create a directory called Mounts inside the Items directory. Inside the Mounts directory, create a file called HotAirBalloonMountItem.cs with the following code.

using Mountmod.Mounts; // We will be creating this in a later step so ignore any errors for now
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Mountmod.Items // Update this namespace with your project name. In our case, it's Mountmod
{
    class HotAirBalloonMountItem: ModItem
    {
        public override void SetDefaults()
        {
            Item.width = 32;
            Item.height = 32;
            Item.useTime = 20;
            Item.useAnimation = 20;
            Item.useStyle = ItemUseStyleID.MowTheLawn;
            Item.value = Item.sellPrice(gold: 3);
            Item.rare = ItemRarityID.Green;
            Item.UseSound = SoundID.Item79;
            Item.noMelee = true;
            Item.mountType = ModContent.MountType<HotAirBalloonMount>(); // We will fix this error when we create the actual mount
        }

        public override void AddRecipes()
        {
            Recipe recipe = CreateRecipe();
            recipe.AddIngredient(ItemID.DirtBlock, 10);
            recipe.AddTile(TileID.WorkBenches);
            recipe.Register();
        }
    }
}

For the item image we will use the following image but feel free to create your own!
HotAirBalloonMountItem

What we’ve done here is, create a new ModItem. You are free to change the default values as you like. Keep in mind however that the width and height are equal to the sizes of your image which you’re using. In our case, this is 32×32.

Finally, we add our crafting recipe for this mount. You can opt to make this mount not craftable and instead be obtainable but for simplicity sake we will be able to craft our version with 10 dirt. In a later part we will cover loot tables and how to add custom drops, so keep a watch on our latest posts!

Now that we’ve set up our item, we will need to create our buff. Mounts, potions and pets are considered buffs within Terraria which is why we need to create our own.

Creating our mount buff

Create or enter your Buffs directory and create the following file inside HotAirBalloonMountBuff.cs. Before we add code to this file it’s important to understand that buffs, like items, come with an image. For our buff we will be using the following image but like the rest of this tutorial, feel free to use your own assets!

HotAirBalloonMountBuff

Add this or your own image inside your Buffs directory.

After you’ve done that, open up HotAirBalloonMountBuff.cs and add the following code

using Terraria;
using Terraria.ModLoader;

namespace Mountmod.Buffs // Update this namespace with your project name. In our case, it's Mountmod
{
    public class HotAirBalloonMountBuff: ModBuff
    {
        public override void SetStaticDefaults()
        {
            Main.buffNoTimeDisplay[Type] = true;
            Main.buffNoSave[Type] = true;
        }

        public override void Update(Player player, ref int buffIndex)
        {
            player.mount.SetMount(ModContent.MountType<Mounts.HotAirBalloonMount>(), player);
            player.buffTime[buffIndex] = 10;
        }
    }
}

This file is luckily pretty simple. We create a ModBuff and first, like our items, set some default values. These two default values however are special: Main.buffNoTimeDisplay[Type] = true; and Main.buffNoSave[Type] = true;. These make it so our mount doesn’t show the remainder of the duration and that we don’t spawn as our mount when we quit the game respectively.

Inside the Update method, we invoke the SetMount function with an instance of our hot air balloon. Don’t worry about your errors just yet, we will create our actual mount in the last part! player.buffTime[buffIndex] = 10; makes it so our mount never expires.

Now that we have both our item and buff created, we can move on to the actual mount!

Creating our mount

For this part, we will require a directory called Mounts so enter or create this directory. You won’t believe what’s coming next, we need an image for our mount! We will be using the following sprite sheet.

HotAirBalloonMount_Front
Image taken from www.svgrepo.com. We don’t take any credits for the actual image. We only turned it into a sprite sheet.

After you’ve saved this image inside your Mounts directory, create the following file called AirBalloon.cs and add the following code.

using Microsoft.Xna.Framework;
using Mountmod.Buffs;
using System;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;

namespace Mountmod.Mounts // Update this namespace with your project name. In our case, it's Mountmod
{
    public class HotAirBalloonMount: ModMount
    {
        public override void SetStaticDefaults()
        {
	    MountData.buff = ModContent.BuffType();

            // Movement fields:
            MountData.flightTimeMax = 999; // always set flight time to a high amount for flying mounts
            MountData.fallDamage = 0; // how much fall damage will the player take in the hot air balloon
            MountData.runSpeed = 5f; // how fast can the mount go
            MountData.acceleration = 1f; // how fast does the hot air balloon accelerate
            MountData.jumpHeight = 5; // how far does the hot air balloon jump
            MountData.jumpSpeed = 2; // how fast does the  hot air balloon jump
            MountData.blockExtraJumps = true; // Can the player not use a cloud in a bottle when in the hot air balloon?
            MountData.heightBoost = 12;

            // Drawing fields:
            MountData.playerYOffsets = new int[] { 0, 0, 0 }; // where is the players Y position on the mount for each frame of animation
            MountData.xOffset = 2; // the X offset of the sprite
            MountData.yOffset = -35; // the Y offset of the sprite
            MountData.bodyFrame = 3; // which body frame is being used from the player when the player is boarded on the mount
            MountData.playerHeadOffset = 14; // Affects where the player head is drawn on the map

            MountData.totalFrames = 3;
          
            MountData.flyingFrameCount = 2;
            MountData.flyingFrameDelay = 12;
            MountData.flyingFrameStart = 1;
            MountData.inAirFrameCount = 2;
            MountData.inAirFrameDelay = 12;
            MountData.inAirFrameStart = 1;

            if (Main.netMode != NetmodeID.Server)
            {
                MountData.textureWidth = MountData.frontTexture.Width();
                MountData.textureHeight = MountData.frontTexture.Height();
            }
        }
    }
}

While this file can become a bit complex when taking custom movement and dust particles into account, a basic mount script would look like this. A couple of important things to note here are MountData.buff = ModContent.BuffType(); which links our buff we created to our mount and MountData.totalFrames = 3; which is the number of frames our sprite sheet has. In our case, this is 3. All the other properties we’ve set are either commented or pretty straightforward. The actual numbers are a bit trial and error depending on the size of your mount so we advise you to play a bit with the numbers.
Lastly, we have this section which is just a fail-safe to make our mount texture be the _Front texture as it could cause de-sync for other players.

if (Main.netMode != NetmodeID.Server)
            {
                MountData.textureWidth = MountData.frontTexture.Width();
                MountData.textureHeight = MountData.frontTexture.Height();
            }

Conclusion

If you’ve followed along, you should now be able to create a basic custom mount in Terraria and apply images to it!

The final step is to, hop into your game, build your mod and enter your world. Next, grab 10 dirt and you’ll be surprised by a flight permit showing up. Put the flight permit into your mount slot and you should be greeted with your own personal hot air balloon!

custom mount in Terraria - Hot air balloon in action

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *