Cannot access on_message message table values (SOLVED)

I’m very confused right now. I’m able to receive messages through on_message. When I print my message variable it shows me the table with the data I sent. So far completely fine. But when I try to access a value from my message table it is always nil.

What I’m doing is this:

Script 1) posts a message to Script 2)
msg.post("go#hero", "set_move_direction", { move_direction = val } )

Script 2) receives the message through the on_message function

  function on_message(self, message_id, message, sender)

    if (message_id == hash("set_move_direction")) then
    	print("print message table")
    	pprint(message)
    	
    	print("print message.move_direction")
    	pprint(message.move_direction)
    	
    	move_direction = message.move_direction
    end
    
end

But when I access message.move_direction it’s nil!

DEBUG:SCRIPT: print message table
DEBUG:SCRIPT: 
{
   move_direction = -1,
}

DEBUG:SCRIPT: print message.move_direction
DEBUG:SCRIPT: nil

Could that be a bug in pprint? Try print:

print(message.move_direction)
1 Like

Unfortunately the variable really seems to be nil. Print results in nil as well. Using another name for my table variable instead of move_direction entry makes no difference, too. In other parts of the same project the message passing works fine!

Can you post the full script?

:worried: … what happens if you set move_direction to 1 before posting? Also try message[“move_direction”]
(None of these things should of course make a difference)

what happens if you set move_direction to 1 before posting?

same problem :frowning:

print(message["move_direction"])

results in nil too :frowning:

here is my full script.

inputController.script:

    local spriteClickDetection = require "input.spriteClickDetection"

function init(self)
	set_hero_move_direction(0)
	
    print("init() inputController")
    
    msg.post(".", "acquire_input_focus")
    
    -- Add controlPad to spriteClickDetection
    spriteClickDetection.add("ui_controlPad#ui_controlPad", vmath.vector3(0, 0, 0), on_controlPad_input)
    
end

function set_hero_move_direction(val)
	msg.post("go#hero", "set_move_direction", { move_direction = val } )
end

function on_input(self, action_id, action)

	   --- PC KEYBOARD

	   -- Left key released
	   if action_id == hash("move_left") and action.released then
	   	  set_hero_move_direction(0)
	   end
	   
	   -- Right key released
	   if action_id == hash("move_right") and action.released then
	   		set_hero_move_direction(0)
	   end

	   -- Right or left key pressed or repeated
       if action_id == hash("move_left") and (action.pressed or action.repeated) then
	         set_hero_move_direction(-1)
	   elseif action_id == hash("move_right") and (action.pressed or action.repeated) then
             set_hero_move_direction(1)
       end
       
       
       --- CLICK / TOUCH
       
       -- Check if control element sprite is clicked
       -- Will call handle_sprite_clicks, if yes
       if action_id == hash("click") or action_id == hash("touch") then
       		spriteClickDetection.on_input(action_id, action)
       end
       
end


-- Is called when spriteClickDetection detects a click
function on_controlPad_input(url, action_id, action)

	-- Click, just for easier debugging
	if action_id == hash("click") then
		if action.x < go.get_position("ui_controlPad#ui_controlPad").x then
			set_hero_move_direction(-1)
		else
			set_hero_move_direction(1)
		end
	end
	
	-- Touch
	if action_id == hash("touch") then
	
		if action.touch.released then
				set_hero_move_direction(0)
		end
	
		if action.touch.pressed then
			if action.touch.x < go.get_position("ui_controlPad#ui_controlPad").x then
				set_hero_move_direction(-1)
			else
				set_hero_move_direction(1)
			end
		end

	end
	
end

hero.script

    local move_direction = 0
local speed = 5
local camera_should_follow_hero = true
local camera_id = "camera#cameraController"

-- Updates heros
function update(self, dt)

	if camera_should_follow_hero then
		update_camera_position()
	end
	
end

function update_camera_position()

	-- print(move_direction)
	    
    if (move_direction == 1 or move_direction == -1) then
    	 -- Get current camera position
    	 local pos = go.get_position(cameraID)
    	 pos.x = pos.x+speed*move_direction
    	 msg.post(camera_id, "set_camera_position", { pos = pos })
    end
    
end

function on_message(self, message_id, message, sender)

    if (message_id == hash("set_move_direction")) then
    	print("print message table")
    	pprint(message)
    	
    	print("print message.move_direction")
    	print(message.move_direction)
    	print(message["move_direction"])
    	
    	move_direction = message.move_direction
    end
    
end

function on_input(self, action_id, action)
    -- Add input-handling code here
    -- Remove this function if not needed
end

function on_reload(self)
    -- Add reload-handling code here
    -- Remove this function if not needed
end

If it helps I can share my whole project with you.

You are not declaring this function as local (ie prefixing it with the local keyword). Could it be that you have it defined in multiple places and the wrong version of the function is invoked?

You really should make a habit out of using local variables (and thereby also local functions). There is a huge risk that you are either overwriting values or redeclaring functions unless they are local. A lot of unforeseen consequences can come out of only using global functions and variables (not that they might not be of some use in rare cases).

The same thing should obviously also apply to this functions (Especially this function as it has a more generic name and might be declared somewhere else as well).

1 Like

Thanks britzl, I wasn’t aware that the function names should be local (I thought otherwise there must be already an error cause every script has update() etc.). I made the functions local but my problem still occurs :frowning:

Can you share the project with me? My email is mikael@sicher.org

M

Yes sure, I added you to my team. You can provoke the mentioned debug statements when you run the game and click the control pad (the black circle) on the bottom left corner.

Thanks…

Wow, this was a nasty one! It’s a really simple error but was very hard to spot. Here’s what’s going on:

Lua allows unicode identifiers so you can have variables like this if you want:

function init(self)
    msg.post("#", "test", { 😀 = "happy" })
end

function on_message(self, message_id, message, sender)
    pprint(message)
    pprint(message.😀)
end

Running this results in:

DEBUG:SCRIPT: 
{
  😀 = happy,
}

DEBUG:SCRIPT: happy

Now, the unicode set includes a character that is pretty easy to type by mistake, a non breaking space. It is entered with Alt+SPACE. Turning on “show whitespace characters” in the editor makes the culprit in your code visible:

Notice that there is no grey dot between the ‘{’ and ‘m’. The non breaking character you have inserted by mistake there becomes part of the identifier so the table member’s name is not ‘move_direction’ but ’ move_direction’, with the initial non breaking space unicode character. Just remove it and enter a regular space and you’re good to go.

Note: this is really stupid and easy to make by mistake. We will look at some way to capture or highlight these things.

8 Likes