Uncaught TypeError: AudioParam.value setter error in Web build.
Tested versions
Error occurs in v4.3.beta3.official [82cedc83c] Error did not occur in 4.3.beta2
System information
Godot v4.3.beta3 - Windows 10.0.19045 - GLES3 (Compatibility) - NVIDIA GeForce RTX 3080 (NVIDIA; 31.0.15.3623) - 12th Gen Intel(R) Core(TM) i9-12900KF (24 Threads)
Issue description
When playing the game on a web browser (such as itch.io), sometimes playing different audio causes this error. I don't really have a reliable way to reproduce this and I know this is super vague, but I wanted to bring it up regardless as this did not happen in 4.3beta2, but does happen in 4.3beta3.
The error in full is as thus:
Blocking on the main thread is very dangerous, see
Steps to reproduce
N/A
Minimal reproduction project (MRP)
N/A
Please confirm with rc1, a lot of web related issues were fixed since beta3
Is this just a warning or error popping up? Does it affect anything? Is audio working correctly otherwise?
Is this just a warning or error popping up? Does it affect anything? Is audio working correctly otherwise?
It crashes the game. I apologize in advance for being so difficult on my explanations and helping figure this all out, I genuinely am not sure precisely what causes it so I don't know where to begin with an MRP, but I can confirm that reverting back to beta1 (wasn't beta2, my mistake) has everything work just fine.
Here's the error in full when the crash occurs. The crash occurs when the game is fading out volume, loading up a new song, then fading volume back in, basically just a music transition.
https://imgur.com/CLVAkmN
Let me know what else I can do to help figure this out.
EDIT: And by crash, I mean the game freezes. I'm assuming that's the same thing, but wanted to throw it out there just in case.
I also just tried rc1, no change unfortunately. This error is on rc1, in fact.
Oh yeah it crashing is very different from what you said in your description, important detail to mention at first
Edit: freezing is not crashing, though I guess it depends on web
Are you putting the audio source very very far away? Or is it assigned an invalid transform? For example setting some scale to 0? Or is the audio listener right on top of the audio source?
CC @adamscott
For sake of thoroughness (though I apologize if it's a lot of unnecessary info), this is what I'm doing roughly when it occurs.
I'm setting music like this:
var event_music = events.event_music["discovery"]
func _ready():
helpers.play_event_music(event_music)
Where "events" is an AutoLoad and "events.event_music" is a dict of preloads, like this:
var event_music = {
"discovery" = preload("res://Music/EventDiscovery.ogg"),
Where "helpers" is an AutoLoad and in the "helpers" func that's called, it does this:
func play_event_music(song):
event_song = song
Inside "helpers", there's this:
func _process(_delta):
if event_song != null:
music.set_volume()
sfx.set_volume()
if global.event_volume_mult > 0.0:
global.event_volume_mult -= 0.01
else:
global.event_volume_mult = 0.0
if !event_song_played:
music.play_event(event_song)
event_song_played = true
else:
music.set_volume()
sfx.set_volume()
if global.event_volume_mult < 1.0:
global.event_volume_mult += 0.01
else:
global.event_volume_mult = 1.0
if event_song_played:
music.stop_event()
event_song_played = false
If I had to guess, this is where the problem is. I'm sure my method for handling this isn't ideal, but none-the-less it did work before and now does not. When a song is stopped, I'm just setting "event_song" back to null.
I have a "music" AutoLoad arranged like this:
https://imgur.com/6gjWNzS
...which in the "music" script, is instantiated like this:
@onready var event_music_audio_player: AudioStreamPlayer = %EventMusicAudioPlayer
func _ready():
set_volume()
func set_volume():
var master_volume = global.settings["master_volume"]
var music_volume = global.settings["music_volume"]
var volume = ((master_volume * music_volume) / global.volume_division) * global.event_volume_mult
var event_volume = ((master_volume * music_volume) / global.volume_division) * (1.0-global.event_volume_mult)
if !global.game_in_focus and global.settings["mute_music_unfocused"]:
volume = 0.0
event_volume = 0.0
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Music"), linear_to_db(volume))
AudioServer.set_bus_volume_db(AudioServer.get_bus_index("EventMusic"), linear_to_db(event_volume))
Again I'm sorry if I'm wasting your time with a bunch of nonsense, just trying to help narrow what this could be for you.
I apparently don't know how to do proper code blocks on GitHub either, but I'm hoping you can make sense of where I was trying to do them.
Can't see anything obviously wrong with this, so we'll see what the web team might find
Have you made sure the volume and event_volume values are finite? That global.volume_division is not zero?
Have you made sure the
volumeandevent_volumevalues are finite? Thatglobal.volume_divisionis not zero?
I don't actually know what them being finite means. They're reset to 0.0 if below 0 and 1.0 if above 1. global.volume_division is:
var volume_division: int = 4
Finite means not inf, which can happen if volume_division is 0, or similar, try checking with is_finite just to confirm
Finite means not
inf, which can happen ifvolume_divisionis0, or similar, try checking withis_finitejust to confirm
Sorry for the delay. volume_division may as well be a const as it's never changed anywhere. I double-checked my code to confirm this and ran print statements, it's initialized at 4 and remains 4 at all times. It is finite.
~Meant to check what volume and event_volume are, are they also finite?~
Also realized what is wrong, it's quite simple:
if !global.game_in_focus and global.settings["mute_music_unfocused"]:
volume = 0.0
event_volume = 0.0
This part will break things, as linear_to_db will return -inf when fed with 0.0
This is the issue I'm almost certain, please confirm
This part should be documented, as it's not given in linear_to_db
However the freeze remains, which should be fixed, but it shouldn't happen if valid values are input, so this is far less critical assuming the above assumption is correct
Generally weird and bad things happen when you pass non-finite stuff around, and not sure how to approach this, will write up a documentation improvement to linear_to_db to clarify that 0 results in potentially bad output
We could sanitize non-finites as well, will look into where and how to do that, and see where the regression might have occured here, might be a check that got lost somewhere
But generally we should be able to rely on users not feeding bad values into the output, but will test this on my end to see how it presents (how the freeze behaves, if it is a full freeze or just audio breaking, setting the audio to -inf will probably silence everything else as well)
Will try doing some investigations today
Edit: this might be more of a web side error with finite value handling not being correct, but the assignment should be finite as it is processed with db_to_linear, will see if I can't pin down what's wrong and see if it's just a web side issue
After some testing I think I've pinned this down to user error
You have provided a negative value to linear_to_db which yields NaN, this is likely because this check:
if global.event_volume_mult > 0.0:
global.event_volume_mult -= 0.01
If global.event_volume_mult is less than 0.01 it will become negative, which will cause problems, or:
if global.event_volume_mult < 1.0:
global.event_volume_mult += 0.01
If global.event_volume_mult is greater than 0.99, it will become greater than 1 and 1.0-global.event_volume_mult will become negative
So while we should probably investigate how to improve this this is a case of user error, my bad for the false hint of the linear_to_db(0.0)
So not marking this as critical as it doesn't happen with properly handled input and we can work out how to fix this down the line
To ensure this works you should instead check if the value is greater than 1.0 or less than 0.0 and update the value to 1.0 or 0.0 to ensure it has a valid range
Leaving open for further discussion on how to resolve the rest, but not considering this critical for 4.3 as it is avoidable with proper value safety
Will see about writing up a temporary fix maybe to handle invalid values being passed, or catching the error, but not sure if it should be done directly
Edit: Also the reason this fails for you and yields a negative input is because of floating point error, performing foo -= 0.01 a hundred times after initializing foo to 1.0 is not going to yield 0.0 due to small rounding errors due to 0.01 not being possible to represent exactly in binary
Will write up a quick fix by adding a try/catch handling the error and just not updating anything, should be safe enough and prevent any errors
Edit: Done, added a try/catch to handle it gracefully, now the volume is just ignored with a message if it is an invalid input
I apparently don't know how to do proper code blocks on GitHub either, but I'm hoping you can make sense of where I was trying to do them.
You can add syntax highlighting by adding gdscript to the code block:
```gdscript
<Your code here>
```
To clarify separately from my wall of text why I classify this as non-critical: While it blocks running web exports it only happens with invalid code, which should still work gracefully but IMO isn't critical as long as the code is working generally
@TheFoxKnocks Next time, please join an MRP to the issue.
@TheFoxKnocks Next time, please join an MRP to the issue.
Thanks for the help! As stated in my original post, there's a reason why I was unable to do this. I can't make an MRP of something where I'm not particularly sure what the problem is exactly.
Either way, a try/catch is a good solution and it seems like my issue isn't a bug, more that something that simply happened to work in a previous beta and with updates now no longer works. I'll adjust my code accordingly.