Agrair
Terrarian
Terraria Interface for Dummies
Congrats! You found my guide on Terraria’s user interface. In this guide, I’ll go over what and how interfaces work, how to create one, and then properly implement it into your mod. It requires some basic terminology, like “class” and “method”. I suggest you figure out what these mean.
There’s also a mod that goes with this. You may have gotten here because of it. If you load it in game, you can use commands to see each example (i.e. /something will display the first example). If you want, here's the source: Agrair/TerrariaUITutorial
Fundamentals
The Terraria UI framework is very polymorphic. All classes (at least the one’s I’ll show) inherit from UIElement, allowing us to manipulate our UI to a great extent. Don’t understand? It’ll become clear soon enough. There are three classes you’ll probably use the most. UIState, UIPanel, and UIElement (UIState and UIPanel inherit from UIElement, meaning values and methods in UIElement will appear in both without actually being implemented. We use this to our advantage). You can think of UI as a family tree. UIState is the head of the family, UIPanels are beneath them, and UIElements beneath them. UIPanels and UIElements are appended to their “parents”. In a practical sense, only UIPanels can draw themselves because they usually tend to be blue rectangles that look like control panels in game (hence the name). Not too much complexity, is there. UIElements are things like buttons and text boxes. They move, change, and are interacted with by the player. You can always append UIElements directly to a UIState if you don’t want to use UIPanels. You use a UIState to keep them all in one place. There’s a fourth class I haven’t talked about, and it’s called UserInterface. This is a handy little “wrapper” that does all the extra stuff for you and puts them into one or two methods.
Still with me? Great, on to the next bit. You can always take a break though, which is a good idea if you need a rest from reading.
Starting out - Something
We’re going to create a blank square that we can drag around the screen. First, you want to create a folder called UI and a file called "SomethingUI.cs" (change this to whatever you want) inside. Note that you need to change `TerrariaUITutorial` and `SomethingUI` to whatever you like. Namespace is just the same as folder path.
Code:
using Terraria.UI;
namespace TerrariaUITutorial.UI
{
internal class SomethingUI : UIState
{
public override void OnInitialize()
{
}
}
}
Code:
using Terraria.UI;
namespace TerrariaUITutorial.UI
{
internal class SomethingUI : UIState
{
public static bool visible;
public DragableUIPanel panel;
public override void OnInitialize()
{
// if you set this to true, it will show up in game
visible = false;
panel = new DragableUIPanel(); //initialize the panel
// ignore these extra 0s
panel.Left.Set(800, 0); //this makes the distance between the left of the screen and the left of the panel 500 pixels (somewhere by the middle)
panel.Top.Set(100, 0); //this is the distance between the top of the screen and the top of the panel
panel.Width.Set(100, 0);
panel.Height.Set(100, 0);
Append(panel); //appends the panel to the UIState
}
}
}
Code:
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ModLoader;
using Terraria.UI;
using TerrariaUITutorial.UI;
namespace TerrariaUITutorial
{
public class TerrariaUITutorial : Mod
{
internal SomethingUI somethingUI;
public UserInterface somethingInterface;
public override void Load()
{
// this makes sure that the UI doesn't get opened on the server
// the server can't see UI, can it? it's just a command prompt
if (!Main.dedServ)
{
somethingUI = new SomethingUI();
somethingUI.Initialize();
somethingInterface = new UserInterface();
somethingInterface.SetState(somethingUI);
}
}
public override void UpdateUI(GameTime gameTime)
{
// it will only draw if the player is not on the main menu
if (!Main.gameMenu
&& SomethingUI.visible)
{
somethingInterface?.Update(gameTime);
}
}
public override void ModifyInterfaceLayers(List<GameInterfaceLayer> layers)
{
layers.Add(new LegacyGameInterfaceLayer("Cool Mod: Something UI", DrawSomethingUI, InterfaceScaleType.UI));
}
private bool DrawSomethingUI()
{
// it will only draw if the player is not on the main menu
if (!Main.gameMenu
&& SomethingUI.visible)
{
somethingInterface.Draw(Main.spriteBatch, new GameTime());
}
return true;
}
}
}
Congrats, you've created your first UI! However, there's *still* something wrong with your UI. Changing the UI scale in your settings will completely change the position. We can remedy this by making the code look like this now:
Code:
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.UI;
namespace TerrariaUITutorial.UI
{
internal class SomethingUI : UIState
{
public static bool visible;
private DragableUIPanel panel;
public float oldScale;
public override void OnInitialize()
{
// if you set this to true, it will show up in game
visible = false;
panel = new DragableUIPanel(); //initialize the panel
// ignore these extra 0s
panel.Left.Set(800, 0); //this makes the distance between the left of the screen and the left of the panel 800 pixels (somewhere by the middle).
panel.Top.Set(100, 0); //this is the distance between the top of the screen and the top of the panel
panel.Width.Set(100, 0);
panel.Height.Set(100, 0);
Append(panel); //appends the panel to the UIState
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
if (oldScale != Main.inventoryScale)
{
oldScale = Main.inventoryScale;
Recalculate();
}
}
}
}
UI is a very delicate part of coding, and I hope that this guide helped you in some way or another. Sometimes, it can take awhile to complete, but with enough practice and understanding you can get the hang of it. If you found this tutorial helpful, I'm glad you did.
Last edited: