Tools Needed
- Terraria - The game, buy it, kind of the purpose of this tutorial.
-- Terraria
- ILSpy - Or another suitable .NET decompiler.
-- ILSpy - SharpDevelop Wiki
- Visual Studio 2010
-- Free Developer Tools - Visual Studio 2010 Express | Microsoft Visual Studio
- XNA GameStudio 4
-- Download: Microsoft XNA Game Studio 4.0 - Microsoft Download Center - Download Details
What to do before-hand.
Please be sure that before you start this tutorial that:
- You have Terraria downloaded and installed.
- You have Visual Studio 2010 for C# installed and ready.
- You have XNA Game Studio 4 installed and ready.
I recommend using the latest nightly build of ILSpy for best support when decompiling Terraria.
Step 1. Decompile Terraria
Here is the short and easy steps of how to do this:
- Open ILSpy.exe
- Choose File -> Open from the top menu.
- Navigate the file selector to your Terraria.exe located at:
- C:\Program Files\Steam\steamapps\common\terraria
- On the left side, select Terraria from the treeview.
- Choose File -> Save Code
- Make a new folder on your desktop to save the code to and save it.
This will take about 2-5min depending on your system to fully decompile.
Step 2. Fixing The Errors
While this does convert the code back to a readable format, it isn't perfect. So there are errors to fix. There are about 70-80 errors to fix but they are simple fixes that wont take more then 5minutes to get all of them. Most are just casting problems since the decompiler does not account for casting types between one to another that well.
To start, load up the csproj file that ILSpy created on your desktop in the new folder. This should open Visual Studio 2010 when you open it.
Next try to build the source. You can do that by going to:
Build -> Rebuild Solution
This will ask you to save a solution file. Save it in the new folder you made on the desktop as well. Afterward it will try to compile the source and complain about a bunch of errors.
I'm not going to show you how to fix each error individually, but I will show you how to fix each unique error that shows up.
Projectile.cs - Only assignment, call, increment, decrement, and new object expressions can be used as a statement
- Comment out the line the error is on.
- // this.velocity != value2;
Main.cs, messageBuffer.cs -
Cannot implicitly convert type 'int' to 'byte'. An explicit conversion exists (are you missing a cast?)
- Surround the data in a cast like this:
- Before: color.R = Main.mouseTextColor / 2;
- After: color.R = (byte)(Main.mouseTextColor / 2);
Operator '??' cannot be applied to operands of type 'int' and 'int'
- Change these lines to be a full null check like this
- Before:
Code:
int num61 = num56 ?? -1;
- After:
Code:
int num61 = (num56 != null) ? num56 : -1;
WorldGen.cs -
Cannot implicitly convert type 'int' to 'short'. An explicit conversion exists (are you missing a cast?)
- Surround the data in a cast like this:
- Before: Main.tile[num3 + 1, num].frameX = num2 + 18;
- After: Main.tile[num3 + 1, num].frameX = (short)(num2 + 18);
No such label 'IL_2B5' within the scope of the goto statement
- Just comment out this line.
Fix all the errors and it should compile fine.
Removing Steam Requirement
If you hate having to run Steam in order to play a game you can remove the requirement by editing the following:
Program.cs - Find the following code:
Code:
Steam.Init();
if (Steam.SteamInit)
{
main.Run();
}
else
{
MessageBox.Show("Please launch the game from your Steam client.", "Error");
}
Change the code to:
Code:
//Steam.Init();
//if (Steam.SteamInit)
//{
main.Run();
//}
//else
//{
// MessageBox.Show("Please launch the game from your Steam client.", "Error");
//}
Collectors Edition
To change the client to the collectors edition client, you can edit the following:
Main.cs - Find the following code:
Code:
protected void CheckBunny()
{
try
{
RegistryKey registryKey = Registry.CurrentUser;
registryKey = registryKey.CreateSubKey("Software\\Terraria");
if (registryKey != null && registryKey.GetValue("Bunny") != null && registryKey.GetValue("Bunny").ToString() == "1")
{
Main.cEd = true;
}
}
catch
{
Main.cEd = false;
}
}
Change to:
Code:
protected void CheckBunny()
{
Main.cEd = true;
}