Open mindrage opened 9 years ago
Why don't a function for load all scripts inside a folder and then load it in global.lua?
Cause that is alot of work, and really, the functionailty would still be the same. No real need to make such ways. Also there is many ways to load in things. How exactly do you mean? One simple function to load a data folder?,. Or do you mean loading everything in by lua? It really doesnt fill out the details.
Not sure which is the right approach but I like simplifying the process of providing / adding new systems / events. Instead of describing what has to be added where you can just provide the folder.
This might however conflict with the idea/concept of the new events.
I agree that we need more modularity for systems implemented in Lua. I'm just not sure about the idea of having multiple data folders, I'd rather have modules in a path like data/modules/. Here's my suggestion:
data/modules/shovel/module.xml:
<module name="Shovel" enabled="1">
<action itemid="2554" script="scripts/use.lua" />
<!--
This should allow for any of our scripting interfaces, e.g. you could also add:
<movevent event="StepIn" itemid="2554" script="scripts/stepin.lua" />
-->
</module>
data/modules/shovel/scripts/use.lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
if not target:isItem() or target:getId() ~= 481 then
return false
end
target:transformTo(482)
return true
end
I'm not entirely satisfied with that solution though, I'd rather find a way we could also hook into events (e.g. make use of Player:onLook() in a module). We would also have to worry about execution order/priority. Perhaps we could allow events to be registered in a modules XML file like this:
<event class="Player" method="onBrowseField" script="scripts/browsefield.lua" executionorder="-1" />
... where the execution order is 0 for the default events in data/events/, and -1 in this case would mean that this modules event will run before the default event (and anything above 0 would mean after), and if this modules event returns false then the default event won't run. Execution order would also be necessary for interfaces like actions (e.g. if two different modules register an action with the same item id, which one will run first?).
This issue is open for discussion, I'd love to hear other ideas or improvements on my suggestion.
Hooks to the new event interface will be awesome.
Hooks for events can be done by Lua, something like Npcsystem do, would be easier and will work like a charm =)
Well i did notice that when you use the form: @conde
function Creature:onSomething()
return stuff
end
The function object could be obtained trough __newindex and hooked in that way. I thought first maybe you could have done something like
function Action{ itemid = 1432}:onUse()
end
However that would be a syntax error.
Hooking events trough lua would give much more control of things, though there would be alot of things what would get messy, I liked the Structure mark suggested as it made most sense for new scripters.
But somehow i also can imagine by hooking modules as actual lua modules.
Then the acutal choosing of where to hook would be simular to something like this.
local Demon = MonsterType("Demon")
function Demon:onCreatureAppear(creature)
return true
end
local Shovel = ItemType(xxxx)
function Shovel:onUse()
end
function Shovel:onStepIn(thing)
end
local player = Player("Name")
function player:onLogin()
end
The __newindex could simply link the reference of the function, and the actual classes for the Event Containers would only be used to verify. But then the problem would be here. How would you register these events on actual instances?
Anyone knows what im doing wrong with my markdown?..
Registers event would be awesome if we could do something like that:
local Shovel = {}
function Shovel.someOnUse()
some stuff
end
function Shovel.someOnStepIn()
some stuff
end
function Shovel.registerEvents()
Shovel.someOnUse:registerOnUse(XXXX)
Shovel.someOnStepIn:registerOnStepIn(XXXX)
end
Shovel.registerEvents()
@nu77, Yeah This is all just speculation around. Hooking things trough lua would be a good way to handle the events. However it would break backwards compability quite alot. I think i heard @dalkon was working on a XML Parser in lua, which could basically make all the current systems be read and loaded in trough lua. That would work as a transition so the compability will atleast be there.
The point of having this was simply to make the handling of scripts more organized. No real need to actually bind things trough lua. But it surely gives more functionality by being able to to handle the creation and binding of events directly trough lua calls.
To be more to the point. The events must be able to link to multiple objects as easy as XML can link them. You still want an easy syntax to write with. Adding an extra function call to bind the event is not really anything newer people wants to do. The syntax: ˋˋˋ function Creature:onUse()
end ´´´ syntax was very good indeed and it can still be used with __newindex as a way to link things. However how the syntax should be to easily link it to an certain object. you could do something like this: ˋˋˋ Game.getItem(4321).onStepIn = function(self, fromPos, toPos) end ´´´ But to be honest.. That is quite ugly. I was planning on making some Data Collection library which could be used as a way to link multiple classes and preform operations on all. Where the getPlayers() would return a Group Object. Game.getPlayers():setLevel(8)
So.. i was thinking why not make something simular to bind Events? ˋˋˋ local Shovels = Game.getItems{ itemid = {1435, 2141}, actionid = 1003 } function Shovels:onUse() end ´´´ This basically means that the Server handles the "Group" class. and the group can be securely checked and all that.
With this suggestion and all further comments, aren't we being literally redirected into Revscriptsys?
From Marksamman suggestion, it would look awful to have:
data/mobules/shovel/module.xml data/mobules/shovel/scripts/use.lua
It would mean we will have several folders and files just in the modules folder, which is really disorganized.
Can't we just have it like this:
<module name="Normal Shovel" enabled="1">
<action itemid="2554" allowfaruse="no">
<script type="onUse">
--- lua code
</script>
<script type="onStepIn">
--- lua code
</script>
</module>
There is nothing wrong with revscriptsys, I was actually planning on using revscriptsys before starting the development of 1.0, but because of @hjnilsson's inactivity and the fact that I had very little knowledge about the codebase I figured that it would be too much work to have everyone rewrite all their scripts to make the transition. Instead, we've been making incremental steps towards revscriptsys (unintentionally). I think we should definitely look at revscriptsys for inspiration of how to design a more modular script system, @hjnilsson has done a really good job with it and it's sad that it didn't get widely adopted.
As for your suggestion, Lua should not be written in XML files for many reasons, one of them being that debugging becomes harder. If we really want it to be a single file, then it should be entirely in Lua, example of how shovel.lua could look:
local function onUseShovel(player, item, fromPosition, target, toPosition, isHotkey)
if not target:isItem() or target:getId() ~= 481 then
return false
end
target:transformTo(482)
return true
end
registerEvent({event = "onUse", itemid = 2554, callback = onUseShovel})
^
That's what I meant when i said:
"Hooks for events can be done by Lua, something like Npcsystem do, would be easier and will work like a charm =)"
It's what i was trying to say, registering events should be possible in Lua without .xml file.
I really do like the idea of binding all things directly in Lua, thats what i felt made Revscriptsys so attractive to me when it was under the works, however I can definately agree that when doing mods for example of the 0.3-0.4 branch of TFS, it made it really hard to acutally make stuff inside files, so you had to basically, make a separate file and link it, then go around and copy paste everything inside the file later, then test everything again just to make sure its working. The only benefit i see with using XML is the fact that its a data language, it doesnt execute any operations, which makes it a safety factor. it also looks a bit more organised, since well coders in the OT community arent all experienced and do not really think of how they want to organize their code, they simply want to working.
However i really do appreciate the benefits given from lua version, due to all of the possiblities you get with it. But still i prefer som kind of forced structuring so we actually have a standard for new people to try it out as well. this is still a community-focused software.
I think which .xml will continue and the change will be the new folder only... also think which .xml let all more disorganized, with hooks events is possible do a entire system with only one script, easy and fast to do.
LUA script event registering is good, let's stop using ugly XML files :+1: besides that it will clean up the code it will make the interface more friendlier, and again it just shows that we're again moving forward to a more revscriptsys environment, too bad Revscriptsys didn't get the love it deserved.
Maybe this implementation should work in a module folder for keeping Backwards compability.
I think we should look forward and use the total power of Lua Scripting, if you look around other lua engine implementations we see the use of hook binding, it's a powerfull feature. This could be done without affect backward scripts, then why not?
modules.lua could look like this:
registerAction(uniqueId, 30015, "--[[data/modules/]] quests/annihilator.lua")
registerMonster("Troll", "Trolls/troll.xml")
everything can be loaded from global.lua anyway so if you want to get rid of xml files, it may become main script loader, for example: global.lua
dofile('data/actions/actions.lua')
actions.lua would look like this:
registerAction(uniqueId, 30015, "--[[data/actions/scripts/]] quests/annihilator.lua")
Basically what you mean is mods. They're already included in TFS 0.3/0.4. You can make multiple systems. The idea is simple: you have one XML file per system. In that file you can define as many actions/talkactions/items etc as you wish.
Example mod: https://github.com/slawkens/tfs-mods/blob/master/killed-monsters-counter.xml
I might make support for mods for TFS 1.0 when more people are interested.
@slawkens Would be better to have it in Lua, trying to find errors etc with mods can sometimes be a pain. But I would love to have "mods" back - just keep it 100% Lua :p
Yeah, the idea was just to be able to package things together for easier management and (maybe) distrobution. Having it in lua would be pretty great. but security is also a factor.
The best solution would be probably adding simple lua functions for registering actions/items etc.
Like this:
function myFunction(cid, ...)
print('Test')
end
Actions:registerActionId(300, myFunction)
Movements:registerUniqueId(100, myFunction)
local properties = {weight = 100, value = 1}
Items:register(2160, "gold coin", properties)
Talkactions:register("!mycommand", myFunction)
And then, make a directory (Like plugins/mods) where are .lua files will be automatically loaded from.
We are talking about an entire module restructuring, not just folders, and that probably will come after a Lua interface restructuring.
Some days ago @TheSumm posted this on Discord https://github.com/TheSumm/forgottenserver/commits/action-script That's pretty clean imo
A better system has been developed around 10 years ago on my old, slow PC, in Poland.
The system is called "mods" and is in TFS 0.3 series since ages.
Originally it was first introduced in 0.4.0_DEV, as pointed in CHANGELOG file of the revision 3777 of TFS 0.4 series, that is and was, by the way, the most successful series of TFS 0.3, and was originally developed by me, Elf and KaczooH.
I post a link with example mods developed for the system, if someone is interested: https://github.com/slawkens/tfs-mods
Yes, I was the original guy behind the idea. The whole concept is based on my vision, and the first implementation was done by me and Elf, around 10 years ago.
SO please, don't comment if you didn't developed something better. This is nothing personal to you @joseluis2g, thanks by the way, for refreshing this thread and posting something interesting.
@slawkens https://github.com/HeavenIsLost/elysium/blob/master/data/actions/actions.lua Check this, i appreciate your feedback.
Hierarchical modules are nice, but not code inside XML. I would prefer something scripted in Lua instead.
@ranisalt I also don't like the code inside of xml files, because you can't highlight it without plugins etc.. The examples I posted were just to demonstrate the power of the system. Normally it's possible to register them (any actions, events) in separate files. That's possible with the mods system. I just wanted to show that idea isn't new, and some work in this direction has been already done.
I find the data folder really useful when creating scripts, its as simple as selecting the event you want to make, then make the script for it. However. It also is something i think most people find annoying. Everything is clustered around all diffrent folders, you dont really have much options to organise. Yes, you could link the folders with the ".." paths but. nothing really anybody prefers to work with.
So.. i come with this suggestion instead. What if we made the data folders modular. Keep the same structure inside the data folder. But allow multiple data folders to be loaded in. and only load in those folders which exists inside a folder.
The folders will be linked via a xml file, which has these attributes:
this would basically make systems much more organised and work can be shared and edited separately. The current data folder could be called core, main, default or something.
So the general benefits: Grouping scripts, allowing people to work on a system and then only need to paste a folder to combine systems. Ability to disable systems Little to low coding, You practically only need to iterate the folders in the modules.xml file, and maybe make folders optional for everything except the main module. Backwards compability, Everything you written should work out of the box.
The drawbacks would be small. a bit longer loading time, since obviously more files to load. The modules obviously would contains alot of folders, ex Talkaction/scripts/ will still be there for every folder that uses a talkaction..
Since i've heard many people also wanted mods back into the code, this would actually be a simple but pretty flexible solution.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.