Standalone [1.3] tModLoader - A Modding API

Fixed.

No one has tried, but I imagine it might be possible.

For Git, just download GitHub Desktop, there is no reason to learn the commands yourself. You just type a message for a commit, submit and sync.

You can look up the aiStyle and type in the wiki and use those values to mimic AI. Or, you can copy the code from decompiled terraria and modify the code to fit your new NPC. You can decompile and save the code with Ilspy.

It's all in NPC.cs. First find the type of the worm (head, body, and tail), see which aiStyle they use, then find the code that corresponds to that aiStyle and type.

Just call the code to place the tiles when the npc dies. HitEffect if (npc.life <= 0).

Are you positive everyone playing with you has all the same mods, all the same versions? Any clue what event causes this? We need more info to fix this bug.
We all have the same mods, the same versions of the mods,
 
I need help...
2016-02-27_00006.jpg
That was after i quit the game... later i see that the character not saved~also corrupted, not that i quit the game
2016-02-28_00003.jpg
then i see that after i play with the other character this gonna happen to...
2016-02-28_00002.jpg
and i can't create new characters...
Apk.PNG

and all happen after i reach the 500 hours milestone on steam...
 
Last edited:
Hi Jopojelly, I got GitHub desktop, cloned the repository, decompiled terraria without any errors, open vs solution, compiled it fine.
Try to run / debug the build and I get this error:
Code:
System.TypeInitializationException was unhandled
Message: An unhandled exception of type 'System.TypeInitializationException' occurred in Terraria.exe
Additional information: The type initializer for 'Terraria.Main' threw an exception.
Any thoughts? I'd like to contribute if I can.
Did you try to run it from visual studio? You can build, but the working directory thing never worked for me, so I build and then open up Terraria directly. (Build copies the exe in)

You need to do port forwarding and connect via IP. That solved problems for me.

Anyone knows what causes it?
Good to know port forwarding solved it for you. Also, I still don't know what triggers the bug.

Hey,
thanks for the info and good to hear it has been fixxed.
is there an estimated time for a release?
the sync fix would be realy nice atleast
It'd be nice to release when we fix all the bugs that have been found. And I might make an auto updater. No idea right now for certain.

Did you fix error above?
The get alpha one? I haven't even reproduced it yet.

I need help...
View attachment 98579
That was after i quit the game... later i see that the character not saved~also corrupted, not that i quit the game
View attachment 98584
then i see that after i play with the other character this gonna happen to...
View attachment 98583
and i can't create new characters...
View attachment 98586
and all happen after i reach the 500 hours milestone on steam...
This was a bug in the old version. You should update to the latest tmodloader.

You'll lose mod items in your inventory, but you can delete the Tplr file and cheat them back in to play your character again.
 
ok thanks Jopojelly youre the best
[DOUBLEPOST=1456695100,1456695029][/DOUBLEPOST]and i am so dumb i never show at the tmod version... and i google for hours, i ama jackass
 
The source code does some really weird things.

Because the UseItem hook is called on the server, it allows for things like NPCs to spawn. Because the Shoot hook is called only on the client, it allows for the projectile's owner to be easily set (and also makes it so that you can see what you shoot right away).
Well, that's interesting. Looks like I might need to use both UseItem and Shoot at once, though I hope there's a better way.

Another thing, I have a custom field in a modBuff, and I found that it's value isn't reset when a player quits and reloads a world. Is there a way to reset a field on a buff when a player enters a world? Also, tAPI's modBuff had Start and End hooks that I found very useful. Could these be added to tModLoader? It would also be great if modBuff had a onEnterWorld hook, then I wouldn't need to reset my field.

Thank you.
 
Well, that's interesting. Looks like I might need to use both UseItem and Shoot at once, though I hope there's a better way.

Another thing, I have a custom field in a modBuff, and I found that it's value isn't reset when a player quits and reloads a world. Is there a way to reset a field on a buff when a player enters a world? Also, tAPI's modBuff had Start and End hooks that I found very useful. Could these be added to tModLoader? It would also be great if modBuff had a onEnterWorld hook, then I wouldn't need to reset my field.

Thank you.
Well, the problem is that tModLoader doesn't actually create ModBuff objects for each buff (ModBuff acts in a similar way to ModTile). Would you be able to transfer the field to ModPlayer or NPCInfo?
 
i hate it... the version 7.1.1 mean for me that must recover all my items... and i have many mod items in my inventory everytime... F*ckkkkkkkkkkkkkkk
[DOUBLEPOST=1456698996,1456698487][/DOUBLEPOST]oh hell thanks... tremor is not jet ready involved and i IS MY MAIN MOD... second F*ckkkkkkkkkkkkkkk
 
It's probably missing code. The spawning thing probably isn't in the AI directly, but in another part of it. (Don't quote me - this is an educated guess)
 
Fixed.

No one has tried, but I imagine it might be possible.

For Git, just download GitHub Desktop, there is no reason to learn the commands yourself. You just type a message for a commit, submit and sync.

You can look up the aiStyle and type in the wiki and use those values to mimic AI. Or, you can copy the code from decompiled terraria and modify the code to fit your new NPC. You can decompile and save the code with Ilspy.

It's all in NPC.cs. First find the type of the worm (head, body, and tail), see which aiStyle they use, then find the code that corresponds to that aiStyle and type.

Just call the code to place the tiles when the npc dies. HitEffect if (npc.life <= 0).

Are you positive everyone playing with you has all the same mods, all the same versions? Any clue what event causes this? We need more info to fix this bug.

When I tried to make my New custom ore generate underground randomly once the custom boss is defeated I got this error
c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(51,9) : error CS0103: The name 'Codable' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(51,67) : error CS0103: The name 'Codable' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(72,202) : error CS0103: The name 'Config' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(75,27) : error CS0117: 'Terraria.ModLoader.ModWorld' does not contain a definition for 'misc'

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(77,46) : error CS0117: 'Terraria.ModLoader.ModWorld' does not contain a definition for 'misc'

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(81,20) : error CS0117: 'Terraria.NetMessage' does not contain a definition for 'SendModData'

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(81,32) : error CS0103: The name 'modId' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(82,5) : error CS0103: The name 'Codable' does not exist in the current context

Here is the code for the World.cs file
Code:
using System.IO;
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.World.Generation;
using Microsoft.Xna.Framework;
using System;

namespace EpicnessMod
{
    public class EpicnessWorld : ModWorld
    {
        private const int saveVersion = 0;
        public static bool downedDarkNebula = false;
        public static int DarkNebulaDefeated;
        public const int MSG_BLESS = 1;
       
        //public struct EpicnessMsgs
//{
public static string[] misc = {"Your world has been infected with Corrupt Ore!"};
//}

        public override void Initialize()
        {
            downedDarkNebula = false;
        }

        public override void SaveCustomData(BinaryWriter writer)
        {
            writer.Write(saveVersion);
            byte flags = 0;
            writer.Write(DarkNebulaDefeated);
            if (downedDarkNebula)
            {
                flags |= 1;
            }
            writer.Write(flags);
        }

        public override void LoadCustomData(BinaryReader reader)
        {
            reader.ReadInt32();
            DarkNebulaDefeated = reader.ReadInt32();
            byte flags = reader.ReadByte();
            downedDarkNebula = ((flags & 1) == 1);
        }
#region Bless() : void [STATIC]
public static void Bless()
{
    if (Codable.RunGlobalMethod("ModWorld", "PreBless") && !(bool)Codable.customMethodReturn)
        return;
    if (Main.netMode == 1) return;
    DarkNebulaDefeated++;
    int amount = 0;
    double num5;
    num5 = Main.rockLayer;
    int xloc = -100 + Main.maxTilesX - 100;
    int yloc = -(int)num5 + Main.maxTilesY - 200;
    int sum = xloc * yloc;
    amount = (int)(sum / 10000) * 10;
    if (DarkNebulaDefeated == 1)
    {
        if (DarkNebulaDefeated == 1)
        {
            for(int zz = 0; zz < amount; zz++)
            {
                int i2 = WorldGen.genRand.Next(100, Main.maxTilesX - 100);
                double num6;
                num6 = Main.rockLayer;
                int j2 = WorldGen.genRand.Next((int)num6, Main.maxTilesY - 200);
                WorldGen.OreRunner(i2, j2, (double)WorldGen.genRand.Next(WorldGen.genRand.Next(2, 4), WorldGen.genRand.Next(4, 7)), WorldGen.genRand.Next(WorldGen.genRand.Next(3, 5), WorldGen.genRand.Next(4, 8)), Config.tileDefs.ID["Corrupted Ore"]);
            }
            if (Main.netMode == 0)
                Main.NewText(ModWorld.misc[1], 80, 65, 130);
            else if (Main.netMode == 2)
                NetMessage.SendData(25, -1, -1, ModWorld.misc[1], 255, 80f, 65f, 130f, 0);
        }
    }
    if (Main.netMode == 2)
        NetMessage.SendModData(modId, MSG_BLESS, -1, -1, -1);
    Codable.RunGlobalMethod("ModWorld", "PostBless");
}
#endregion
    }
}
 
When I tried to make my New custom ore generate underground randomly once the custom boss is defeated I got this error
c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(51,9) : error CS0103: The name 'Codable' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(51,67) : error CS0103: The name 'Codable' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(72,202) : error CS0103: The name 'Config' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(75,27) : error CS0117: 'Terraria.ModLoader.ModWorld' does not contain a definition for 'misc'

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(77,46) : error CS0117: 'Terraria.ModLoader.ModWorld' does not contain a definition for 'misc'

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(81,20) : error CS0117: 'Terraria.NetMessage' does not contain a definition for 'SendModData'

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(81,32) : error CS0103: The name 'modId' does not exist in the current context

c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(82,5) : error CS0103: The name 'Codable' does not exist in the current context

Here is the code for the World.cs file
Code:
using System.IO;
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.World.Generation;
using Microsoft.Xna.Framework;
using System;

namespace EpicnessMod
{
    public class EpicnessWorld : ModWorld
    {
        private const int saveVersion = 0;
        public static bool downedDarkNebula = false;
        public static int DarkNebulaDefeated;
        public const int MSG_BLESS = 1;
      
        //public struct EpicnessMsgs
//{
public static string[] misc = {"Your world has been infected with Corrupt Ore!"};
//}

        public override void Initialize()
        {
            downedDarkNebula = false;
        }

        public override void SaveCustomData(BinaryWriter writer)
        {
            writer.Write(saveVersion);
            byte flags = 0;
            writer.Write(DarkNebulaDefeated);
            if (downedDarkNebula)
            {
                flags |= 1;
            }
            writer.Write(flags);
        }

        public override void LoadCustomData(BinaryReader reader)
        {
            reader.ReadInt32();
            DarkNebulaDefeated = reader.ReadInt32();
            byte flags = reader.ReadByte();
            downedDarkNebula = ((flags & 1) == 1);
        }
#region Bless() : void [STATIC]
public static void Bless()
{
    if (Codable.RunGlobalMethod("ModWorld", "PreBless") && !(bool)Codable.customMethodReturn)
        return;
    if (Main.netMode == 1) return;
    DarkNebulaDefeated++;
    int amount = 0;
    double num5;
    num5 = Main.rockLayer;
    int xloc = -100 + Main.maxTilesX - 100;
    int yloc = -(int)num5 + Main.maxTilesY - 200;
    int sum = xloc * yloc;
    amount = (int)(sum / 10000) * 10;
    if (DarkNebulaDefeated == 1)
    {
        if (DarkNebulaDefeated == 1)
        {
            for(int zz = 0; zz < amount; zz++)
            {
                int i2 = WorldGen.genRand.Next(100, Main.maxTilesX - 100);
                double num6;
                num6 = Main.rockLayer;
                int j2 = WorldGen.genRand.Next((int)num6, Main.maxTilesY - 200);
                WorldGen.OreRunner(i2, j2, (double)WorldGen.genRand.Next(WorldGen.genRand.Next(2, 4), WorldGen.genRand.Next(4, 7)), WorldGen.genRand.Next(WorldGen.genRand.Next(3, 5), WorldGen.genRand.Next(4, 8)), Config.tileDefs.ID["Corrupted Ore"]);
            }
            if (Main.netMode == 0)
                Main.NewText(ModWorld.misc[1], 80, 65, 130);
            else if (Main.netMode == 2)
                NetMessage.SendData(25, -1, -1, ModWorld.misc[1], 255, 80f, 65f, 130f, 0);
        }
    }
    if (Main.netMode == 2)
        NetMessage.SendModData(modId, MSG_BLESS, -1, -1, -1);
    Codable.RunGlobalMethod("ModWorld", "PostBless");
}
#endregion
    }
}
What the heck is Codable? Sendmoddata? Config? Modid? These things don't exist.
 
Can someone please tell me how to start up a tmodloader server, my friend and i have been trying for a while and we've been using the tmodloaderserver file but once it says the server is started we don't know what to do from there.
 
When I try to build my mod the custom ore generate code gives me this error
c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(69,202) : error CS0103: The name 'Config' does not exist in the current context

Here is the world.cs file
Code:
using System.IO;
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.World.Generation;
using Microsoft.Xna.Framework;
using System;

namespace EpicnessMod
{
    public class EpicnessWorld : ModWorld
    {
        private const int saveVersion = 0;
        public static bool downedDarkNebula = false;
        public static int DarkNebulaDefeated;
        public const int MSG_BLESS = 1;   
        //public struct EpicnessMsgs
//{
public static string[] misc = {"Your world has been infected with Corrupt Ore!"};
//}

        public override void Initialize()
        {
            downedDarkNebula = false;
        }

        public override void SaveCustomData(BinaryWriter writer)
        {
            writer.Write(saveVersion);
            byte flags = 0;
            writer.Write(DarkNebulaDefeated);
            if (downedDarkNebula)
            {
                flags |= 1;
            }
            writer.Write(flags);
        }

        public override void LoadCustomData(BinaryReader reader)
        {
            reader.ReadInt32();
            DarkNebulaDefeated = reader.ReadInt32();
            byte flags = reader.ReadByte();
            downedDarkNebula = ((flags & 1) == 1);
        }
#region Bless() : void [STATIC]
public static void Bless()
{
    if (Main.netMode == 1) return;
    DarkNebulaDefeated++;
    int amount = 0;
    double num5;
    num5 = Main.rockLayer;
    int xloc = -100 + Main.maxTilesX - 100;
    int yloc = -(int)num5 + Main.maxTilesY - 200;
    int sum = xloc * yloc;
    amount = (int)(sum / 10000) * 10;
    if (DarkNebulaDefeated == 1)
    {
        if (DarkNebulaDefeated == 1)
        {
            for(int zz = 0; zz < amount; zz++)
            {
                int i2 = WorldGen.genRand.Next(100, Main.maxTilesX - 100);
                double num6;
                num6 = Main.rockLayer;
                int j2 = WorldGen.genRand.Next((int)num6, Main.maxTilesY - 200);
                WorldGen.OreRunner(i2, j2, (double)WorldGen.genRand.Next(WorldGen.genRand.Next(2, 4), WorldGen.genRand.Next(4, 7)), WorldGen.genRand.Next(WorldGen.genRand.Next(3, 5), WorldGen.genRand.Next(4, 8)), Config.tileDefs.ID["CorruptOre"]);
            }
             if (Main.netMode == 0)
                Main.NewText(EpicnessWorld.misc[1], 80, 65, 130);
             else if (Main.netMode == 2)
                NetMessage.SendData(25, -1, -1, EpicnessWorld.misc[1], 255, 80f, 65f, 130f, 0);
        }
    }
}
#endregion
    }
}
 
When I try to build my mod the custom ore generate code gives me this error
c:\Users\Julian Romero\Documents\My Games\Terraria\ModLoader\Mod Sources\EpicnessMod\EpicnessWorld.cs(69,202) : error CS0103: The name 'Config' does not exist in the current context

Here is the world.cs file
Code:
using System.IO;
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.World.Generation;
using Microsoft.Xna.Framework;
using System;

namespace EpicnessMod
{
    public class EpicnessWorld : ModWorld
    {
        private const int saveVersion = 0;
        public static bool downedDarkNebula = false;
        public static int DarkNebulaDefeated;
        public const int MSG_BLESS = 1;  
        //public struct EpicnessMsgs
//{
public static string[] misc = {"Your world has been infected with Corrupt Ore!"};
//}

        public override void Initialize()
        {
            downedDarkNebula = false;
        }

        public override void SaveCustomData(BinaryWriter writer)
        {
            writer.Write(saveVersion);
            byte flags = 0;
            writer.Write(DarkNebulaDefeated);
            if (downedDarkNebula)
            {
                flags |= 1;
            }
            writer.Write(flags);
        }

        public override void LoadCustomData(BinaryReader reader)
        {
            reader.ReadInt32();
            DarkNebulaDefeated = reader.ReadInt32();
            byte flags = reader.ReadByte();
            downedDarkNebula = ((flags & 1) == 1);
        }
#region Bless() : void [STATIC]
public static void Bless()
{
    if (Main.netMode == 1) return;
    DarkNebulaDefeated++;
    int amount = 0;
    double num5;
    num5 = Main.rockLayer;
    int xloc = -100 + Main.maxTilesX - 100;
    int yloc = -(int)num5 + Main.maxTilesY - 200;
    int sum = xloc * yloc;
    amount = (int)(sum / 10000) * 10;
    if (DarkNebulaDefeated == 1)
    {
        if (DarkNebulaDefeated == 1)
        {
            for(int zz = 0; zz < amount; zz++)
            {
                int i2 = WorldGen.genRand.Next(100, Main.maxTilesX - 100);
                double num6;
                num6 = Main.rockLayer;
                int j2 = WorldGen.genRand.Next((int)num6, Main.maxTilesY - 200);
                WorldGen.OreRunner(i2, j2, (double)WorldGen.genRand.Next(WorldGen.genRand.Next(2, 4), WorldGen.genRand.Next(4, 7)), WorldGen.genRand.Next(WorldGen.genRand.Next(3, 5), WorldGen.genRand.Next(4, 8)), Config.tileDefs.ID["CorruptOre"]);
            }
             if (Main.netMode == 0)
                Main.NewText(EpicnessWorld.misc[1], 80, 65, 130);
             else if (Main.netMode == 2)
                NetMessage.SendData(25, -1, -1, EpicnessWorld.misc[1], 255, 80f, 65f, 130f, 0);
        }
    }
}
#endregion
    }
}
The error tells you the line number. That parameter is the tileid, remember that we get mod tile tileid by calling mod.TileType("name"), right?
 
Back
Top Bottom