Msg.post doesn't appear to be working (SOLVED)

Hi, I’m essentially trying to make a sprite invisible (that code works fine), or even just disable it (idk if that’s possible) when the user clicks a button on a character selection screen. The sprite is within the first level collection which uses a tilemap.
This code is on the sending half:

			msg.post("main:/controller", "load level 1")
function on_message(self, message_id, message)
	if message_id == hash("proxy_loaded") then
		if character == "male" then
			msg.post("girlpl:/controller", hash("set female invisible"))
		elseif character == "female" then 
			msg.post("boypl:/controller", hash("set male invisible"))
		end
		
		if maledisable == true then
			msg.post("girlpl:/controller", hash("reset female to visible"))
		elseif femaledisable == true then
			msg.post("boypl:/controller", hash("reset male to visible"))

		end
	end
end

And this is an example of the receiving half for one of sprite scripts (they use the same code and both don’t work)

function on_message(self, message_id, message, sender)
	if message_id == hash("set male invisible") then
		go.set("#boyplayer", "tint", vmath.vector4(0, 0, 0, 0))
	elseif message_id == hash("reset male to visible") then
		go.set("#boylayer", "tint", vmath.vector4(1, 1, 1, 1))

	end
end

Any advice is sincerely appreciated

Can you verify that you get a message and handle it correctly? Set a break point using the debugger or print() something.

Also, I would recommend that you enable and disable the sprite instead:

msg.post("#boylayer", "enable")
msg.post("#boylayer", "disable")

I changed the sprite code like you said and added some debug points - the first one being

function on_message(self, message_id, message)
	if message_id == hash("proxy_loaded") then
		print("it is loaded")

which didn’t print anything, I’m not really sure why. (this is right before it sends the msg.post()s)

In you rfirst post, you have the “msg.post” outsize of the lifecycle functions.
That won’t work, So perhaps it part of the problem, that the message is never sent?

Sorry I should’ve made it a bit clearer, that line of code was on the very end of the previous on_input function, I just included it there so people could see what I used incase there was something wrong with it.

Well, you are probably not loading the collection proxy correctly. Can you show how you are loading the collection?

Also please check that you don’t have any errors in the console in the editor.

Hi, this is how I’m loading it.

in the character selection script:

		if action.pressed and gui.pick_node(gui.get_node("button_play2"), action.x, action.y) then
			--check if the player has pressed the button_play2 node button
			msg.post("main:/controller", "load level 1")
			

and then in main script:

elseif message_id == hash("load level 1") then
	-- level 1 game starting
	msg.post(self.current_collection, "unload")
	msg.post("#level1_proxy", "load")
	self.current_collection = "level1_proxy"

You need to print() debug every step of the way to figure out where things fall down. Is input being detected at all, if yes is the button being clicked, if yes is any message received (if so what’s the id), etc…

1 Like

Everything works and prints as intended prior to the first print issue that I showed above. I’m not sure if I’m missing something or what - I’m pretty new to defold

1 Like

Can you share the project as a zip file here please?

1 Like

Here’s a google dropbox link.
https://www.dropbox.com/scl/fo/y0gp7ghd2ly1o760ufyyd/AFrxcUIAQMRoMy3O9nl5yTw?rlkey=zmgx55nxf0z19nfqimdqfx1gd&st=f8gf0jjv&dl=0

I had a look at your project:

  • You have a main.collection with a main.script which acts as a controller to load and unload screens and levels. This is a good practice!
  • From the main.collection you load a character select screen with a character.gui_script
  • When the player has selected male or female and press Play you send a message from character.gui_script back to main.collection to load the first level.

The problem is that you expect the “proxy_loaded” message to be sent to character.gui_script. This will not happen since it is the main.script which loads level1.collection.

One solution would be to store the character selection choice in a Lua module. Use this information in level1.collection to disable one of the player characters.

-- settings.lua
local M = {}
M.gender = "male"
return M
-- character.gui_script
local settings = require("settings")

function on_input(self, action_id, action)

   if gui.pick_node(...) then
       settings.gender = "male"
--- boypl.script
local settings = require("settings")

function init(self)
    -- delete if male is not selected (do same in girlpl.script)
    if not settings.gender == "male" then
      go.delete()
   end
end

Another option would be to send the selected character from character.gui_script back to main.script in the load level 1 message use it there instead.

2 Likes

Thank you, I’ve implemented what you’ve said, but it comes up with the error that the file settings.lua cannot be found. Also silly question maybe, but what would it look like when I want to do the settings.lua code for the female part? I assume I’d change M for F and “male” for “female”

Did you do New → Lua Module and created a settings.lua in the root of your project?

No, not exactly. A Lua module is usually a Lua table with data and/or functions. It is typically named M. Read about it here: Lua modules in Defold

So in your character.gui_script you do:

local settings = require("settings")

...

settings.gender = "male"
--OR
settings.gender = "female"

And from other places you check the gender as I showed previously:

local settings = require("settings")

if settings.gender == "female" then
   print("I'm female")
elseif settings.gender == "male" then
   print("I'm male")
end
1 Like

Thanks for the explanation!
I’m pretty sure I did exactly that for the lua module, I attached a screenshot.

That doesn’t look to be the project root I think (which is where .gitattributes is). Is it in a folder?

In which case you do

local settings = require "foldername.settings"

Sorry, I’m an idiot lol. Still doesn’t seem to work though… I’m at an absolute loss on how I’ve messed it up. I did a print statement:
local Lsettings = require “main.Lsettings”

function init(self)
	msg.post("#", "acquire_input_focus")
	print("test")
	
	if not Lsettings.gender == "female" then
		print("its a boy!")
		go.delete()
	end
end

The first print test works, but the second does not. I did the exact same in the lua file as you said so I’m unsure as to why nothing is being returned.

Print Lsettings.gender and check the value!

1 Like

I changed

if not Lsettings.gender == "female" then

to be

if Lsettings.gender == "male" then

and vice versa for the malepl script.
It works now! Thanks so much for your help :slight_smile: