Jump to content

Lagging Custom Entity AI


Recommended Posts

Hi, I updated the Slender Man mod to 1.3.2 and in ModLoader it's AI started to "lag"


What would happen is that the Slender Man would move for half a second, pause for half a seconds, etc.

I'm thinking this has something to do with the new server/client merge, but I'm not sure.


Is there a code I need to include that sends packets of information about mob AI even for a single player mod?


The exact same code was working perfectly for 1.2.5 in both modloader and forge.


I decided to move my mod to forge to see if that would help, it didn't.


Anyone know what's going on? I'm new to forge, so I dunno what to do...


Link "making a github for it now"


here's the mod_ class if that helps


package colossali.SlenderMan.common;

import java.util.Random;
import java.util.Map;
import java.util.List;
import java.util.jar.*;
import java.util.*;
import java.util.logging.*;
import java.util.concurrent.*;
import java.awt.datatransfer.*;
import java.awt.geom.*;
import java.util.zip.*;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import net.minecraft.client.Minecraft;
import net.minecraft.src.*;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.common.Property;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import colossali.SlenderMan.client.ClientProxy;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.Init;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartedEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;

        modid = "colossali_SlenderMan",
        name = "SlenderMan",
        version = "v2.1 [1.3.2]"

        clientSideRequired = true,
        serverSideRequired = false

public class mod_slenderman 
            clientSide = "colossali.SlenderMan.client.ClientProxy",
            serverSide = "colossali.SlenderMan.common.CommonProxy"
    public static CommonProxy proxy;
    public static int ChildSoulID = 4150;
    public static int SlenderMaskID = 4151;
    public static int SlenderSuitID = 4152;
    public static int SlenderPantsID = 4153;
    public static int SlenderShoesID = 4154;
    public static int SlenderSwordID = 4155;
    public static int SlenderNoteID = 4156;
    public static int SlenderManID = 123;
    public static int SlenderNoteEntityID = 124;
public static final Item ItemChildSoul = new ItemFood(ChildSoulID, 1, 1F, false).setPotionEffect(Potion.blindness.id, 20, 1, 0.9F).setItemName("Child Soul");
    public static final Item ItemSlenderMask = (new ItemSlenderArmor(SlenderMaskID, EnumArmorMaterial.DIAMOND, ModLoader.addArmor("slender"), 0)).setItemName("Slender Mask");
    public static final Item ItemSlenderSuit = (new ItemSlenderArmor(SlenderSuitID, EnumArmorMaterial.DIAMOND, ModLoader.addArmor("slender"), 1)).setItemName("Slender Suit");
    public static final Item ItemSlenderPants = (new ItemSlenderArmor(SlenderPantsID, EnumArmorMaterial.DIAMOND, ModLoader.addArmor("slender"), 2)).setItemName("Slender Pants");
    public static final Item ItemSlenderShoes = (new ItemSlenderArmor(SlenderShoesID, EnumArmorMaterial.DIAMOND, ModLoader.addArmor("slender"), 3)).setItemName("Slender Shoes");
    public static final Item ItemSlenderSword = (new ItemSlenderSword(SlenderSwordID, EnumToolMaterialSlender.SLENDER)).setIconCoord(3, 4).setItemName("Slender Sword");
    public static final Item ItemSlenderNote = (new ItemSlenderNote(SlenderNoteID)).setItemName("Slender Note");
    public static String itemsPath = "/colossali/SlenderMan/sprites/items.png";

    public void preInit(FMLPreInitializationEvent var1)
        Configuration var2 = new Configuration(var1.getSuggestedConfigurationFile());

            Property var3 = var2.getOrCreateIntProperty("ChildSoul", "item", 4150);
            ChildSoulID = var3.getInt(4150);
            var3 = var2.getOrCreateIntProperty("SlenderMask", "item", 4151);
            SlenderMaskID = var3.getInt(4151);
            var3 = var2.getOrCreateIntProperty("SlenderSuit", "item", 4152);
            SlenderSuitID = var3.getInt(4152);
            var3 = var2.getOrCreateIntProperty("SlenderPants", "item", 4153);
            SlenderPantsID = var3.getInt(4153);
            var3 = var2.getOrCreateIntProperty("SlenderShoes", "item", 4154);
            SlenderShoesID = var3.getInt(4154);
            var3 = var2.getOrCreateIntProperty("SlenderSword", "item", 4155);
            SlenderSwordID = var3.getInt(4155);
            var3 = var2.getOrCreateIntProperty("SlenderNote", "item", 4156);
            SlenderNoteID = var3.getInt(4156);
            var3 = var2.getOrCreateIntProperty("SlenderNote", "general", 123);
            SlenderManID = var3.getInt(123);
            var3 = var2.getOrCreateIntProperty("SlenderNoteEntity", "general", 124);
            SlenderNoteEntityID = var3.getInt(124);
        catch (Exception var7)
            FMLLog.log(Level.SEVERE, var7, "Slender Man Fucked Up", new Object[0]);
            FMLLog.severe(var7.getMessage(), new Object[0]);

    public void load(FMLInitializationEvent event)


        ModLoader.addRecipe(new ItemStack(ItemSlenderSword, 1), new Object[] {"090", "090", " 8 ", '0', Block.obsidian, '9', ItemChildSoul, '8', Item.diamond});

        ModLoader.addRecipe(new ItemStack(ItemSlenderMask, 1), new Object[] {"797", "969", "797", '7', Item.leather, '9', ItemChildSoul, '6', Item.ghastTear});

        ModLoader.addRecipe(new ItemStack(ItemSlenderSuit, 1), new Object[] {"595", "555", "434", '5', Item.diamond, '9', ItemChildSoul, '4', Block.cloth, '3', Item.redstone});

        ModLoader.addRecipe(new ItemStack(ItemSlenderPants, 1), new Object[] {"454", "5 5", "9 9", '5', Item.diamond, '9', ItemChildSoul, '4', Block.cloth});

        ModLoader.addRecipe(new ItemStack(ItemSlenderShoes, 1), new Object[] {"   ", "595", "7 7", '5', Item.diamond, '9', ItemChildSoul, '7', Item.leather});
        ModLoader.registerEntityID(EntitySlenderMan.class, "Slenderman", SlenderManID, 16260, 11020932);  
        LanguageRegistry.instance().addStringLocalization("entity.SlenderMan.name", "en_US", "Slender Man");
        ModLoader.addSpawn(EntitySlenderMan.class, 1, 1, 2, EnumCreatureType.monster, BiomeGenBase.extremeHills);
        ModLoader.addSpawn(EntitySlenderMan.class, 4, 1, 2, EnumCreatureType.monster, BiomeGenBase.forest);
        ModLoader.addSpawn(EntitySlenderMan.class, 4, 1, 2, EnumCreatureType.monster, BiomeGenBase.swampland);
        ModLoader.addSpawn(EntitySlenderMan.class, 4, 1, 2, EnumCreatureType.monster, BiomeGenBase.hell);
        ModLoader.addSpawn(EntitySlenderMan.class, 2, 1, 2, EnumCreatureType.monster, BiomeGenBase.forestHills);
        ModLoader.addSpawn(EntitySlenderMan.class, 2, 1, 2, EnumCreatureType.monster, BiomeGenBase.jungle);
        ModLoader.addSpawn(EntitySlenderMan.class, 2, 1, 2, EnumCreatureType.monster, BiomeGenBase.jungleHills);
        ModLoader.addSpawn(EntitySlenderMan.class, 2, 1, 2, EnumCreatureType.monster, BiomeGenBase.taiga);
        // Register your entities here
        // Parameters are: entClass, entName, ID, mod, trackingRange, updateFrequency, sendVelocityUpdates // Just like before, just called
        // Differently
        EntityRegistry.registerModEntity(EntitySlenderNote.class, "Slender Note", 1, this, 250, 5, false);

        // This is pretty much the old ModLoader method (in fact, the ModLoader method just calls this)
        EntityRegistry.registerGlobalEntityID(EntitySlenderNote.class, "Slender Note", SlenderNoteEntityID, 0x00000, 0x000000);//last param is entity ID, must be unique

    LanguageRegistry.addName(mod_slenderman.ItemChildSoul, "Child Soul");
    LanguageRegistry.addName(mod_slenderman.ItemSlenderMask, "Slender Mask");
    LanguageRegistry.addName(mod_slenderman.ItemSlenderNote, "Slender Note");
    LanguageRegistry.addName(mod_slenderman.ItemSlenderPants, "Slender Trousers");
    LanguageRegistry.addName(mod_slenderman.ItemSlenderShoes, "Slender Shoes");
    LanguageRegistry.addName(mod_slenderman.ItemSlenderSuit, "Slender Suit");
    LanguageRegistry.addName(mod_slenderman.ItemSlenderSword, "Slender Sword");


    public void modsLoaded(FMLPostInitializationEvent var1) {}

    public void serverStarted(FMLServerStartedEvent var1) {}


Link to comment
Share on other sites

I found the problem, I had certain code in the Entity AI file that used rayTrace to see if the entity was in the field of view of the player. I wanna keep that, does anyone think I could move that method into the client tick handler or some other handler and still get it to work? If yes, then any ideas as to how?...

Link to comment
Share on other sites

I found the problem, I had certain code in the Entity AI file that used rayTrace to see if the entity was in the field of view of the player. I wanna keep that, does anyone think I could move that method into the client tick handler or some other handler and still get it to work? If yes, then any ideas as to how?...

Just reduce the number of times it is called. eg call it only if a player is with in x range, then use the ray trace to see if that player is in range and in front on entity. You can also add a tick handler for you entity to control the tick rate to 10ticks or 2 times a second. that will keep it reacting fast enough to be life like and reduce lag.

Link to comment
Share on other sites

look at ITickHandler for controlling tick rate then create something like this

public void tickStart(EnumSet<TickType> type, Object... tickData) {
// TODO Auto-generated method stub
	for(int i = 0; i < NPCList.size(); i++)
        	 EntityNPC entity = NPCList.get(i);
        	 if(entity instanceof EntityNPC)
				 if (inGameTicks % entity.getTickInterval() == 0 && entity.getTickInterval() > 0)

 inGameTicks ++;
catch(Exception e)

in your entity you need to create a method for tickedUpdate(). In your tick handler you need to create a Static List of entities and in your entity a way to add itself to that list.


This only work in your entity Class

public List players(int range)

	 return worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.boundingBox.expand(range, 4.0D, range));
public void doTrace()
if(players(10).size() > 0)
//do ray trace

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

By using this site, you agree to our Terms of Use.