I feel like I’ve got the syntax right, but the value returned is nil.
the module
local B = {}
function B.dmg(self, v, message_id, message, sender, damage)
damage = 1
if message_id == hash("dmg") then
damage = 2
local del = nil
del = timer.delay(10, false, function(self)
damage = 1
end)
del = nil
end
end
function B.get(damage)
local value = damage
return value
end
return B
the script it’s targeting(ignore the bad spelling)
local B = require "main.enimeises.dmg"
self.dmg = B.get(damage)
There’s a few issues here and I don’t think it’s a problem with your module syntax.
The main problem is the damage variable. It doesn’t appear to be declared anywhere other than inside B.dmg(), where it is declared as a global variable. I would either declare it as B.damage (if you want it to be directly accessible from outside the module) or as a local variable inside B (in which case you could use a function like B.get() to return the value.
local B = {}
B.damage = 1
--or
local damage = 1
--etc
Your function B.get() doesn’t really make sense as currently written. It will basically just return whatever value you pass in. E.g. B.get(2) will return 2, no matter what else is going on inside your module. I would write it as:
function B.get()
return damage
--or return B.damage
end
Depending on how you scoped the damage variable.
I don’t exactly understand what you are trying to achieve in function B.dmg(), but it doesn’t make much sense to me and probably needs a redesign.
Sorry for the late response, I’ve had a lot of stuff to deal with recently, but the purpose of the Module is to create and change a value for player damage that can be stored and accessed by any file that needs it, e.g an enemy. I’ve also tried the b.damage and return b.damage and it still returns nil. Not sure what else I can do, but I don’t really feel like restructuring it for the forth time.
I wouldn’t think about it as “restructuring for the fourth time”, but rather as a learning experience. It’s obvious it’s not quite clicking for you just yet so it’s an investment in future skills. Once you get it, it’ll be trivial to do in the future. I have dozens of things that used to be really difficult that I can now type out in my sleep. For loops, basic vector math, and indeed modules - all were things that used to be tricky that now form the basis of all my games.
Give up if you want, but it doesn’t seem to me like a massively complex module so it should be relatively easy to fix. First step is figuring out why your get function still isn’t working. After that we figure out the dmg function.
If you post the most recent state of the module and explain what you’ve done, I’ll take a look again.
can’t believe I’ve been so stupid. I mean, at least i think that this is the main error. I didn’t change the message passing from the slime script, from when I was trying to do it without modules for some reason. is message passing to a module even possible though?
if message.group == hash("player") then
pprint("dectecting player interactions")
msg.post("slime#slime", "dmg")
pprint(msg)
go.delete("item")
end
also making this a local instead of self makes the module value the actual value instead of nil i think
local dmg = B.get(damage)
pprint("dmg is ", dmg)
```
if message.group == hash("player") then
pprint("dectecting player interactions")
msg.post("enimeises#dmg.lua", "dmg")
pprint(msg)
go.delete("item")
end
I’m not fully sure if I understand what you’re saying. is there a different syntax for message passing to a module or is it completely impossible and I’m just being stupid? code is from a script btw
Passing a message to a module doesn’t really exist as a concept. The module just stores information, such as variables or functions.
Take this example module:
local M = {}
function M.pos()
print(go.get_position())
end
return M
If you call M.pos() from a script attached to a game object, what you will get is the position of that game object. The module itself does not have a position. So, in the same way, if we have a module like this:
local M = {}
function M.handle_message()
print(msg.url())
--do stuff to handle an incoming message
end
return M
And call the function in the on_message function of a script:
function on_message(self, message_id, message, sender)
M.handle_message()
end
Then the output of the print() will be the url of the script that is receiving the message, not the module. Because the module doesn’t have a url.
You might be using a module because multiple scripts share similar behaviours. Or you are storing variables in the module, so handling the message using a module function might make more sense (you could modify a variable local to the module that way).
its so I can store a global value for the player’s current damage, so that it can be subtracted dynamically from enemy health. the message passing is so that it can increase and then decrease after being triggered since it’s supposed to be a limited time buff. I was trying the message passing because I didn’t know any other way to get a trigger targeting the module.
Okay, here is what I would do. It’s untested so you might run into some issues. The way you structured your timer was suboptimal so I cleaned it up, and you still include a “damage” parameter in your get function which is not necessary.
local B = {}
B.damage = 1
B.buff_timer_handle = nil
function B.buff_damage()
--reset active timers, if any
if B.buff_timer_handle then
timer.cancel(B.buff_timer_handle)
B.buff_timer_handle = nil
end
--buff the damage
B.damage = 2
--create a timer to reset the damage to normal
B.buff_timer_handle = timer.delay(10, false, function()
B.damage = 1
B.buff_timer_handle = nil
end)
end
function B.get_damage()
return B.damage
end
return B
Note that I’ve removed the message_id check because I think that is best done in the on_message function of your receiving script, like so:
function on_message(self, message_id, message, sender)
if message_id == hash("dmg") then
B.buff_damage()
end
end
This has the added benefit of making your buff_damage function more flexible - you can call it in other contexts, not just in a message.
just so you know, its not completely working but I probably won’t be doing more stuff on it for a little while. (one day at most) it’s nearly fixed and I need a little mental break. the error though is that when one of the functions is called health and damage end up with a nil value.
Fair enough. I’m fairly confident what I wrote works and it certainly shouldn’t let the damage variable become nil, so the issue is probably in some other part of your scripts that you haven’t posted.
WOW I did not mean to take that long of a break, downward spirals are really something huh. Wouldn’t be surprised actually if you’ve given up on this. Oh well, after messing around with my code I managed to get your system working, I can’t even remember what I was doing wrong. bruh. Anyway, the only thing I need to get the full system working is a way to get the message passing used to subtract the health to only trigger once.
There’s probably a way you’re supposed to do this without message passing, with a time to live thing, but I couldn’t seem to get it working.
if message.group == hash("bullet") then
if not message_id == hash("bk") then
msg.post("player#bullet", "death")
end
local damaged = true
--tiemr = 1
pprint("bullet collision")
if damaged == true then
pprint("health decreased")
self.health = self.health - dmg1
damaged = false
end
pprint("dmg is ", dmg1)
pprint("health is ",self.health)
end
end
The bullet hash gets called repeatedly due to the bullet being in constant contact to the slime, even repeats when telling the bullet to delete after touching the slime.
First things first - are you sure the bullet is actually being deleted? I would think that with message timing you might get a second damage message before the bullet is deleted, but if you are getting more than two hits then something is wrong.
this is what I have set up to handle bullet deletion.
slime script
if message.group == hash("bullet") then
if not message_id == hash("bk") then
msg.post("player#bullet", "death") <--
end
bullet script
if message_id == hash("death") then
msg.post("slime#slime", "bk")
go.delete() <--
end
I guess the message passing to handle the bullet death itself could be faulty, but I feel like it might be delayed or something so it doesn’t realise it’s deleted before triggering the collision again.
This looks strange. Why are you checking message_id inside the outer if then? At that point you probably already know the message type since you use message.group.
I would also like to point out that the use of not like that won’t do what you expect. Note that not will negate the value to the right of it and it has precedence over the equality check. What you want is either of these:
if not (foo == "bar") then
print("Foo is not equal to bar")
end
-- Check if something is not equal uses this: ~= (similar to != in other languages)
if foo ~= "bar" then
print("Foo is not equal to bar")
end
the second if statement is supposed to be a check to make sure that the slime object is alive, since the message will get continuously sent to an object that doesn’t exist otherwise.
function on_message(self, message_id, message, sender)
if message_id == hash("contact_point_response") then
go.delete()
end
if message_id == hash("death") then
msg.post("slime#slime", "bk") <--
go.delete()
end
end
it could cause a loop I guess, since it’s going back and forth