simple entity esp

Hi,

SO this has something thats got me confused lol
I
decided to make a simple entity esp, very easy thing to do as you all know. Get all entities in some sort of loop, Find the ones you want and draw them above the entity using draw.SimpleTextOutlined or something. Very easy just a few lines of code lol

It works fine as I expected, the problem is that when I move, I get a slight lag every 5 seconds (singleplayer), its not much to notice but for a script with lots of things its just going to add to the previous things that cause slight lag and just make it awful.
I really want to know how to optimize it, I never had this trouble when I made my player ESP, is this lag it because it’s going through all the entities ( maps can have lots of entities) on the map using pairs??


CreateClientConVar("dark_entity", 1, false, false)

hook.Add("HUDPaint", "ESP", function()
if GetConVarNumber ("darkcide_entity") == 1 then
for k,Ent in pairs(ents.GetAll()) do
itempos = (Ent:GetPos()+Vector(0,-10,25)):ToScreen()
itemposwep = (Ent:GetPos()+Vector(0,-20,25)):ToScreen()
itemposmoney = (Ent:GetPos()+Vector(0,-10,25)):ToScreen()
if Ent:GetClass() == "money_printer" then
draw.SimpleTextOutlined ("Money Printer" , "Trebuchet18", itempos.x ,itempos.y, Color(255,255,0),0,0,1,Color(0,0,0))
else if Ent:GetClass() == "spawned_weapon" then
draw.SimpleTextOutlined ("Weapon" , "Trebuchet18", itemposwep.x ,itemposwep.y, Color(255,145,0),0,0,1,Color(0,0,0))
end
end
end
end
end)

So I thought I would solve this by using a different method shown below but it made it 10 times more laggy and unplayable…




CreateClientConVar("dark_entity", 1, false, false)

hook.Add("HUDPaint", "ESP", function()
if GetConVarNumber ("darkcide_entity") == 1 then
for i = 1, #ents.GetAll() do
local entstuff = ents.GetAll()*
itempos = (entstuff:GetPos()+Vector(0,-10,25)):ToScreen()
itemposwep = (entstuff:GetPos()+Vector(0,-20,25)):ToScreen()
itemposmoney = (entstuff:GetPos()+Vector(0,-10,25)):ToScreen()
if entstuff:GetClass() == "money_printer" then
draw.SimpleTextOutlined ("Money Printer" , "Trebuchet18", itempos.x ,itempos.y, Color(255,255,0),0,0,1,Color(0,0,0))
else if entstuff:GetClass() == "spawned_weapon" then
draw.SimpleTextOutlined ("Weapon" , "Trebuchet18", itemposwep.x ,itemposwep.y, Color(255,145,0),0,0,1,Color(0,0,0))
end
end
end
end
end)


Can anyone give me a optimized version on how to do this as I am clueless with optimization stuff I know pairs shouldn’t be used but it was much more faster (still not good though) than the other way I know to do this.

Thanks

Haven’t tested this, but it addresses a lot of things you are doing incorrectly that you may not realize.


local draw    = draw
local ents    = ents
local Color   = Color
local tobool  = tobool
local ipairs  = ipairs
local Vector  = Vector
local IsValid = IsValid
--[[------------------------------------------------------------------------]]--
local espCvar = CreateClientConVar("dark_entity", 1, false, false)

cvars.AddChangeCallback( "dark_entity", function( cvar, old, new )
    enableESP = tobool( new )
end, "updatevalue" )

local enableESP = espCvar:GetBool()

local lookup = {
    money_printer  = true,
    spawned_weapon = true,
}

local itemOffset = Vector( 0, -10, 25 )
local swepOffset = Vector( 0, -20, 25 )

local itemColor = Color( 255, 255, 0 )
local swepColor = Color( 255, 145, 0 )
--[[------------------------------------------------------------------------]]--

hook.Add( "HUDPaint", "ESP", function()
    if ( not enableESP ) then return end
    
    local pos, ent
    local entTable = ents.GetAll()
    
    for i = 1, #entTable do
        ent = entTable[ i ]
        if ( not IsValid( ent ) )           then continue end
        if ( not lookup[ ent:GetClass() ] ) then continue end

        if ( ent:GetClass() == "money_printer" ) then
        
            pos = ( ent:GetPos() + itemOffset ):ToScreen()
            draw.SimpleTextOutlined( "Money Printer", "Trebuchet18", pos.x, pos.y, itemColor, 0,0,1, color_black )
            
        elseif ( ent:GetClass() == "spawned_weapon" ) then
        
            pos = ( ent:GetPos() + swepOffset ):ToScreen()
            draw.SimpleTextOutlined( "Weapon", "Trebuchet18", pos.x, pos.y, swepColor, 0,0,1, color_black )
            
        end
    end
end )

You need to avoid doing unnecessary operations if the Entity in any given iteration doesn’t match what you’re looking for.
Instead of calculating 3 different :ToScreen() positions even if the entity isn’t what you’re looking for, only calculate the position when you have a matching Entity, and only calculate the needed position, not the other unneeded positions.

Also, “else if” is very different than “elseif”. Look up the difference and make sure to use the correct one given the situation.

Thank you for the detailed response.
Wow this code looks a lot better than mine, I see now that there are better ways of doing it… Thank you for explaining!

I took the chance to expand upon the code to make the printer text Yellow/gold, the Weapon text red, and I made a new entity lookup for money. I also made it so on the Z axis the ESP doesn’t overlap each other or come near. It seems to be working nice now.





local espCvar = CreateClientConVar("dark_entity", 1, false, false)

cvars.AddChangeCallback( "dark_entity", function( cvar, old, new )
enableESP = tobool( new )
end, "updatevalue" )

local enableESP = espCvar:GetBool()

local lookup = {
money_printer = true,
spawned_weapon = true,
spawned_money = true,

}

local itemOffset = Vector( 8, -10, 30 )
local swepOffset = Vector( 3, 0, 20 )
local moneyOffset = Vector( 3, 0, 10 )


local itemColor = Color( 255, 255, 0 )
local swepColor = Color( 255, 0, 0 )
local moneyColor = Color( 0, 255, 0 )
--[[------------------------------------------------------------------------]]--

hook.Add( "HUDPaint", "ESP", function()
if ( not enableESP ) then return end

local pos, ent
local entTable = ents.GetAll()

for i = 1, #entTable do
ent = entTable[ i ]
if ( not IsValid( ent ) ) then continue end
if ( not lookup[ ent:GetClass() ] ) then continue end

if ( ent:GetClass() == "money_printer" ) then

pos = ( ent:GetPos() + itemOffset ):ToScreen()
draw.SimpleTextOutlined( "Money Printer", "Trebuchet18", pos.x, pos.y, itemColor, 0,0,1, color_black )

elseif ( ent:GetClass() == "spawned_weapon" ) then

pos = ( ent:GetPos() + swepOffset ):ToScreen()
draw.SimpleTextOutlined( "Weapon", "Trebuchet18", pos.x, pos.y, swepColor, 0,0,1, color_black )


elseif ( ent:GetClass() == "spawned_money" ) then

pos = ( ent:GetPos() + moneyOffset ):ToScreen()
draw.SimpleTextOutlined( "Money", "Trebuchet18", pos.x, pos.y, moneyColor, 0,0,1, color_black )



end
end

end )