• 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!

OTClient Graphics Discussion (Anyone out there more knowledgeable than me?)

Yep that's what I'm wondering too, but I guess that we can only see when you try it?


Can you reverse the order?(but leave lighting and text to work as they work right now)
And row by row should start from last tile and work backwards (because of 64x64 sprites can cover tiles what are positions [-1,-1])

What about these questions?

If we can check at the pixel level we would create perfect results.

Another idea is straight out ignore objects what are behind bigger objects, but problem is that lot of mappers use combination of different items to create the scenario.

1 more idea what you could already produce would be to:
Ignore an object what has same type or id (in case of monster we use type, we only take the top creature of same type)(walking from tile to tile from same position by same monster type might start looking glitchy though)
in case of items we take the top item of same id. (although we need to consider stack amount on some items too then, some sprite change on different counts..)
in case of effecst we use a limit of enums on same position, lets say 10.
Reason you had huge fps drop was you created like hundreds of animations. and each position had like ~50 effects moving on it.

You have great ideas. These are the things I started attempting (with little success) when I first started trying to optimize the client myself.

Here is the core issue:
  • The game window in tibia is by default 512x352 pixels.
  • That means the Resolution of the game window is 512x352.
  • The FPS Counter in the OTClient, only tracks the FPS in this game window. (It has a separate FPS counter for the UI)

Can you IMAGINE running a game with a 512x352 resolution and getting FPS Drops, then thinking "Hmm maybe it is because there are too many creatures on the screen?"
Hell no.

If you ran a game at 800x600 and did not have 60 FPS, it better be a next-gen god-tier game.

So we have an issue, where the OTClient is drawing a game window with a resolution of 512x352, and some computers have issues running this game smoothly.
This is the equivalent, of giving an adult a paperclip, and they have trouble picking it up because it is too heavy.

There is either something wrong with the adult, or the paperclip. It is either the computer, or the client.
It is as if we have super-glued the paperclip to the floor. Then we tell an adult "hey pick up that paperclip." and watch them struggle with a task that should be VERY simple.

We need to find the glue, what is making this incredibly easy task so difficult for computers?
The OTClient is doing something clearly wrong. It has the illusion of working correctly because it LOOKS right, but somewhere in the code it is doing something insanely stupid. We need to find out what that is, and fix it.
 
in otc is it possible to write something like this?:
if frames < 10 then
print("functionName: "..socket.getTime())
end
(otc is written in C++ right? there was a way to get function name with some method imo.)
anyway put these statements on every function what deal with rendering.
on last function add 1 to frames and make empty print.

If you can do this, we could compare the results in which cases it took the most time to hop from 1 function to another and see start by looking at the functions what take the most time.
 
what fps do you get otclient at? i think theres something wrong with mines since on the login screen i get 6k fps then i log in the game i get 300 fps when i move i get 200fps.
 
look =
20h50t3.jpg

RAM CONSUMED = before login / after login .
OTCLIENT = 31,7 / 181,1
TIBIA = 31,1 / 35,9

of course have a problem
 
You have great ideas. These are the things I started attempting (with little success) when I first started trying to optimize the client myself.

Here is the core issue:
  • The game window in tibia is by default 512x352 pixels.
  • That means the Resolution of the game window is 512x352.
  • The FPS Counter in the OTClient, only tracks the FPS in this game window. (It has a separate FPS counter for the UI)

Can you IMAGINE running a game with a 512x352 resolution and getting FPS Drops, then thinking "Hmm maybe it is because there are too many creatures on the screen?"
Hell no.

If you ran a game at 800x600 and did not have 60 FPS, it better be a next-gen god-tier game.

So we have an issue, where the OTClient is drawing a game window with a resolution of 512x352, and some computers have issues running this game smoothly.
This is the equivalent, of giving an adult a paperclip, and they have trouble picking it up because it is too heavy.

There is either something wrong with the adult, or the paperclip. It is either the computer, or the client.
It is as if we have super-glued the paperclip to the floor. Then we tell an adult "hey pick up that paperclip." and watch them struggle with a task that should be VERY simple.

We need to find the glue, what is making this incredibly easy task so difficult for computers?
The OTClient is doing something clearly wrong. It has the illusion of working correctly because it LOOKS right, but somewhere in the code it is doing something insanely stupid. We need to find out what that is, and fix it.

So we need to profile things...
 
look =
20h50t3.jpg

RAM CONSUMED = before login / after login .
OTCLIENT = 31,7 / 181,1
TIBIA = 31,1 / 35,9

of course have a problem
makes you wonder does it load all the sprites into memory.

EDIT: When it creates/saves picture (png?) does it do the huge for loop evrey time for each object or it knows that it has already drawn that image before in this cycle? (we do have lot of repeating tiles/items in 1 screen)
 
Last edited:
how do they compress sprites that much?
- I guess they use bytes directly from .spr to draw, compression to PNG is a waste of efficiency.
- My next guess is if object is not on the screen/in inventory it's removed quickly from memory.

Animations can be done same way, just with layers I believe.

Regarding current otclient rendering:
Player sprite:
64x64
7 frames
4 facing directions
outfit + addon1 + addon2
=
448x768
=
344064 pixels
 
Last edited:
My computer is now fully set up again so I can compile the OTClient.

I wasn't able to do much last weekend because of having to re-format my computer and re-install everything. (Plus I had a task I had to complete on my own server)
I plan to keep working on optimizing the OTClient along-side making my server.

I was on Discord in the OTLand channel and was told that openGL could be part of the reason the FPS is so low.
Maybe re-doing everything to work with DirectX9 (instead of ghetto rigging it to work with DX9) would be a good goal?
 
@Flatlander can you join the otland discord? https://discord.gg/014c72lqphZCNHVuJ

Another thing, can you test a really small optimization?

here after this line: https://github.com/edubart/otclient/blob/master/src/client/thingtype.cpp#L492

add this:

Code:
m_textures[animationPhase] = animationPhaseTexture;

Now on TexturePtr& ThingType::getTexture function it will get the already loaded texture instead of loading it from the spr, creating a big image and loading it into the gpu.

@edit

Creature::internalDrawOutfit is not well optimized in my opinion. It should create a complete texture and then reuse it with the outfit colors etc, if the creature got a outfit change then rebuild the texture.

This increased my FPS slightly.
Not enough to really matter, but I did get on average 5-20 fps boost (when I set it to max)
 
This increased my FPS slightly.
Not enough to really matter, but I did get on average 5-20 fps boost (when I set it to max)
This optimization is not a optimization. It was based on my lack of understand of C++ :(
OTClient does store/cache the textures. Having small textures like you said is really bad, it will multiply the use of memory(by using even more textures) and it will make OTC do even more texture binds which is bad(we need to reduce opengl calls).

Anyway, my current idea is:
Draw all the items(ground, walls, equips, etc) inside a Tile to a FrameBuffer and hold it as a cache(each Tile will have a FrameBuffer). If there is a update of the items(item removed, added, etc) it would clear the FrameBuffer and draw all the items again. The idea is simple: Draw one time to the tile FrameBuffer and keep it as a cache and just draw the tile FrameBuffer to the MapView framebuffer. It will reduce opengl calls(texture binds) a lot. Effects, outfits, animated texts, names and lights would be draw like they are now(each frame). Another idea is to use a big FrameBuffer to hold all the Tiles Drawing cache and reduce even more the opengl calls/binds.
 
Last edited:
This optimization is not a optimization. It was based on my lack of understand of C++ :(
OTClient does store/cache the textures. Having small textures like you said is really bad, it will multiply the use of memory(by using even more textures) and it will make OTC do even more texture binds which is bad(we need to reduce opengl calls).

Anyway, my current idea is:
Draw all the items(ground, walls, equips, etc) inside a Tile to a FrameBuffer and hold it as a cache(each Tile will have a FrameBuffer). If there is a update of the items(item removed, added, etc) it would clear the FrameBuffer and draw all the items again. The idea is simple: Draw one time to the tile FrameBuffer and keep it as a cache and just draw the tile FrameBuffer to the MapView framebuffer. It will reduce opengl calls(texture binds) a lot. Effects, outfits, animated texts, names and lights would be draw like they are now(each frame). Another idea is to use a big FrameBuffer to hold all the Tiles Drawing cache and reduce even more the opengl calls/binds.

It already does this for the UI, so you can use this to kind of copy-paste similar code for the ground. (I would just test to see if you can get it working with ground-tiles first)
 
I noticed when adding or removing a bunch of creatures at the same time to the screen. The OTClient would lag a huge deal.

After doing some tests, I found this is caused by the BattleList. After disabling the BattleList, I no long have stuttering or freezes when walking around with monsters on my screen.
The FPS is still low-ish with a bunch of monsters, but it is MUCH more managable.

I will have to look through the entire battlelist.lua and find out what needs to be changed to make it work smoothly.
 
After doing some tests, I found this is caused by the BattleList. After disabling the BattleList, I no long have stuttering or freezes when walking around with monsters on my screen.
The FPS is still low-ish with a bunch of monsters, but it is MUCH more managable.
Dude! This must be disabed. That is making tibia client horrible. We need onMove script instead of that useless feature what helps to bot.
 
Dude! This must be disabed. That is making tibia client horrible. We need onMove script instead of that useless feature what helps to bot.

If you completely disable the battle list you lose the Red/Green boxes for follow and attack. You also lose the ability to easily manage monsters on screen.

I currently use the battlelist.lua for Hold Target and auto-targeting (similar to the flash client, where you just press Spacebar to target the closest monster, makes playing tibia for long periods of time much easier since you don't have to click on every damn monster)
 
Dude! This must be disabed. That is making tibia client horrible. We need onMove script instead of that useless feature what helps to bot.
If you get the chance, I think you should try it. Small issue on some servers is anti-dash that slows you down when "using floor tiles" when you miss moving target. But you can still use ctrl+mouse or disable classic control(?) to choose an option like "attack", "use", "look" before actually doing it.

Sure, it's a little harder than using battle window. But not too hard to get used to. I started using it for "Copy name" to heal players and after awhile goes pretty much automatic. You won't be able to attack someone in the dark or under a roof though... Big deal, right? :)

side note
: Since early clients were played on those big bowl monitor boxes with less colours and pixels in lower resolution; players were often only able to open a single or a few windows at a time. To open battle screen they had to close map or equipment first. To open a backpack runes (pots, fluids) they had to close battle window (which would even stop the attack afaik). Sounds like fun, no? xD

Players today still do similar stuff to get more available fps. Downgrading their graphic options in full screen mode. Using 16b instead of 32b, picking a lower resolution, even using older directx version sometimes. It helps a great deal to aim when you have less pixels on screen, and a lower total amount improves a smoother online gameplay overall. Even at the cost of having less windows open. It's easier to maintain decent fps and in the end promotes a better client-server communication, I suppose. It's not uncommon for players on outdated systems to outplay someone with latest hardware when they know exactly how to gain control over it. In OTClient there are no such options, sadly.

And if you think about where Tibia is most popular. It's in places where average computers are more outdated. These kids still choose to play Tibia because their computer can't handle more popular games like LoL. You'd be surprised how many Tibia players still run Windows XP. lol
So you're definetly right that it's important to improve this part of the client. It directly effects possible popularity of your game.
makes playing tibia for long periods of time much easier since you don't have to click on every damn monster
Honestly, fighting a lot of monsters never is fun. Not to mention looting/selling every single one of them. Bigger creatures that take more time to lure and kill with some danger involved and tactic required always is. And can be done without waste at any level after putting in some thought and preparation. Even though it won't give you the best exp/gold rate an hour and will result in more deaths. But that's not really what a game like Tibia should be about.

Nice research, guys. Good luck with this.
Perhaps you can try to involve some spriters and graphic artists to tell you what looks bad compared to real client. They might have a better eye to notice any wrong techniques used that are fucking things up terribly. xD
 
Btw is this client drawing the screen or TFS does it?
Maybe its much better if the tile pixel information is created on TFS and client only handles the drawing.
This way client only loops trough 17x11x32 pixels every interval. (~6000 map pixels) and gives each pixel its color. can be done with byte code I guess. TFS could create the byte code table
As its 2D its shouldn't be demanding to make it draw 60 frames per sec, that would only mean ~17 screen requests per sec from TFS.

Also if we are going to save sprite or tile information for some amount of time. We would rly want to do it on server, we wouldn't even care if 2gb ram is lost. Its just few euros for hosters xD
And cmon it wont be more than client takes ram right now. (150mb)

but saving the tile draw information for each position we allow us to make byte check if anything has changed since last call and if not, use old info.

Look how many unmoving objects we have

EDIT: We rly want to figure out how to multithread on TFS though. draw request should not pause monster AI or stop some game mechanic
 
Last edited:
Sure, it's a little harder than using battle window. But not too hard to get used to. I started using it for "Copy name" to heal players and after awhile goes pretty much automatic. You won't be able to attack someone in the dark or under a roof though... Big deal, right? :)

Not being able to select a target in the dark should be intended behavior, as you can't see it.

Not being able to select a target under a roof is a problem of prospective, and is a ''bug''.

The combat window has always seemed a bit like cheating to me, as you should just rely on what you see in the game window, and interact with the game window to get targets .




Honestly, fighting a lot of monsters never is fun. Not to mention looting/selling every single one of them. Bigger creatures that take more time to lure and kill with some danger involved and tactic required always is. And can be done without waste at any level after putting in some thought and preparation. Even though it won't give you the best exp/gold rate an hour and will result in more deaths. But that's not really what a game like Tibia should be about.

What Flatlander meant is that he is adding additional controls for being able to select a target with the keyboard, and not having to rely 100% on a mouse for target selection.

It's sometimes simpler to toggle through your available targets by pressing space bar then moving your mouse over to click them.

It wasn't really commentary about how it is annoying to fight monsters en masse. (though, I do agree with you, that outside of special events, having to kill tons of monsters is bad game design)

You still would have to use crosshairs on the game window to shoot anything with the crosshairs.
 
look =
20h50t3.jpg

RAM CONSUMED = before login / after login .
OTCLIENT = 31,7 / 181,1
TIBIA = 31,1 / 35,9

of course have a problem
RAM/CPU useage is NOT BAD.
If your program does not have something like 'limit fps', it should use 100% of resources to increase it's speed [FPS].
Maybe RAM useage is problem for players that like to run 50 MCs, but for normal player 200 or 500 MB should not be a problem in 2016.
I don't know how it's now, but in times of Tibia 8.6 real tibia client had problem with FPS drops. When you visited new area, it could lag like hell [freez for 0.2-0.5 sec.. every step you see some new textures (house items).. wtf], because it had to load new textures from HDD and most of players had HDD, not SSD.
I think that loading all textures at start is a good idea. I'm just not sure, if OTClient loads all textures at start or it caches Tibia.spr file in RAM [I saw some code to cache that file in OTC].
 
Btw is this client drawing the screen or TFS does it?
Maybe its much better if the tile pixel information is created on TFS and client only handles the drawing.
This way client only loops trough 17x11x32 pixels every interval. (~6000 map pixels) and gives each pixel its color. can be done with byte code I guess. TFS could create the byte code table
As its 2D its shouldn't be demanding to make it draw 60 frames per sec, that would only mean ~17 screen requests per sec from TFS.

Also if we are going to save sprite or tile information for some amount of time. We would rly want to do it on server, we wouldn't even care if 2gb ram is lost. Its just few euros for hosters xD
And cmon it wont be more than client takes ram right now. (150mb)

but saving the tile draw information for each position we allow us to make byte check if anything has changed since last call and if not, use old info.

Look how many unmoving objects we have

EDIT: We rly want to figure out how to multithread on TFS though. draw request should not pause monster AI or stop some game mechanic

The issue with your idea isn't the extra ram usage of TFS, it would be the extra network usage of literally streaming all the textures to the client. (we should keep network usage as low as possible, so you can have as many players as possible)

Also, I agree with your multithread issue. Drawing would be much faster, and the client would be much smoother if it was multithreaded.
The client just needs to be fixed. If CIP's tibia client can do it, so can the OTClient.
 
Back
Top