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

Source's custom OT game engine (TypeScriptFTW)

Implemented local activation yesterday, finished a couple of details today, recording from yesterday:

CPU usage now with full map is 1.7-2% with 1 player in middle of Draconia pyramid (40 activated monsters), idle CPU usage is 0.3-0.7% regardless of map size so you can subtract that number to get an estimate of monster activation/deactivation including randWalk cost.
Chase mode (GM: 0) seem to not add much of any cost regardless of the place and the number of monsters trying to chase you, approximately 0.3% extra with 15 monsters at a time when all monsters has a chance to reach you, so they're all actively doing pathfinding which I wrote in C++ I believe about a year ago.

Might upload this to the testserver sometime soon. Will also try to remember to remove the account 0 issue.

Server will probably get closed in a week or two so take the chance to try it out now if you're curious.

Edit: Decided to compare with TFS 1.4.2 for fun on my CPU underclocked laptop.
TFS 1.4.2 with real map used 7% with no players on, 10% with 1 player on, and 12% with 2 monsters fleeing, 6 monsters chasing, and 6 monsters randWalking (14 total).
That's a +2% CPU usage with 14 monsters activated. Compare that with my +1-1.4% CPU usage with 40 activated monsters on Draconia or +1-2% CPU usage with 7 monsters chasing and 6 monsters randWalking (13 total, same location).
Performance seem to be on par, with a slight edge to my server, and a much lower IDLE state.

I've also updated the testserver, so you can test monsters chasing/pathfinding now with the command /gm to activate/deactivate chasing.
The command also works in combination with the command /rotate and /watch.

Also before anyone might complain about a bug with some monsters sometimes double stepping, I'm working on it (there were many such bugs, now there's just 1 more left to my knowledge).
 
Last edited:
Newest features since two weeks ago:
  • Monsters and players attack (100% accurate real tibia melee formulas thanks to @jay's posts including armor, confirmed damage is the exact same on local cip engine), attack is generated onStep the same way I believe real tibia does it
  • Local randWalk (sidestepping), and
  • Flee algorithm ("stole" from/modified OTHire (open source project as you all know) flee algorithm, 2nd piece of code I've taken after XTEA, all other code is custom/written from scratch)

Other fixes/additions:
  • Monster RNG loot was accidentally removed in one update without me noticing, it's now been added back.
  • Fixed the ability to set outfit again (dwarven outfit).
  • Monsters no longer turn towards target when on a different floor.
  • Fixed "no creature found" in client when pushing casted creature (would cause crash in cip client).
  • Added "You lose x health by y z." messages when attacked, also applies to cast viewers.
  • Set fist attack and defense appropriately (fist defense was inaccurate).
  • Server can now log to multiple different logfiles with the same log function call with low performance cost (but you still have to specify log filenames before-hand because opening/closing logfiles is very expensive).
  • Attacks break shield after the second attack per attack round/two seconds.
  • Fixed summoning monsters whose name is more than one word.
  • Fixed /rotate default cast interval set to 5 seconds bug.
  • Fixed so summoned monsters immediately starts moving/activates if target is on screen.
  • Various other improvements / other boring bug fixes like monsters sometimes not getting deactivated when trying to randWalk but failing because all 4 directions are blocked.

Let me know if anyone would like to try out the Test Server again, I think I forgot to mention the !commands command which lists all commands and/or I should have explained a few of the commands a little better maybe.

Either way, have a good one!
 
Last edited:
New update!

Added some more juicy bi-weekly features:
  • Distance creatures keeps distance with 7.70 real tibia slowdown algorithm (might not be perfect, but I reverse engineered what I could by behaviors and tried to replicate the real thing).
  • Added physical attacks, blood/slime on ground with decay and creature death.
  • Added immediate follows onStep when a creature targets another and that creature is not a GM like 7.70 cip engine.
  • Tons of bug fixes.

Here's the first three attempts at distance creature behavior (the 1st shows slowed down distance creature monster mechanic, 3rd is the latest/current implementation):

And here's an orc berserker killing rats, killing GM, and killing a monk.


Here's a list of all the bug fixes and improvements this time around:
  • Slight improvement to armor (should be cast as int, not double, for the real tibia 7.70 cip mechanics).
  • getRandomStep implemented as a function in pathfinding with diagonal option/param (it was "loose spaghetti code" before repeated in 3 different functions).
  • Creatures parsing flags bugs (orc spearmen weren't recognized as a distance creature).
  • Walk function didn't actually check nextwalktime bug.
  • Creatures like dogs shouldn't attack even though they follow you around.
  • Distance creatures keeps distance and runs slower when "panicking".
  • Creatures moves instantly when their target moves if they were in range.
  • Log function now DOES allow you to use any name when logging to $name.log with no manual setup beforehand - the log function will open a filehandle if one isn't already open and keep track of the filehandles in the equivalent of a std::map, so now you can do log("test", "ksrgsrgkdgdrkgdkr") if you wish to start logging to the file logs/ksrgsrgkdgdrkgdkr.log without setting up the filehandle beforehand.
  • Creature was immediately randWalking when player (target) was moving (bug).
  • Looking at tile now shows "a pool of blood" or any other liquid instead of "%d pools".
  • Fixed multiple bugs related to items either over-expiring (enchanted staff -> staff -> nothing) or under-expiring (blood1 -> blood2 -> blood3 -> no more change/not removed), it now also clears containers when an item expires, etc.
  • Had a poor implementation of "vcreatures" (vector of creatures) that could easily (and did) result in a segfault due to an old "C-like" design, now redesigned using C++ operations.
  • Creature death implemented which, like the real tibia 7.70 engine, is called in the gameLoop by iterating over creatures with 0 health, this creates a pseudo-random effect for when monster actually dies.
  • Bugs related to dying, which deletes the creature, but still staying connected to the server (which it should).
  • Server with full real map had started to increase to 1.1GB of memory used, it's now back to <1.0GB thanks to some optimizations.
  • Bunch of re-calls (check if delay > 0, if it is re-call function slightly later) necessary for timing related functions since the scheduler is not entirely reliable anymore (possibly related to using a too new version of the language/some libraries, it's been entirely reliable until now/recently).
  • world.addPool(...) had a bug where a creature whose blood lands on the ground underneath them disappears from battle list for a second (no crash in cipclient, no error in otclient, so hard to debug what's going wrong), replaced gameSendUpdateTile to gameSendRemoveObject + gameSendAddObject for now.
  • Creatures were pseudo-randomly suddenly chasing/trying to attack (fails because onAttacked checks if creature is GM) castviewed creature with GM-mode activated.
  • Creatures were no longer counter-attacking approaching creature when it reached range even though it's targeted.
  • Creatures pseudo-randomly stopped moving after killing target (sometimes it did, sometimes it didn't).

Couple of points also worth mentioning:
1. Like the cip engine/real tibia 7.70 we prioritize the attacks of the approaching creature that reaches range first.
2. I'm aware that monsters shouldn't (visually) hit higher than the remaining HP of a creature. I've kept it this way for now though because it's more fun and shows the actual hit, so an apocalypse does not hit up to 150 damage everytime (max player health), which is no fun.

I might stream again in the upcoming days if the IRC client still works.
Here's a feature I implemented earlier in January when I implemented the IRC client:

Let me know if you have any ideas for interacting with the server through twitch or any quiz questions to add that can preferably be generated based on already available information.

Here's an example of an idea that might be interested in the future with a public server:
Using quiz points to summon monsters of your choice (with an increasing price the stronger it is) randomly across the map somewhere.
This won't be viable for a while, but might be an interesting idea.


Cheers!
 
Last edited:
i'm trying do this in my tfs 1.4.2 for poketibia, i feel so excited see this, its possible to do -. Gratz bro, im following u.
 
im not sure it that is a good idea to say what % of usage cpu is used in my pc i got mostly 0% in linux i get like 0.3-0.7% it jumps back and forth each 5-10 sec.) and 0.1% in my pc while having whole screen filled with monsters
map is around 25MB which is not that bit but still

im using optimized tfs from sayan or how was his nickname preety much first github link in google
 
im not sure it that is a good idea to say what % of usage cpu is used in my pc i got mostly 0% in linux i get like 0.3-0.7% it jumps back and forth each 5-10 sec.) and 0.1% in my pc while having whole screen filled with monsters
map is around 25MB which is not that bit but still

im using optimized tfs from sayan or how was his nickname preety much first github link in google
There's a couple of reasonable possibilities, either:
1) Real map uses way more CPU due to new 10.x scripts etc (I use the 10.77 ORTS real map with TFS 1.4.2 which I know uses global scripts running all the time, because it literally gave me errors in some of the scripts on a continuous basis until I fixed them) , or
2) CPU perf is affected by me only having 8 gigs of RAM on this laptop, even though I close memory hungry processes like MSVS and Firefox when I run TFS to try to compensate for the high memory usage.

I wonder why your creatures seems to be walking when this is non-default behavior on GMs under TFS, did you customize this yourself (why)?
A video/gif with both top window and your client side by side would've been better, but yeah.
And also I think a problem with Windows CPU usage is that it might (at least task managers does this) show CPU usage of the total number of cores (100% = all cores) while on Linux 100% = 1 core.
And I don't fully understand your results. It uses 0.7% with no one on, and 0.1% with half a screen filled with dark elves? Something's not quite making sense.. I guess it doesn't make sense to compare Windows with Linux so I'd have to see the Linux results since I run my server on Linux (WSL2) as well.
 
There's a couple of reasonable possibilities, either:
1) Real map uses way more CPU due to new 10.x scripts etc (I use the 10.77 ORTS real map with TFS 1.4.2 which I know uses global scripts running all the time, because it literally gave me errors in some of the scripts on a continuous basis until I fixed them) , or
2) CPU perf is affected by me only having 8 gigs of RAM on this laptop, even though I close memory hungry processes like MSVS and Firefox when I run TFS to try to compensate for the high memory usage.

I wonder why your creatures seems to be walking when this is non-default behavior on GMs under TFS, did you customize this yourself (why)?
A video/gif with both top window and your client side by side would've been better, but yeah.
And also I think a problem with Windows CPU usage is that it might (at least task managers does this) show CPU usage of the total number of cores (100% = all cores) while on Linux 100% = 1 core.
And I don't fully understand your results. It uses 0.7% with no one on, and 0.1% with half a screen filled with dark elves? Something's not quite making sense.. I guess it doesn't make sense to compare Windows with Linux so I'd have to see the Linux results since I run my server on Linux (WSL2) as well.
2 tests were made
1 on high end PC with 0% cpu usage and 0.1% cpu usage (well that was understandable cause cpu has 12 cores and 24 threads...)
2 on linux VPS with 4 vCPU Cores and 8GB ram and 200 GB SSD (1 vcore was around 2GHz could be less i dont remember now) and usage on vps was 0.3 to 0.7%

if you have working map already why not testing it on GitHub - opentibiabr/optimized_forgottenserver: Optimized forgotten server made by @SaiyansKing (https://github.com/opentibiabr/optimized_forgottenserver) < this

im sure it will be more performant then default tfs and if your code will run similar or even faster then that then it will be most likely better then anything released up to this point.
also for this optimized version of tfs (its based on tfs 1.3) and preety sure it will crash some scripts cause alot of things are done differently then default tfs 1.4.2 that you are using also no web Acc will work on this you will need to add players manually through DB.

PS. i think that VPS of mine is preety much the same as your machine i supose ? (it just has 4 cores and no additional threads so its 4/4)
 
@thesxw I've double checked without a pagefile enabled to make sure high CPU on TFS wasn't caused by disk buffering, anyway that's all I can do for you, you should try to run TFS 1.4.2 with OTRS yourself if you need to verify yourself.
And yes since my CPU is underclocked it's about the equivalent of a cheap VPS. Thanks for your feedback.

@everyone
Update time! Major updates:
  • Monsters now talks and yells at random times.
  • Monsters on death now respawns after some time. Added respawnRate in config.
  • Added parsing of all spells except for Outfit spells which is a weird one - there are only 4 params and Outfit requires 5 (type + 4 colors). Some basic spells (Target Missile and Self Healing) are now cast by all monsters that has these spells! Physical spells are blocked by eq/armor like they should.
  • Discovered a huge bottleneck (30-70% of CPU) when screen full of monsters and WE (player) walk around. To solve this we had to redesign the entire onPositionChange system replacing gameGetCreatures (getCreatures) with two std::map's that keeps track of attacks and follows. CPU consumption is now 2-10%, generally the same amount as TFS in every area, the only area I haven't tested is the 10% which only happens when a GM summons around with /a 1 with a screen full of chase (non-ranged) monsters. Earlier a screen full of Minotaur Archers + player movement costed up to 70% of the CPU, now it's only 2%, even though monsters still reacts instantly to target movement. This problem/experience taught me code profiling.

Spells (other missiles works as well, like all the beholder and minotaur mage missiles)

Automatic Respawning:

Other fixes/details:
  • Monsters casts spells exactly at the same time as with Cip engine/retro tibia. Monsters also only turn every 2 seconds when in melee range rather than every second.
  • Player chase mode and follow feature is now respected and the player will chase the monster when these are functions are activated. Moving away from the monster will instantly cause the player to move back to the monster if chase mode is still on (client option).
  • Worldlight is now updated immediately upon server start, not after the Tibia clock turns an hour.
  • Pressing the ESC button to cancel attack during castviewing mode now works.
  • Added adminPassword config variable (to gain God access).
  • Should be no more "trapped bears" or other monsters "trapped" on spawn. During my first twitch stream I found a bear trapped between bushes. It could move diagonally, but randWalk does not walk diagonally. This should no longer happen.

I also tried to add Cip engine "Show character list even though server is not done booting yet" and got it partially working, but it wasn't viable as we would have to remove the multithreaded map loading to get it fully working.
We would also have to move a lot of code around and do some rewrites. So I decided not to go through with it.

Next update we'll have to rewrite the items expiration system/function to account for items that could be stored in player inventory or backpack. This way we can start moving items to and from player inventory.
At least that's what I have planned, hopefully I'll stick with the schedule and figure this one out for next time.
 
I also tried to add Cip engine "Show character list even though server is not done booting yet" and got it partially working, but it wasn't viable as we would have to remove the multithreaded map loading to get it fully working.
Normally the login server that handles player authentication runs in a separate process outside of the game server. That way it is possible to show the character list even when the game server is offline. And in addition to the performance bonuses, it is better to outsource authentication to a different process and use a token based login.
 
Normally the login server that handles player authentication runs in a separate process outside of the game server. That way it is possible to show the character list even when the game server is offline. And in addition to the performance bonuses, it is better to outsource authentication to a different process and use a token based login.
Not quite. This is a matter of design, but it's assuming that the server is entirely written in C++, which it's not.
It can't currently be designed the same way TFS or a pure C++ program can, and it probably never will.
Whether it's even possible to run it in a separate process or thread is a question in itself, probably the answer is no.
But it's possible to run the server asynchronously, which it already is, and if the rest of the code was run asynchronously as well including the maploading then the login server could run side by side with the rest of the code.
As to what TFS does, just for the record, it may or may not run the login server as a separate process, but the login server is not available during boot (until everything is finished loading, just like TSS).

I don't quite understand the 'additionally' part. Seems to me like the performance boost is the only advantage. But a fair one at that.
The good news is that it doesn't really matter. You can throttle the login server in other ways, for example through firewall rules, or even keep track of IPs and the number of connections over time like I believe TFS does, and simply close connections that are spamming to save on RSA decryption which is the only thing that's costly here.
Implementing this would take probably about 10 minutes tops as it's really trivial to implement.
And technically RSA CAN be designed to run in a separate process with TSS, so at the end of the day does it even really matter?
 
Not quite. This is a matter of design, but it's assuming that the server is entirely written in C++, which it's not.
It can't currently be designed the same way TFS or a pure C++ program can, and it probably never will.
Whether it's even possible to run it in a separate process or thread is a question in itself, probably the answer is no.
But it's possible to run the server asynchronously, which it already is, and if the rest of the code was run asynchronously as well including the maploading then the login server could run side by side with the rest of the code.
As to what TFS does, just for the record, it may or may not run the login server as a separate process, but the login server is not available during boot (until everything is finished loading, just like TSS).

I don't quite understand the 'additionally' part. Seems to me like the performance boost is the only advantage. But a fair one at that.
The good news is that it doesn't really matter. You can throttle the login server in other ways, for example through firewall rules, or even keep track of IPs and the number of connections over time like I believe TFS does, and simply close connections that are spamming to save on RSA decryption which is the only thing that's costly here.
Implementing this would take probably about 10 minutes tops as it's really trivial to implement.
And technically RSA CAN be designed to run in a separate process with TSS, so at the end of the day does it even really matter?

Not telling you what to do with your server, just giving some recommendations from my own experience. :)

The point being that you can separate the concerns with one process that handles cpu intensive authentication, and another process that runs the game server logic that cannot have high latency. The login and game server can be even physically different servers on the other side of the world with a token based auth. Besides encryption, password hashing is also supposed to be very slow. When you use a suitable algorithm like bcrypt with 12 e.g., rounds of hashing it may take up to 0.5 seconds of CPU time to authenticate a user. That is not something you want to put on the game server because it needs to be doing other things.
 
Not telling you what to do with your server, just giving some recommendations from my own experience. :)

The point being that you can separate the concerns with one process that handles cpu intensive authentication, and another process that runs the game server logic that cannot have high latency. The login and game server can be even physically different servers on the other side of the world with a token based auth. Besides encryption, password hashing is also supposed to be very slow. When you use a suitable algorithm like bcrypt with 12 e.g., rounds of hashing it may take up to 0.5 seconds of CPU time to authenticate a user. That is not something you want to put on the game server because it needs to be doing other things.
I don't think you're hearing what I'm saying. My objection isn't that you're telling me what to do, my objection is the server is not written purely in C++ like TFS is (with Lua bindings for scripting), it's written in a different language where you literally can't spawn another thread that runs on a different core, this is one of a handful of limitations with the language. There are certain ways around it, such as what I did with multicore map loading, but generally speaking you can't, only in certain situations.
Yes, I can separate the code from the server and run the LoginServer as a standalone, but I'm not gonna do that.
My first design did that a long time ago, but it's more convenient to have both running in one go, I'm sure most people would agree with that as well.

I sort of appreciate the feedback, it's something to think about it, but also keep in mind that unsolicited advice is generally the least valued advice.
Usually the better way to phrase unsolicited advice is by turning it into a question instead and staying humble and open minded about whether your question is relevant (if at all practicable, interesting, etc) to the person receiving the question.
To many people in fact unsolicited advice will be insulting. Personally I find it kind of rude or tasteless, but I don't take offense unless it comes off as particularly arrogant and "know-it-all", which I wouldn't strictly (...) classify your advice as, even though it may come off a little know-it-all especially when I just explained what the issue with your advice is as it pertains to my particular server which is not a pure C++ server and you dismiss it all with a "I'm not telling you what to do, BUT".
But to each their own, ya know.

And as far as hashing goes my guy, RSA comes before hashing, so if RSA is disabled temporarily from a certain IP that's spamming, then hashing will be as well.
My server, like I've said before, really isn't trying to compete with TFS on every single level though.
It probably never will, as I've said before, be able to host 1000+ players, for example.
I'm working with what I have and trying to do the best out of it, that's all.
 
Last edited:
I don't think you're hearing what I'm saying. My objection isn't that you're telling me what to do, my objection is the server is not written purely in C++ like TFS is (with Lua bindings for scripting), it's written in a different language where you literally can't spawn another thread that runs on a different core, this is one of a handful of limitations with the language. There are certain ways around it, such as what I did with multicore map loading, but generally speaking you can't, only in certain situations.
Yes, I can separate the code from the server and run the LoginServer as a standalone, but I'm not gonna do that.
My first design did that a long time ago, but it's more convenient to have both running in one go, I'm sure most people would agree with that as well.

I sort of appreciate the feedback, it's something to think about it, but also keep in mind that unsolicited advice is generally the least valued advice.
Usually the better way to phrase unsolicited advice is by turning it into a question instead and staying humble and open minded about whether your question is relevant (if at all practicable, interesting, etc) to the person receiving the question.
To many people in fact unsolicited advice will be insulting. Personally I find it kind of rude or tasteless, but I don't take offense unless it comes off as particularly arrogant and "know-it-all", which I wouldn't strictly (...) classify your advice as, even though it may come off a little know-it-all especially when I just explained what the issue with your advice is as it pertains to my particular server which is not a pure C++ server and you dismiss it all with a "I'm not telling you what to do, BUT".
But to each their own, ya know.

And as far as hashing goes my guy, RSA comes before hashing, so if RSA is disabled temporarily from a certain IP that's spamming, then hashing will be as well.
My server, like I've said before, really isn't trying to compete with TFS on every single level though.
It probably never will, as I've said before, be able to host 1000+ players, for example.
I'm working with what I have and trying to do the best out of it, that's all.
After reading this I don't feel like anyone would even want to check at your thread again, not even once, with that attitude of yours.

Pd: Did you pay Mrianura what you owe?
 
After reading this I don't feel like anyone would even want to check at your thread again, not even once, with that attitude of yours.

Pd: Did you pay Mrianura what you owe?
Feel free to close the door on your way out and never come back :)
And take this pack of tissues with you on your way out, you forgot them here the last time you visited asking for your poor friend's money 😭
 
Feel free to close the door on your way out and never come back :)
And take this pack of tissues with you on your way out, you forgot them here the last time you visited asking for your poor friend's money 😭
I never opened that door, it's more like looking at a window since all you do is bragging about screenshoots and videos, not even a single piece of code of your own to discuss about.
Bye scammer :).
 
Hi there!

I wanted to jump in here real quick and bring us back to the original topic. I know we're all passionate about our opinions, but let's try to stay on track with the discussion.

While I'm not an official moderator, I do think it's important that we respect the purpose of this forum and keep things on topic. If you feel like you want to have a more detailed conversation with someone, I completely understand, but perhaps it would be best to take that conversation to private messages.
 
when does this release? can I contribute? im quite good at typescript but im fucking lazy id never build something like this XD
would love to see this bigbig
 
Back
Top