Gui.set_position not working in release build (SOLVED)

I have a timer script that posts this progress to a gui_script.
The gui script then updates the position of a gui Box.

This works fine in debug build, but does not work for release builds (tried both web and mac builds).

Timer.script:

function update(self, dt)
    if progress == 1 then stop(self) end
    if running then
        progress = progress + (1 / self.durationInSeconds) * dt
        if progress > 1 then progress = 1 end
        msg.post('/gui#gui', TimerHashes.progress,  {progress = progress})
    end
end

gui.gui_script:

local function onProgress(progress)
    gui.set_position(progressBar, vmath.vector3(0, 1, 0) * height * progress)
end

function on_message(self, message_id, message, sender)
    if message_id == TimerHashes.progress then onProgress(message.progress) end
end

The above code is obviously not the complete code ;), but just the relevant parts.

In the release build the position of the gui node is not updated, but in a debug build it is working just fine.

I’m wondering what is the difference between the debug and the release build that could be at the hart of this problem…

So at first it seems strange to me that it works fine in debug mode.
Missing message id in timer.script for msg.post call. So it should look something like this:

msg.post('/gui#gui', TimerHashes.progress, {progress = progress})

Ah, sorry my mistake, I simplified the code a bit for the question and forgot to put the hash in there.
The original code in my project has the hash. Thanks for pointing out the mistake!
I edited my original post.

It is not clear from these code snippets where the error is. I suggest you put together a little sample program that points out the bug and upload it here.

1 Like

Ok I seem to have found the culprit.

When putting together a small sample programm as suggested by coderm4ster, everything just worked as expected… So the above code sample just works as well :roll_eyes:

The problem was in the Messenger “class” I was using, the Messenger allows you to subscript to it by posting a ‘subscribe’ message. When the Messenger posts a message it is posted to all scripts that subscribed to it. Appearenly the Messenger works flawlessly in debug b builds not in release builds.

The Messenger:

local MessengerHashes = require('Messenger.Hashes')

local Messenger = {}
local Prototype = {}

local function subscribe(self, receiver)
	self._receivers[tostring(receiver)] = receiver
end

local function unsubscribe(self, receiver)
	self._receivers[tostring(receiver)] = nil
end

function Messenger:new()
	local messenger = {
		_receivers = {}
	}
	setmetatable(messenger, {__index = Prototype})
	return messenger
end

function Prototype:post(message_id, message)
	if type(message) == 'table' then
		for key, receiver in pairs(self._receivers) do msg.post(receiver, message_id, message) end
	else
		for key, receiver in pairs(self._receivers) do msg.post(receiver, message_id) end
	end
end

function Prototype:on_message(message_id, message, sender)
	if message_id == MessengerHashes.subscribe then subscribe(self, sender) end
	if message_id == MessengerHashes.unsubscribe then unsubscribe(self, sender) end
end

return Messenger

I just removed the Messenger for now and everything is working as it should, I’m still puzzeled why this would work in debug and not in release builds…

If I have to guess, it’s related to the fact that in release builds we don’t have access to the debug strings (the string representation of a hash/id/url)

So, you implementation shouldn’t rely on those constructs.

Thx Mathias, this is very usefull information and would definitely explain why this code would not work in release builds. I guess I need to rethink my implementation :slight_smile:

You can use IDs (also accessible as the “path” property of a URL) as keys, since they are just hashes. The drawback there is they only refer to the game object, not the component, and they may overlap between multiple collection proxies.

Or, instead of trying to use URLs as table keys, you can just put them in as a sequence ({url1, url2, url3, ...}). Then you can use ipairs to iterate, and the only drawback is your unsubscribe function has to search the list.

1 Like

Convert the URLs to strings, perhaps using hash_to_hex():

local key = hash_to_hex(receiver.socket) .. hash_to_hex(receiver.path) ..  hash_to_hex(receiver.fragment)

Thx ross and britzl for the suggestions! I’ll try them out.