View Full Version : Can someone explain Modules a little?
I don't know what a module really does or why you would use it. Could someone explain?
Syntax
02-27-2013, 02:12 AM
It's a queue system. It's so you don't hang up a script's execution running an infinite while loop.
This way you can have all your scripts in one lua file.
Ohman
02-27-2013, 12:43 PM
It's a queue system. It's so you don't hang up a script's execution running an infinite while loop.
This way you can have all your scripts in one lua file.
So when a module is executed, it will run and finish without having its execution interrupted, compared to a script with an infinite while-loop that can have its execution interrupted whenever?
I also see some use the registerEventListener(TIMER_TICK, "functionName"), not really sure when this should be used rather than modules
I've seen in your scripts that you've been using all these different methods. In some you use the above EventListener method, in other you use a module and also
infinite loop in some scripts. What makes you use different methods? Should modules be used only if you want to concurrently execute different contexts in the same script file?
Ended up with lots of questions haha, answer them if you feel like :)
Syntax
02-27-2013, 06:16 PM
So when a module is executed, it will run and finish without having its execution interrupted, compared to a script with an infinite while-loop that can have its execution interrupted whenever?
I also see some use the registerEventListener(TIMER_TICK, "functionName"), not really sure when this should be used rather than modules
I've seen in your scripts that you've been using all these different methods. In some you use the above EventListener method, in other you use a module and also
infinite loop in some scripts. What makes you use different methods? Should modules be used only if you want to concurrently execute different contexts in the same script file?
Ended up with lots of questions haha, answer them if you feel like :)
The main reason to use a module is so the module doesn't get in the way of the rest of the script.
It allows you for example to display messages in a custom channel while also listening for user input in that said channel.
registerEventListener(TIMER_TICK... was the old way of achieving this. Modules actually use this method in it's core, but there's a queue system on top of that so you can support
multiple TIMER_TICKs in a sense, as well as delay, stop, pause, and restart them.
To support old scripts that still have this method, any registerEventListener with TIMER_TICK specified will create a module, it's the same thing, but you should definitely just use a Module in the first place.
As far as my scripts, if I had time I would update them all to use modules, infinite while loops are fine if you have a dedicated .lua script for that specific action.
The main reason to use a module is so the module doesn't get in the way of the rest of the script.
It allows you for example to display messages in a custom channel while also listening for user input in that said channel.
registerEventListener(TIMER_TICK... was the old way of achieving this. Modules actually use this method in it's core, but there's a queue system on top of that so you can support
multiple TIMER_TICKs in a sense, as well as delay, stop, pause, and restart them.
To support old scripts that still have this method, any registerEventListener with TIMER_TICK specified will create a module, it's the same thing, but you should definitely just use a Module in the first place.
As far as my scripts, if I had time I would update them all to use modules, infinite while loops are fine if you have a dedicated .lua script for that specific action.
Sorry to hijack the thread, but have you had a chance to look at the problem I was having with Module.Stop in a custom chat channel?
parrode
03-06-2013, 06:09 AM
Sorry to hijack the thread, but have you had a chance to look at the problem I was having with Module.Stop in a custom chat channel?
I'm having a problem with Module either.
In my lua file I create:
local EquipRing = Module.New('EquipRing', function(module)
end)
function onWalkerSelectLabel(label)
EquipRing:IsActive() -- Always returns false
EquipRing:Stop() -- Seems like not to work, because Module still running
end
Anyone knows why doesn't work?
Bastiat
03-08-2013, 10:46 PM
Has anyone figured out how to make Module:Stop() work?? I've tried both Module.Stop('module name') and modulename:Stop() formats and it doesn't work...
The only thing that works is when I create the module without starting it (using false for param 'startOnCreate') I'm able to start the module using Module.Start... But stopping the module afterwards still doesn't work...
Maybe I'm just fooling myself and I can't use Module.Stop on a label??.. But then again starting a module works...
Also where should one put module code? In the beginning of the main lua file, the end, a dedicated lua file, or doesn't matter??
Has anyone figured out how to make Module:Stop() work?? I've tried both Module.Stop('module name') and modulename:Stop() formats and it doesn't work...
The only thing that works is when I create the module without starting it (using false for param 'startOnCreate') I'm able to start the module using Module.Start... But stopping the module afterwards still doesn't work...
Maybe I'm just fooling myself and I can't use Module.Stop on a label??.. But then again starting a module works...
Also where should one put module code? In the beginning of the main lua file, the end, a dedicated lua file, or doesn't matter??
We seem to be having the same problem actually! parrode too
Bastiat
03-18-2013, 10:05 AM
We seem to be having the same problem actually! parrode too
Yeah I pretty much gave up on modules until things are clearer... For now I'll just keep using multiple lua files. It works, it's reliable, and I can easily manually kill the scripts if I want.
Honestly I'm not even sure what's the advantage of using modules (other than not having to use multiple lua files)... I thought being able to start and stop modules on labels was a great advantage but it doesn't work. :rolleyes: Yes I know I could use labels like elseif (Label == "startRingSwitcher") then RingSwitch = true
elseif (Label == "stopRingSwitcher") then RingSwitch = false and then put if RingSwitch then at the top of the module but I feel it's not clean enough. :p
...Plus I'm not even able to make the anonymous function module format work at all --This format doesn't work (or I just have no idea where the hell to put it):
Module.New('Ring-Switcher', function()
--This format works... to some extend:
function RingSwitcher(module)
Hendy
03-18-2013, 04:27 PM
Below is a description of modules, explanation from Spectrus
A module is a function that when created, is added to the TIMER_TICK event. It is then executed every 200ms, as is the behavior of the TIMER_TICK.
To create a Module, simply call the constructor for it: Module.New(name, func). The parameter name is a string which can then be used to modify the status of the module (i.e. Module.Stop(name), etc.). The function is the function that will be called when the TIMER_TICK event occurs.
In essence, a module is as simple as this:
###############################
-- First create a function for your module.
function checkCreature()
local c = Creature.New('Demon')
if c:isAlive() and c:isOnScreen() then
print('Run!')
end
end
-- Then create a module for that function.
Module.New('creature check', checkCreature)
################################
If you would like to control your module at any time, you can start or stop it with Module.Start(name) and Module.Stop(name).
Bastiat
03-20-2013, 08:53 AM
Below is a description of modules, explanation from Spectrus
A module is a function that when created, is added to the TIMER_TICK event. It is then executed every 200ms, as is the behavior of the TIMER_TICK.
To create a Module, simply call the constructor for it: Module.New(name, func). The parameter name is a string which can then be used to modify the status of the module (i.e. Module.Stop(name), etc.). The function is the function that will be called when the TIMER_TICK event occurs.
In essence, a module is as simple as this:
###############################
-- First create a function for your module.
function checkCreature()
local c = Creature.New('Demon')
if c:isAlive() and c:isOnScreen() then
print('Run!')
end
end
-- Then create a module for that function.
Module.New('creature check', checkCreature)
################################
If you would like to control your module at any time, you can start or stop it with Module.Start(name) and Module.Stop(name).
That somehow gave me a little insight and I rewrote the module and got it running seemingly perfect including Module.Start() and Module.Stop() on labels.
Now I just need to figure out the whole Channel class. xD I need to start/stop modules by typing stuff in a channel. :D
Spectrus
03-20-2013, 09:02 AM
Here we goooooo! Explanation time:
The channel class is used to create custom console channels. To better understand how it works, let's first consider what classes are. There are several classes in Xenobot scripting; Self, Creature, Map, Item, etc. When you need to interact with one of these classes you create an object of that class. You do this by calling a constructor function (in most cases something like Creature.New()). Each constructor function for each class requires certain information in order to make your object how you desire. For a channel, that information is a name (shown on the channel tab), a function to be called when a user inputs text, and a function to be called when the channel is closed.
What all this looks like:
################################
-- note that the onSpeak and onClose functions should be defined before creating the channel.
function onSpeak(channel, message)
-- receives the channel object that called it and the message that was inputted.
if (message == 'hi') then
channel:SendOrangeMessage('Robot', 'Hi!')
end
end
function onClose(channel)
-- receives the channel object that called it
print(channel:Name() .. ' has been closed.')
end
-- Now we create the channel.
local customChannel = Channel.New('My Channel', onSpeak, onClose)
################################
Some important functions for using channels.
Channel:SendYellowMessage(senderName, message)
Channel:SendOrangeMessage(senderName, message)
Channel:Close()
I don't really use any of the other ones... :(
Also, it's important to note that we define the callback functions before creating the channel. If they were after, the channel would be created first and it would not know those functions exist (error plx). Also important is the fact that they are passed the channel that called them. Inside the scope of these functions, always refer to the channel object as it is passed in the parameter, not what you have named the channel object when you created it (in my example, inside the function use channel:SendOrangeMessage() and outside the function use customChannel:SendOrangeMessage()).
Hope it helps!
Bastiat
03-21-2013, 01:07 AM
Here we goooooo! Explanation time:
The channel class is used to create custom console channels. To better understand how it works, let's first consider what classes are. There are several classes in Xenobot scripting; Self, Creature, Map, Item, etc. When you need to interact with one of these classes you create an object of that class. You do this by calling a constructor function (in most cases something like Creature.New()). Each constructor function for each class requires certain information in order to make your object how you desire. For a channel, that information is a name (shown on the channel tab), a function to be called when a user inputs text, and a function to be called when the channel is closed.
What all this looks like:
################################
-- note that the onSpeak and onClose functions should be defined before creating the channel.
function onSpeak(channel, message)
-- receives the channel object that called it and the message that was inputted.
if (message == 'hi') then
channel:SendOrangeMessage('Robot', 'Hi!')
end
end
function onClose(channel)
-- receives the channel object that called it
print(channel:Name() .. ' has been closed.')
end
-- Now we create the channel.
local customChannel = Channel.New('My Channel', onSpeak, onClose)
################################
Some important functions for using channels.
Channel:SendYellowMessage(senderName, message)
Channel:SendOrangeMessage(senderName, message)
Channel:Close()
I don't really use any of the other ones... :(
Also, it's important to note that we define the callback functions before creating the channel. If they were after, the channel would be created first and it would not know those functions exist (error plx). Also important is the fact that they are passed the channel that called them. Inside the scope of these functions, always refer to the channel object as it is passed in the parameter, not what you have named the channel object when you created it (in my example, inside the function use channel:SendOrangeMessage() and outside the function use customChannel:SendOrangeMessage()).
Hope it helps!
Hell yeah works like a charm! :D
http://img515.imageshack.us/img515/8282/modulechannel.jpg
Is it ok to use "wait(50)" inside modules or do you have to use "module: Delay(50)"? Also, If you call a function from outside the module is it ok to have "wait(50)" in that function or will those commands delay the execution of the main .LUA ?
Spectrus
04-13-2013, 07:17 AM
Is it ok to use "wait(50)" inside modules or do you have to use "module: Delay(50)"? Also, If you call a function from outside the module is it ok to have "wait(50)" in that function or will those commands delay the execution of the main .LUA ?
wait(50) will delay the execution of other modules, whereas module:Delay() will yield to other modules until it's ready to start again, but module:Delay() can only be delayed in increments of 200ms.
Syntax
04-13-2013, 07:19 AM
Is it ok to use "wait(50)" inside modules or do you have to use "module: Delay(50)"? Also, If you call a function from outside the module is it ok to have "wait(50)" in that function or will those commands delay the execution of the main .LUA ?
wait(50) will lock the thread (the entire script will stop 'thinking')
module:Delay(50) will pause the module, it won't fire until the delay has passed (though there's no point in calling a delay under 200ms as Modules can't think faster than 200ms (TIMER_EVENT limitation)
edit: fuuuuuuuuu Spectrus.
@Spectrus (http://forums.xenobot.net/member.php?u=3) @Syntax (http://forums.xenobot.net/member.php?u=193)
+1
Thanks so much, this definitely explains a problem I was having. I think I am better off using separate .LUA scripts. :(
What about if you call a function from outside a module within a running module will the wait interupt it?
Spectrus
04-13-2013, 08:41 PM
Yes. :p
Danicast
06-13-2013, 09:47 AM
i have a probelm with modules :S!
im using a script wich use a targetting script instead of using the classic targeting... im trying to use modules 'cause you can have all in one lua but... it suddenly stops the modules and i have to restart the script :S
its anoying 'cause i want to afk bot :S
anyone knows whats happening?
Nakuu
06-13-2013, 09:51 AM
i have a probelm with modules :S!
im using a script wich use a targetting script instead of using the classic targeting... im trying to use modules 'cause you can have all in one lua but... it suddenly stops the modules and i have to restart the script :S
its anoying 'cause i want to afk bot :S
anyone knows whats happening?
Show us the error message.
Danicast
06-13-2013, 09:55 AM
there's not an error message it just stop executing the module... Here it is:
function TargetingScript()
local Creatures = {"Water Elemental", "Quara Mantassin Scout"}
for i = CREATURES_LOW, CREATURES_HIGH do
local c = Creature.GetFromIndex(i)
if c:isAlive() and c:isVisible() and c:isReachable() and c:isTarget() then
if (GetMonstersArround(6, unpack(Creatures)) < 4) then
if (Lightning) then
if (Self.CanCastSpell("Exori amp vis")) and (c:DistanceFromSelf() <= 4) and (c:HealthPercent() >= 30)then
Self.Say("Exori amp vis")
end
end
if (ExoriGranVis) then
if (Self.CanCastSpell("Exori gran vis")) and (c:DistanceFromSelf() <=3) and (c:HealthPercent() >= 30)then
Self.Say("exori gran vis")
end
end
if (Self.CanCastSpell("Exori vis") and c:DistanceFromSelf() <=3) then
Self.Say("Exori vis")
end
else
if (UE) then
if Self.CanCastSpell("exevo gran mas vis") then
Self.Say("exevo gran mas vis")
end
end
if (ThunderStorm) then
Self.UseItemWithTarget(3202)
end
end
end
end
end
function GetMonstersArround(r, ...)
local n = 0
local m = {...}
for i = CREATURES_LOW, CREATURES_HIGH do
local c = Creature.GetFromIndex(i)
if c:isAlive() and c:isVisible() and c:isReachable()and c:isMonster() and (c:DistanceFromSelf() < r) and table.contains(m, c:Name()) then
n = n + 1
end
end
return n
end
Module.New('TargetingModule', TargetingScript, true)
dinmamma
06-13-2013, 10:33 AM
After how long tome does it stop?
Because I noticed that a few of my simplier modules are stopping after a couple of hours if not being used. Has also happened that they stop inthe middle of a hunt, but very rarely and only if I did something to interrupt the module (like walking manually causing the actions of the module not being executed properly).
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.