• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Moving towards OTC

What should we do


  • Total voters
    57
  • Poll closed .
Status
Not open for further replies.
It's a process cost not sprite, creature item mimic is only putting a item frame instead outfit to be rendered.
Creatures is by far more complex than items is and that is why you get a lot more of resources to be used when you have a lot of that in screen.
I don't know if the code is inefficient and surely it can be improved, but it's unlikely to have so much creatures to be drawn then it's not so bad.

edit:
@Flatlander I don't know too, but it should be better than loading every time, right?
Can you try caching creatures ( outfit ) texture and see if something changes? You can check if we have that creature cached, if yes then load the texture from cache instead getting a new one.

I plan on it. I also am going to look at what processes run for each creature on screen.
If for some reason, simply a creature standing still, doing nothing, takes a lot of processing power, then clearly we can optimize that.
 
FYI: When you load a thing, it's created one big texture for each animation phase including layers, x,y,z patterns, width, height.
So, if you have a 2x2 creature with 4 directions and a mask layer, a texture of size 256x256 will be created (there's a function to calculate a power of 2 texture size that fit all this info)
This was created to draw less transparent pixels to the screen as we can define a better bouding rect.

In order to be possible to draw things per sprite, reducing the change of texture (which i do not believe will make a huge change), you need to enable opengl depth test.

Take a look at:
const TexturePtr& ThingType::getTexture(int animationPhase)

Looking at this now, i would make it slightly different.
New rules to create textures.
For items: Make a texture with width, height, x,y,z patterns, layers.
For creatures, missiles and effects: Only width, height.

This will reduce the size of creature textures, reducing memory usage and the transfer time of the texture between you RAM and GPU memory, thus increasing fps. (not 100% sure of this but there's a good chance)

About lights, tibia has little changes per frame. So lights usually won't change every frame and there's no need to redraw it.
Try this: http://pastebin.com/wLmkD3qT
 
FYI: When you load a thing, it's created one big texture for each animation phase including layers, x,y,z patterns, width, height.
So, if you have a 2x2 creature with 4 directions and a mask layer, a texture of size 256x256 will be created (there's a function to calculate a power of 2 texture size that fit all this info)
This was created to draw less transparent pixels to the screen as we can define a better bouding rect.

In order to be possible to draw things per sprite, reducing the change of texture (which i do not believe will make a huge change), you need to enable opengl depth test.

Take a look at:
const TexturePtr& ThingType::getTexture(int animationPhase)

Looking at this now, i would make it slightly different.
New rules to create textures.
For items: Make a texture with width, height, x,y,z patterns, layers.
For creatures, missiles and effects: Only width, height.

This will reduce the size of creature textures, reducing memory usage and the transfer time of the texture between you RAM and GPU memory, thus increasing fps. (not 100% sure of this but there's a good chance)

About lights, tibia has little changes per frame. So lights usually won't change every frame and there's no need to redraw it.
Try this: http://pastebin.com/wLmkD3qT

I will be looking into your changes to lighting!

I've literally been working with constant tests and studying for a couple of weeks now trying to figure out what is slowing down OTClient and ways I can increase FPS.
It's nice to see someone with more knowledge than I have contributing. :)

Can you explain how creatures, missiles and effects would only need width and height? When using the DAT, and looking at how it loads creatures/effects/missiles. It looks like we would lose functionality if we removed these.
 
Spr stores 32x32 images, however there're a lot of items that uses more pixels than that.
When creating a texture from the spr data, it's not very interesting to create many 32x32 textures.
Let's say a Demon, it has width 2 and height 2 (if I recall right), if we create simply 32x32 textures we will always make 4 draw calls to draw a Demon.
It's better to create a 64x64 texture that contains the whole Demon in a certain position, walk phase and animation, so we'll make a single draw call and we can draw a few less pixels, as the Demon probably uses ~56x56 pixels instead of 64x64.
Right now, otclient creates a huge texture that contains not only the width and height, but the 'x pattern' (where it's looking), 'y pattern' (addons), 'z pattern' (mounts) and layers (color masks).
It uses too much memory and probably make it harder to make an opengl bind to this texture.
It doesnt make sense to store all this info in a single texture as it most likely will not be used 2 times in a single frame draw. It wastes memory.
For example the Demon: it has width 2, height 2, xpattern 4, animation phases 3, so in this new format we would have 12 textures of size 64x64.
-- Oh, keeping layer in this same texture would be good as just after drawing the outfit we will probably draw its layer.

Can you explain how creatures, missiles and effects would only need width and height? When using the DAT, and looking at how it loads creatures/effects/missiles. It looks like we would lose functionality if we removed these.
I guess it's clear now, that it's not removing these, it's just caching it in different textures.

As for items, there're a few of them, such as grounds, that uses x and y patterns. They're used to make the ground look continuous, for example that cobblestone one.
I think that this cobblestone ground has width=1, height=1, xpattern=4 and ypattern=4. If we do the same as monsters, we would have 16 different textures. It's not that easy to explain, but without framebuffer, resizing would lose a lot of quality. Therefore items should be saved in a single texture, except for animation phases.
 
Spr stores 32x32 images, however there're a lot of items that uses more pixels than that.
When creating a texture from the spr data, it's not very interesting to create many 32x32 textures.
Let's say a Demon, it has width 2 and height 2 (if I recall right), if we create simply 32x32 textures we will always make 4 draw calls to draw a Demon.
It's better to create a 64x64 texture that contains the whole Demon in a certain position, walk phase and animation, so we'll make a single draw call and we can draw a few less pixels, as the Demon probably uses ~56x56 pixels instead of 64x64.
Right now, otclient creates a huge texture that contains not only the width and height, but the 'x pattern' (where it's looking), 'y pattern' (addons), 'z pattern' (mounts) and layers (color masks).
It uses too much memory and probably make it harder to make an opengl bind to this texture.
It doesnt make sense to store all this info in a single texture as it most likely will not be used 2 times in a single frame draw. It wastes memory.
For example the Demon: it has width 2, height 2, xpattern 4, animation phases 3, so in this new format we would have 12 textures of size 64x64.
-- Oh, keeping layer in this same texture would be good as just after drawing the outfit we will probably draw its layer.


I guess it's clear now, that it's not removing these, it's just caching it in different textures.

As for items, there're a few of them, such as grounds, that uses x and y patterns. They're used to make the ground look continuous, for example that cobblestone one.
I think that this cobblestone ground has width=1, height=1, xpattern=4 and ypattern=4. If we do the same as monsters, we would have 16 different textures. It's not that easy to explain, but without framebuffer, resizing would lose a lot of quality. Therefore items should be saved in a single texture, except for animation phases.

Ok, I implemented your lighting, there are a few bugs with it, but I didn't have time to make a video. Basically, lighting effects from distance effects aren't removed, and then they follow your character around.

Honestly, I never ever have a problem with memory, I would rather store all the possible textures for a creature when it enters the screen, than lose FPS.

My #1 goal is to increase fps. Even if you cached every single texture that tibia has, that's still a maximum of 100 mb (I think). And most people have 1 gig or more video ram and 4 gigs or more memory.
 
Well just a small update to inform you guys that im still working on this :p
Tought id atleast be ready to upload the UI changes and the idle animation fixes, but since I didn't get as much help as I tought with the UI ive had to spent alot more time on it.
I also found out that OTC has bugs with the animation phases when a player uses utana vid or the chameleon rune, the chameleon code is working as it should but the invisibility is abit off but I corrected the ticks so it looks OK but .. it's not correct :p

Fixed a couple of bugs with the bot and updated some of the UI to match the new one.

Most of the top buttons are removed by now, left are; the MOTD button, console, cooldown and the bot button.
Been thinking about using the left side panel for this(the one you always see) to have the console (modules, looks good in the options tab tho :p) and bot button.
What do you guys think?

And BTW nice so see some acitvity in the thread :)
 
Ok, I implemented your lighting, there are a few bugs with it, but I didn't have time to make a video. Basically, lighting effects from distance effects aren't removed, and then they follow your character around.

Honestly, I never ever have a problem with memory, I would rather store all the possible textures for a creature when it enters the screen, than lose FPS.

My #1 goal is to increase fps. Even if you cached every single texture that tibia has, that's still a maximum of 100 mb (I think). And most people have 1 gig or more video ram and 4 gigs or more memory.



Flatlander I think you misunderstand Baxnie, he is saying that the textures is to big and because of that it uses to much memory and also loose FPS.
If you create textures that fits better for each type of thing, it would be better because you are going to draw LESS pixels, saving memory and increasing fps.

It uses too much memory and probably make it harder to make an opengl bind to this texture.


just trying to clarify: make an opengl bind means giving the graphic card the ability to access the given information, in this case the texture to be drawn.
 
Flatlander I think you misunderstand Baxnie, he is saying that the textures is to big and because of that it uses to much memory and also loose FPS.
If you create textures that fits better for each type of thing, it would be better because you are going to draw LESS pixels, saving memory and increasing fps.




just trying to clarify: make an opengl bind means giving the graphic card the ability to access the given information, in this case the texture to be drawn.

I have very little knowledge of opengl or graphics engines. But, I am under the impression of the following:
  1. You have to create a texture before sending it to the graphics card.
  2. Creating a texture takes time, so once you create a texture, if you expect it will be used again soon, you should save it.
  3. Almost all of the creatures you encounter in tibia will walk around, and turn different directions.
  4. Using the above 3 lines of thinking, when a creature texture is created, you should save it.
Now, maybe when a creature appears on screen, it currently creates one huge texture that includes all of the possible sprite data that might be used for a creature.
At first, to me it sound like a great thing. When a creature appears on screen, you load all the sprite data you'll need to draw that creature as it moves around.
Creating a new texture each frame, (to me) sounds like a bad idea, so it obviously needs to save the textures.

But, maybe what you are saying is the WAY it is saving the textures is bad.
Should it be creating multiple textures for each creature, instead of one huge texture?
 
I have very little knowledge of opengl or graphics engines. But, I am under the impression of the following:
  1. You have to create a texture before sending it to the graphics card.
  2. Creating a texture takes time, so once you create a texture, if you expect it will be used again soon, you should save it.
  3. Almost all of the creatures you encounter in tibia will walk around, and turn different directions.
  4. Using the above 3 lines of thinking, when a creature texture is created, you should save it.
Now, maybe when a creature appears on screen, it currently creates one huge texture that includes all of the possible sprite data that might be used for a creature.
At first, to me it sound like a great thing. When a creature appears on screen, you load all the sprite data you'll need to draw that creature as it moves around.
Creating a new texture each frame, (to me) sounds like a bad idea, so it obviously needs to save the textures.

But, maybe what you are saying is the WAY it is saving the textures is bad.
Should it be creating multiple textures for each creature, instead of one huge texture?
I think him is saying that having a small texture instead of a huge one the time for transfer data to GPU is less, which will improve the FPS.
In theory this is right, less data less time. With a lot of creatures, this can do a good difference.
 
I have very little knowledge of opengl or graphics engines. But, I am under the impression of the following:
  1. You have to create a texture before sending it to the graphics card.
  2. Creating a texture takes time, so once you create a texture, if you expect it will be used again soon, you should save it.
  3. Almost all of the creatures you encounter in tibia will walk around, and turn different directions.
  4. Using the above 3 lines of thinking, when a creature texture is created, you should save it.
Now, maybe when a creature appears on screen, it currently creates one huge texture that includes all of the possible sprite data that might be used for a creature.
At first, to me it sound like a great thing. When a creature appears on screen, you load all the sprite data you'll need to draw that creature as it moves around.
Creating a new texture each frame, (to me) sounds like a bad idea, so it obviously needs to save the textures.

But, maybe what you are saying is the WAY it is saving the textures is bad.
Should it be creating multiple textures for each creature, instead of one huge texture?

Should it be creating multiple textures for each creature, instead of one huge texture?
EXACTLY

It has to load HUGE textures every draw, so if you split the textures as Baxnie explained, you then just need to select which texture you are going to use.

You're still going to cache them but they are going to be small textures and will be selected using CPU power instead of putting everything for the GPU.
 
Should it be creating multiple textures for each creature, instead of one huge texture?
EXACTLY

It has to load HUGE textures every draw, so if you split the textures as Baxnie explained, you then just need to select which texture you are going to use.

You're still going to cache them but they are going to be small textures and will be selected using CPU power instead of putting everything for the GPU.

Sounds like a plan.
I'll see if I can do this. (Also will probably see if it is needed to be done with animated items and effects too)
 
Task iteration:

1.- Condense textures into GPU
2.- Clear blank statements in aray
3.- Transpose mapped coordenates

????

Profit
 
Last edited by a moderator:
Ok, I implemented your lighting, there are a few bugs with it, but I didn't have time to make a video. Basically, lighting effects from distance effects aren't removed, and then they follow your character around.
Steps to reproduce it. And recheck if you properly added all lines from diff file.
 
Today started looking into OTC, first though I'm going to make some kind of guide for myself where is what going trough the data, but as I was reading the code I had some idea what it was doing, but no clue how it was doing it.
So making guide which functions I can use or not, was not helpful at all xD
Next idea was, going to start my server with OTC and start fixing whatever seems to be problem and try to learn OTC from inside out, like I did with LUA scripts on TFS.

Ok first problem was, when you look NPC, the function I created with LUA on server datapack should give me modal window, but with OTC it won't come up instead it just gives the normal "look information"
So I guessed I have to find events or look.
After a while searching, I found these: Not sure are these what I was looking for, but they were only things what remotely looked like they may cause the problem.
Code:
void Game::look(const ThingPtr& thing)
{
    if(!canPerformGameAction() || !thing)
        return;

    if(thing->isCreature() && m_protocolVersion >= 961)
        m_protocolGame->sendLookCreature(thing->getId());
    else
        m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackPos());
}
Code:
ThingPtr Tile::getTopLookThing()
{
    if(isEmpty())
        return nullptr;

    for(uint i = 0; i < m_things.size(); ++i) {
        ThingPtr thing = m_things[i];
        if(!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()))
            return thing;
    }

    return m_things[0];
}
Code:
const CreatureTypePtr& CreatureManager::getCreatureByLook(int look)
{
    auto findFun = [=] (const CreatureTypePtr& c) -> bool
    {
        const Outfit& o = c->getOutfit();
        return o.getId() == look || o.getAuxId() == look;
    };
    auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun);
    if(it != m_creatures.end())
        return *it;
    g_logger.warning(stdext::format("could not find creature with looktype: %d", look));
    return m_nullCreature;
}
There is 1 common problem with all these 3 functions above. They are c++
Which means If do a change then I have to compile it?
That's absurd, no wonder new people are not using OTClient.
I can't even compile it and even if I could. Considering that I reload scripts in TFS constantly, would pretty much mean 90% day is spent on waiting for compiler..

Is there no other way to test the changes I am going to try?
How do I even print things for any console to see what kind of values I get?
Or this is something like: It will work or it will crash. +You will not know why it works or why it crashes unless you have actually learned the language itself.

I can see that these modules somehow connect to the source on starup, so maybe its possible to somehow override the look functions in source with modules?
Or the only thing I can do is c++ and compiling to start fixing problems?
 
Today started looking into OTC, first though I'm going to make some kind of guide for myself where is what going trough the data, but as I was reading the code I had some idea what it was doing, but no clue how it was doing it.
So making guide which functions I can use or not, was not helpful at all xD
Next idea was, going to start my server with OTC and start fixing whatever seems to be problem and try to learn OTC from inside out, like I did with LUA scripts on TFS.

Ok first problem was, when you look NPC, the function I created with LUA on server datapack should give me modal window, but with OTC it won't come up instead it just gives the normal "look information"
So I guessed I have to find events or look.
After a while searching, I found these: Not sure are these what I was looking for, but they were only things what remotely looked like they may cause the problem.
Code:
void Game::look(const ThingPtr& thing)
{
    if(!canPerformGameAction() || !thing)
        return;

    if(thing->isCreature() && m_protocolVersion >= 961)
        m_protocolGame->sendLookCreature(thing->getId());
    else
        m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackPos());
}
Code:
ThingPtr Tile::getTopLookThing()
{
    if(isEmpty())
        return nullptr;

    for(uint i = 0; i < m_things.size(); ++i) {
        ThingPtr thing = m_things[i];
        if(!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()))
            return thing;
    }

    return m_things[0];
}
Code:
const CreatureTypePtr& CreatureManager::getCreatureByLook(int look)
{
    auto findFun = [=] (const CreatureTypePtr& c) -> bool
    {
        const Outfit& o = c->getOutfit();
        return o.getId() == look || o.getAuxId() == look;
    };
    auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun);
    if(it != m_creatures.end())
        return *it;
    g_logger.warning(stdext::format("could not find creature with looktype: %d", look));
    return m_nullCreature;
}
There is 1 common problem with all these 3 functions above. They are c++
Which means If do a change then I have to compile it?
That's absurd, no wonder new people are not using OTClient.
I can't even compile it and even if I could. Considering that I reload scripts in TFS constantly, would pretty much mean 90% day is spent on waiting for compiler..

Is there no other way to test the changes I am going to try?
How do I even print things for any console to see what kind of values I get?
Or this is something like: It will work or it will crash. +You will not know why it works or why it crashes unless you have actually learned the language itself.

I can see that these modules somehow connect to the source on starup, so maybe its possible to somehow override the look functions in source with modules?
Or the only thing I can do is c++ and compiling to start fixing problems?

Just like in TFS, a lot of functions are BOTH in the source (c++) and in LUA.

If you have a function that you'd like to be able to edit in LUA, and currently can't. Then add it, or request that it be added.

For example, currently you cannot edit the health bars above characters in LUA. But I could easily make a new folder called "game_hud" or something and make it for managing the in-game hud.

Though, personally, I would prefer the entire OTClient have NO LUA what so ever. Because if you release your client and people can just easily edit the LUA files.
For example, I could easily turn off lighting effects in LUA with the current version of OTClient.
 

Ive had alot to do, so haven't had time to work on the client :p

Today started looking into OTC, first though I'm going to make some kind of guide for myself where is what going trough the data, but as I was reading the code I had some idea what it was doing, but no clue how it was doing it.
So making guide which functions I can use or not, was not helpful at all xD
Next idea was, going to start my server with OTC and start fixing whatever seems to be problem and try to learn OTC from inside out, like I did with LUA scripts on TFS.

Ok first problem was, when you look NPC, the function I created with LUA on server datapack should give me modal window, but with OTC it won't come up instead it just gives the normal "look information"
So I guessed I have to find events or look.
After a while searching, I found these: Not sure are these what I was looking for, but they were only things what remotely looked like they may cause the problem.
Code:
void Game::look(const ThingPtr& thing)
{
    if(!canPerformGameAction() || !thing)
        return;

    if(thing->isCreature() && m_protocolVersion >= 961)
        m_protocolGame->sendLookCreature(thing->getId());
    else
        m_protocolGame->sendLook(thing->getPosition(), thing->getId(), thing->getStackPos());
}
Code:
ThingPtr Tile::getTopLookThing()
{
    if(isEmpty())
        return nullptr;

    for(uint i = 0; i < m_things.size(); ++i) {
        ThingPtr thing = m_things[i];
        if(!thing->isIgnoreLook() && (!thing->isGround() && !thing->isGroundBorder() && !thing->isOnBottom() && !thing->isOnTop()))
            return thing;
    }

    return m_things[0];
}
Code:
const CreatureTypePtr& CreatureManager::getCreatureByLook(int look)
{
    auto findFun = [=] (const CreatureTypePtr& c) -> bool
    {
        const Outfit& o = c->getOutfit();
        return o.getId() == look || o.getAuxId() == look;
    };
    auto it = std::find_if(m_creatures.begin(), m_creatures.end(), findFun);
    if(it != m_creatures.end())
        return *it;
    g_logger.warning(stdext::format("could not find creature with looktype: %d", look));
    return m_nullCreature;
}
There is 1 common problem with all these 3 functions above. They are c++
Which means If do a change then I have to compile it?
That's absurd, no wonder new people are not using OTClient.
I can't even compile it and even if I could. Considering that I reload scripts in TFS constantly, would pretty much mean 90% day is spent on waiting for compiler..

Is there no other way to test the changes I am going to try?
How do I even print things for any console to see what kind of values I get?
Or this is something like: It will work or it will crash. +You will not know why it works or why it crashes unless you have actually learned the language itself.

I can see that these modules somehow connect to the source on starup, so maybe its possible to somehow override the look functions in source with modules?
Or the only thing I can do is c++ and compiling to start fixing problems?

You can reload scripts, check in the top menu for a folder click it and then select the module, then reload or click reload all.
Certain things really need to be updated and maybe moved to C++ or Lua depending on what it is.
You might be able to use the VS function change and run or w/e it's called.
It's not like Java where you can change the code while the program is running but might speed it up abit :p

And to be honest (no offence to new ppl) but they don't wanna learn and that is why the community is dying out.
They might reach to learn how to change the stages and config but thats it, the rest they ask about on the support / request boards.
So unless we get ppl who wanna learn / knows how to code C++ TFS will die out when the older members start to leave.
Just think about if Mark were to leave, TFS would die out pretty quickly.

Just like in TFS, a lot of functions are BOTH in the source (c++) and in LUA.

If you have a function that you'd like to be able to edit in LUA, and currently can't. Then add it, or request that it be added.

For example, currently you cannot edit the health bars above characters in LUA. But I could easily make a new folder called "game_hud" or something and make it for managing the in-game hud.

Though, personally, I would prefer the entire OTClient have NO LUA what so ever. Because if you release your client and people can just easily edit the LUA files.
For example, I could easily turn off lighting effects in LUA with the current version of OTClient.

I think it would be a good ide to use Lua as much as we can, just look at TFS there are more ppl can who can and does change Lua codes compare to C++.
But it would be good to have certain things in the source code, to make it harder to change the client (as you said) to use bot or w/e.
So things like (as you said) the health bars, should be moved to Lua since it's a thing ppl might wanna change and there is no real reason to have it in C++.
 
Ive had alot to do, so haven't had time to work on the client :p



You can reload scripts, check in the top menu for a folder click it and then select the module, then reload or click reload all.
Certain things really need to be updated and maybe moved to C++ or Lua depending on what it is.
You might be able to use the VS function change and run or w/e it's called.
It's not like Java where you can change the code while the program is running but might speed it up abit :p

And to be honest (no offence to new ppl) but they don't wanna learn and that is why the community is dying out.
They might reach to learn how to change the stages and config but thats it, the rest they ask about on the support / request boards.
So unless we get ppl who wanna learn / knows how to code C++ TFS will die out when the older members start to leave.
Just think about if Mark were to leave, TFS would die out pretty quickly.



I think it would be a good ide to use Lua as much as we can, just look at TFS there are more ppl can who can and does change Lua codes compare to C++.
But it would be good to have certain things in the source code, to make it harder to change the client (as you said) to use bot or w/e.
So things like (as you said) the health bars, should be moved to Lua since it's a thing ppl might wanna change and there is no real reason to have it in C++.

TFS and OTClient aren't similar.
TFS is fine to have everything possible in LUA and easy for people to edit, because everyone that plays your server does not get a copy of TFS.

But everyone who plays your server does get a copy of your Client. So having all your coding and work open to the public is a problem.
And allowing everyone who has base knowledge of LUA to edit their own client can also be a problem.

Like you said, LUA is really easy to edit. So turning off the lighting system isn't hard, and I am sure over time people will find other changes they can make to the client to give them an unfair advantage.
 
TFS and OTClient aren't similar.
TFS is fine to have everything possible in LUA and easy for people to edit, because everyone that plays your server does not get a copy of TFS.

But everyone who plays your server does get a copy of your Client. So having all your coding and work open to the public is a problem.
And allowing everyone who has base knowledge of LUA to edit their own client can also be a problem.

Like you said, LUA is really easy to edit. So turning off the lighting system isn't hard, and I am sure over time people will find other changes they can make to the client to give them an unfair advantage.

Well I get your point, but I also think it should be easy to change things.
Otherwise we will end up with 2-3 devs working on the C++ code and nothing else, maybe some bug reports.

It could be a good ide to have 2 forks, one that is pure C++ and another that uses both C++ and Lua.
Some things could be moved from Lua to C++ to make it harder, ex remove all the health and mana things or the useItem functions, thus making health and mana bots imposible without source edits.
But this would also make it harder to customize your client.

There must be a good way to compress the Lua files into one big exe file or something like that.
Pretty much having files that only you, the person who compiled the client can change.

And things like the lightning system should be optional, I hate playing with light effects I always set it to max haha
 
If someone is going to put a lot of custom changes to their client, they will simply use encryption to it.
 
Status
Not open for further replies.
Back
Top