Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
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!
Some suggestions / requests, for a common issue I've had in the past.
Basically, I would like to see everything related to combat exposed / viewable / modifiable via Lua.
expose the damage before mitigation -- callback
creature:getArmorValue()
creature:getAttackValue()
creature:getDefenseValue()
creature:getElementValue("fire", "all")
creature:getAllStatValues()
item:getValue("anything that can be attached to the item via xml / TOML")
item:setValue("anything that can be attached to the item via xml / TOML") -- this kind of exists, but needs to be expanded?
item:getAllValues("anything that can be attached to the item via xml / TOML")
The before mitigation damage is important as it allows us to modify it before it gets to onHealthChange/onManaChange, allowing for much better direction. A valuable addition to this would be updating onHealthChange/onManaChange to include the before mitigation damage as a new parameter.
The creature stuff is just quality of life perks, so you don't need to manually figure it all out.
The item stuff is.. actually really required.
Currently you often can't find many of the values (gender change, element value, regen values), or you have to juggle between a couple different methods to find the base value or the modified value on the item, and it's really annoying.
And there is quite a few values you cannot alter or add to the item, but are available to be added via xml / TOML.
--
There is also a probably massive thing to change in movements.
Currently onEquip and onDeEquip , onStepIn, onStepOut, onAddItem, onRemoveItem only trigger after the thing has happened.
If at all possible, it'd be great to have some solution.. (maybe new callbacks?) that allows you to check before the thing happens?
Basically I want a system that allows us to return true or false, to be able to allow or negate these actions at our own discretion, instead of applying backwards logic to solve it.
Currently if someone steps on a tile, and we don't want that, we have to teleport them off the tile.
If someone equips a piece of gear, but we don't want that to happen.. we have to go through onMoveItem, and check a whole bunch of extra stuff to see if we want the person to equip the item.. and then return/false true.
It's just really clunky, and you can't solve every issue with these workarounds.
--
1 other quality of life addition would be to add in a way to limit common character actions.
Like..
creature:canInteractWithEnvironment(true/false) -- basically don't let them click on anything / use objects
creature:setMovementBlocked(true/false) -- this already exists, but only works for players, not monsters/npc's. (should also disable follow lock?)
creature:canAttack(true/false)
creature:canHeal(true/false)
creature:canCastSpells(true/false)
creature:canCastRunes(true/false)
I hadn't thought of this section too much, so I'm sure there are other things to limit, but these are helpful.
Although, if you really wanted to, you could re-create the creature walk system in the source.. That's where I found some of these issues.
--
Specifically for monsters, it'd be neat if you could add
monster:setIdle(true/false) -- so they basically just become a statue
monster:canTargetMonsters(true/false[, onlyIfPlayerInRange = true]) -- so they will target monsters as well as players.
monster:ignoreTarget(creature) -- Could potentially improve this to include additional checks, like a list of storage values or something, but I can't think of a good way to do that.
monster:setLoot(table?) -- all of these would modify for a single creature, instead of modifying the entire base creature
monster:addLoot(table?)
monster:removeLoot(table?)
--
oooh, and a way to force players/creatures to cast a spell via Lua.
creature:castSpell("spellName", expendResources = true/false, ignoreRequirements = true/false) -- mana/soul and like level/magicLevel/vocation et cetera.
Not really. This is TFS 1.4/Black-Tek code for onEquip:
Code:
onEquip(player, item, slot, isCheck)
someone even reported that onEquip is called twice, but it's first time called with isCheck = true (before equip) and second time with isCheck = false.
With current item attributes storage method (based on bitwise operation in hasAttribute), it limits 'fast' custom attributes to 30 (31 is CustomAttribute). TFS uses these 30 available values to store common attributes like armor/attack/defense/duration/description, but it can't store every item attribute - there are too many.
I once worked for OTS that rewrote all attributes into 'custom attribute' format ("name" -> "variable type" + "value") with std::map<std::string, CustomAttribute> storing all item attributes in C++, which made it able to store infinite attributes per item in C++ and in database. They had 500+ online, so it could not affect OTS performance too badly.
I'm also pretty sure that long time ago (TFS 0.1/0.2/0.3) this format was used in TFS, because my ItemAttributes code from 2008-2012 looks like this:
function onEquip(player, item, slot, isCheck)
return false
end
The item still gets equipped
I can't read source, but trying before, I've seen isCheck print out up to 7x on 0.x servers and 3x on tfs 1.0+ servers.
So basically the current common solution is
LUA:
function onEquip(player, item, slot, isCheck)
if not isCheck then
-- do the code you intend
end
return true
end
So in practice, even though isCheck could be useful, it currently shows true once or multiple times per item equip, then false when it's done all it's other checks.
If at all possible, it'd be great to have some solution.. (maybe new callbacks?) that allows you to check before the thing happens?
Basically I want a system that allows us to return true or false, to be able to allow or negate these actions at our own discretion, instead of applying backwards logic to solve it.
You mention here and somewhat in other parts of your message about the problems with the current events interfaces and their design... well you better believe I have already realized these problems and been developing a plan of attack design for a total event interface overhaul to tackle the many problems from movements, creatureevents, event callbacks, all of them.
My idea solves the specific complaints you have, as well as help addresses some performance concerns as well.
Basically in most simple terms, its this " canEventName, doEventName, onEventName" So for example. "canMove, doMove, onMove", or "canHealthChange, doHealthChange, onHealthChange".
Where "can" is a boolean based return type, event. Can based events are there for you to determine if we can go forward with the execution.
"Do" is kind of what it sounds like, it's available to provide unique values on the return type, specific to the event.. so for example, exactly how the onHealthChange currently works, it would just be doHealthChange instead, and you would manipulate the damage values and types and return those..
Last we would have a void based event that just triggers whenever the event happens, no return value, basically just a trigger for when things happen. These kind of event convention would address your issues and concerns with pre-damage mitigations and stuff like that, as the "can" would be before the event, the "do" would be literally during logic execution for that event, and "on" would be after everything has checked out successfully and the event served its purpose, so right at the end of the call. This gives us all the places we need, and all the control we need, to handle potentially every possible situaion we might want to address.
I'm still working out the details of this plan, but I think all the "on" events would be best to be "event callback" style, as in the event's are always called without the need to register them specifically to a thing, while the "do" events would for sure be like actions, creatureevents, movements, ect, where you need to register them to a thing before they are executed... and I'm still un-decided if I want to do the "can" bool check events as eventcallback style or old event (registration) style.
monster:setIdle(true/false) -- so they basically just become a statue
monster:canTargetMonsters(true/false[, onlyIfPlayerInRange = true]) -- so they will target monsters as well as players.
monster:ignoreTarget(creature) -- Could potentially improve this to include additional checks, like a list of storage values or something, but I can't think of a good way to do that.
monster:setLoot(table?) -- all of these would modify for a single creature, instead of modifying the entire base creature
creature:castSpell("spellName", expendResources = true/false, ignoreRequirements = true/false) -- mana/soul and like level/magicLevel/vocation et cetera.
I like where you are going with these suggestions! I have already decided monsters need a huge rework, and I also decided I would like to build full fledged "temperaments" for the creatures and rebuild their AI with a good statemachine and coroutines.. These temperaments could include the different attributes you mention as "predefined" sets of values, but ofc I'm big about allowing the end user extensibility and flexibility with the choices, so I may just make the temperaments able to be defined in toml or something... but yeah basically, you would have stuff like :
Each temperament would ofc cause different behaviors from the creatures, depending on if you are attacking them or another monster of their type, if you are too close, ect.
Like passive only attacks back if attacked (and flees when low), timid runs when attacked or you get too close, evasive types immediately and always run, pack types attack if you attack one of their own, territorial monsters attack if you get too close, ect, ect.
I'm very big about having all these kinds of things as options that can be created and decided by the end user, so my plans will for sure empower the Dev's who plan to use BlackTek... the only thing is, after first release, I'm dropping all backwards compat and tibia like restraints on my development, so it means people who wish to use all these new cool things, will not be able to just migrate their ancient datapack on over... pretty much, after first release, any release afterwards is gonna almost require people to recreate their systems and such from scratch, except that I will try to also provide working demonstration systems like TFS has done over the years, like stuff for potions, and doors, and basic stuff, showing how to use all the new API...
As for the part about custom attributes on items, or at least allowing more types of attributes/values to be set/get to/from the item... well I'm working on building all the missing developer tools that should come with this kind of server setup, including an asset manager. At first, the asset manager will be built so that it works perfectly with the spr, dat, and otb formats currently used by blacktek and tfs 1.4, but once I have it all working perfectly, I will have to had written every single attribute/trait/property of sprites, items, objects, and so I will have a good idea on what all is needed, not needed, what can be improved, and how to group them all effeciently, so that I can build new formats and types that will allow much easier integration of new "objects" or "sprites"... and I would like to make that format and the systems that use it very robust and feature full, with stuff like supporing variatible sprite dimensions (as graphic quality settings) from 32x32 on up to 512x512, as well as a whole slew of ideas to make the "Content Developer" not need to know how to code.
All in all, I appreciate your suggestions and I am pleased to see people responding and interested in what's in store next for Black Tek. It seems we are like minded on many things and I think you are going to like what's in store after this first release
I have clearly stated many times and many places... version 1.0 will only serve as a nice updated and stable version of TFS 1.4.2 basically, like its just a better option for 10.98 clients, or anyone who wishes to take a good base server for downgrades that already still uses spr, dat, and otb instead of protobufs, and doesn't require a login server.
I have also stated many times, once the first official version is released, I will be switching gears and transforming the server into a custom game engine, rather than a "tibia emulator". With the purpose of being a unique engine that allows rapid development of custom 2D TopDown MMORPG's or other type of online gameplay that is 2D topdown.
The purpose of this project, is to learn and develop my skills, while improving the codebase and transforming it into something that is actually capable of building and running the game I wish to make.
I have clearly stated many times and many places... version 1.0 will only serve as a nice updated and stable version of TFS 1.4.2 basically, like its just a better option for 10.98 clients, or anyone who wishes to take a good base server for downgrades that already still uses spr, dat, and otb instead of protobufs, and doesn't require a login server.
I have also stated many times, once the first official version is released, I will be switching gears and transforming the server into a custom game engine, rather than a "tibia emulator". With the purpose of being a unique engine that allows rapid development of custom 2D TopDown MMORPG's or other type of online gameplay that is 2D topdown.
The purpose of this project, is to learn and develop my skills, while improving the codebase and transforming it into something that is actually capable of building and running the game I wish to make.
I see you're getting asked these similar questions with a high level of frequency. When I first looked at your project I asked myself the same question: "what's the goal here?" and couldn't find an answer without finding this thread.
I would recommend updating your README to include the purpose of your project; even if the goal in the future is to be an independent game engine, at least in the beginning if you're looking to improve TFS - mention that. The goal is to address these issues with TFS with these goals in mind. Once the project expands and you've got more name recognition, adjust the README accordingly and this text can live in a milestone message.
It's nice seeing the work you've already done and I will continue to follow your project.
Legit, facts. Great recommendation, and honestly not sure why I didn't even think about that, nor why I have taken so long to give the project a description.
We are getting closer now. I have finally updated the windows work flows so that every time a new commit is accepted into BlackTek Server master branch, there will be a compilation done of Premake5, *.dll's, BlackTek-Server-Release.exe, and BlackTek-Server-Debug, and them all zipped together with the datapack and solution files, ect... and then uploaded as an "Edge Build" release.
We are getting closer now. I have finally updated the windows work flows so that every time a new commit is accepted into BlackTek Server master branch, there will be a compilation done of Premake5, *.dll's, BlackTek-Server-Release.exe, and BlackTek-Server-Debug, and them all zipped together with the datapack and solution files, ect... and then uploaded as an "Edge Build" release.
I feel like that is getting to be a bit too verbose at that point. I had other ideas and longer versions I have tried naming them, they just sound better than they look on paper IMO.
In other news: I forgot to mention, getting setup for compiling on windows now (and linux for awhile now) is completely automated via bootstrap script, to make it easier for those looking to get started who are not so handy with build tools and dependencies.
This just seems like an unneccessary complicated move.
Cheers
(tbh can't remember how it was setup, all I know is that I could change EQ on sample chars and they were added to new characters, maybe it's MYAAC-related?)
This just seems like an unneccessary complicated move.
Cheers
(tbh can't remember how it was setup, all I know is that I could change EQ on sample chars and they were added to new characters, maybe it's MYAAC-related?)
I don't think that there is anything complicated about it, you are talking about two different systems made to do the same thing. One from website, other inside the server, you can choose which ever method you want and remove the other... the point in that script on TFS I think was to demonstrate
I don't think that there is anything complicated about it, you are talking about two different systems made to do the same thing. One from website, other inside the server, you can choose which ever method you want and remove the other... the point in that script on TFS I think was to demonstrate
I just wanted to check in with those who are still following the project but have not yet joined the community (for which you can find the link on the github, my signature below, or at the top of the server when it starts up in its console)
I wanted to let you all know, even tho the repo looks like I haven't done anything to it in a nearly three weeks, that's not the case! I have been working on the server tirelessly for the past few weeks making the necessary changes to switch the Thing class and all its derived classes to the use of "shared pointers". If you don't know what that is, it's not something you need to worry so much about, just know that BlackTek aim's to be memory leak free, and this is a great step towards that goal.
Anyways, the rough draft is done. I have successfully compiled, started up, and logged in without any error what-so-ever. There is still loads more to do, but I wanted to let you all know I'm still working on this project tirelessly, not taking a break
- Removed manual ref counting for Thing based classes - Implemented Shared Pointers for managing Thing based classes' objects - Did some minor refactoring - Used const correctness in more lo...