SecTree Memory adjustment

the sectree in metin2 is scary and not even the old korean wizards know what the fuck is happening over there so I took a deep breath and started to change some stuff around. While doing so I found something strange, after around 2.5-5k mobs the ram is exploding and its getting extremely laggy. I noticed that every server-source/game/src/entiy.h -> CEntity has its own

ENTITY_MAP m_map_view;

But what is a ENTITY_MAP? In short, it’s a container of every currently-visible entity. This is useful to see things but has a small issue: every entity sees every entity in proximity. In other words: the amount of currently tracked entities is growing exponentially.

1 mob -> 0 entries
2 mobs -> 1 entry per mob / 2 entries
3 mobs -> 2 entries per mob / 6 entries
4 mobs -> 3 entries per mob / 12 entries
2500 mobs -> 2499 entries per mob / 6247500 entries 

This is not good, but we have to see things, we can’t just remove it completely. Introducing, my pseudo fix:

search for CFuncViewInsert in server-source/game/src/entity_view.cpp my change would be to avoid calling m_me->ViewInsert(ent); every time, so it would look something like that

class CFuncViewInsert
{
    private:
        int dwViewRange;

    public:
        LPENTITY m_me;

        CFuncViewInsert(LPENTITY ent) :
            dwViewRange(VIEW_RANGE + VIEW_BONUS_RANGE),
            m_me(ent)
        {
        }

        void operator () (LPENTITY ent)
        {
            if (!ent->IsType(ENTITY_OBJECT))
                if (DISTANCE_APPROX(ent->GetX() - m_me->GetX(), ent->GetY() - m_me->GetY()) > dwViewRange)
                    return;


            if (m_me->IsType(ENTITY_CHARACTER)) {
                LPCHARACTER ch_me = (LPCHARACTER)m_me;
                if (ch_me->IsPC()) {
                    m_me->ViewInsert(ent);  //the players see everything..
                } else if (ch_me->IsNPC() && ent->IsType(ENTITY_CHARACTER)) {
                    LPCHARACTER ch_ent = (LPCHARACTER)ent;
                    if (ch_ent->IsPC()) {
                        m_me->ViewInsert(ent); //the npcs see the players...
                    }
                    else if (ch_ent->IsNPC()) {
                        /* JOTUN/OCHAO/HYDRA CONTENT, WE DONT NEED THIS RIGHT NOW BUT REMEMBER REMEMBER THE 6th OF NOVEMBER
                        if (IS_SET(ch_me->GetAIFlag(), AIFLAG_HEALER)) {
                            m_me->ViewInsert(ent); //the npc-healers see other npcs (ochao fix)
                        } else {
                            switch (ch_ent->GetRaceNum()) {
                                case 20434: {
                                    m_me->ViewInsert(ent); //the npcs can be seen by other npcs (hydra sail fix)
                                } break;
                            }
                        }
                        */
                    }
                }
            } else {
                m_me->ViewInsert(ent);
            }


            if (ent->IsType(ENTITY_CHARACTER) && m_me->IsType(ENTITY_CHARACTER))
            {
                LPCHARACTER chMe = (LPCHARACTER) m_me;
                LPCHARACTER chEnt = (LPCHARACTER) ent;

                if (chMe->IsPC() && !chEnt->IsPC() && !chEnt->IsWarp() && !chEnt->IsGoto())
                    chEnt->StartStateMachine();
            }
        }
};

We check if both entities are of the “character” type and if so we cast them to LPCHARACTERS. If the current view is of a player, he has to see everything if the current view is of a NPC, he has to see only players

This fix has some issues, with newer versions of the game there are a few mobs that heal each other - I haven’t tested those neither have I tested this change throughout, but I’m fairly certain that it will work. If there is a problem you could add a type/subtype check or even hardcode the vnums since I think that there are only a handful of NPCs that have to see other NPCs (i.e. jotun)

good luck