Prevent sending of "sound_done" message?

Hello,

when playing a sound, as I understand it, Defold notifies the initiating gameobject when the playing is done by a) calling an optional callback funtion and b) sending a “sound_done” message:

sound.play( url, props, function( self, message_id, message, sender )
	-- sound has ended.... do things
end )

Often, I have the case that an initiating object does not need this information. In fact, when I have e.g. a bullet gameobject initiating a sound on impacting its target, the bullet has already been deleted when the sound is done playing. In that case, I get an error message which I would like to avoid:

ERROR:GAMEOBJECT: Instance '/instance12' could not be found when dispatching message 'sound_done' sent from playground:/instance12#sound

I would have thought that just the fact of providing a callback function would already prevent that message sending? After all, such a function will always take care of any action required upon the sound ending and an additional message being passed seems useless - but apparently, the “sound_done” is always sent?

Is there a way when playing sounds to prevent Defold from sending “sound_done” when I do not need / want it?

Do you have a repro for this? I’m not sure I understand your setup. we only send that message when you have supplied a callback

3 Likes

The callback function is still tied to a script+gameobject.
During setup of the callback, we get the gameobject instance but if it’s been deleted, then it’s not much to do.

I do think that the error message is not very useful in this case, and perhaps we could check for this circumstance.

1 Like

Thanks for your very quick responses!

Ok, yes, then my problem is indeed that as the gameobject no longer lives, neither does the callback function.

Well, I would be happy if you decided to check for the existence of the gameobject before sending the “sound_done” and prevented the error message. There is actually nothing the game code can do to remedy the “error” and at least to me, it is just a common (edge) case.

One way or the other - thanks for explaining to both of you!

Might I ask you if the game object you delete has the script attached?

Hi raetia,

yes, that is the problem: I could just play the sound without providing a callback function and that would actually work. Without a callback, no “sound_done” message would be sent, no error message generated.

However, it is a bit more complicated:

To play sounds, I use a library that takes care of other tasks such as orchestrating and ommitting sound instances when (too) many want to get played at the same time. That module always provides its own callback to sound.play() to do its housekeeping. So even when, as in this bullet/explosion example, the bullet does not need a callback function to execute custom game code, the library still does, and so produces an error message.

2 Likes

One solution is to not play the sound from a script attached to a short lived game object. Having a central sound manager which plays sounds is a pretty good design. Also, if the only purpose of the bullet script was to play sounds then you’d now have the opportunity to remove it if you move the responsibility to a central sound manager.

2 Likes

This is what I found yesterday too in a minute test project:

Error message with script attached to the object that is then removed:

Script detached from the object that is removed, callback function runs:

A central sound manager is what we use in our games. It has many benefits. For example, it makes it easier to implement features such as sound gating / not playing sound samples too often.

4 Likes

yes, good point - thanks for the suggestion.
I will look into it.

1 Like