Maaack / Godot-Game-Template

Godot template with a main menu, options menus, pause menu, credits, scene loader, extra tools, and an example game scene.
MIT License
380 stars 22 forks source link

Changing bus volume in option menu "erase" the default bus volume. #124

Closed DinoMC closed 1 month ago

DinoMC commented 2 months ago

Hi, I think I found a bug with the way volume is handled. Once you touch the slider for a bus in the Audio Options menu, the default value for the bus seems to be erased :

Instead I think 100% volume (in audio option) should be the value set in the Editor, and then go down from that if lowered. Edit : Or convert the bus default volume to a % and set the slider to start at that % rather than 100%, so that when you move it the volume doesn't suddenly jump. Not sure if that'd work for default volume above 0db tho. Would require lowering all other sliders and raising the "overall" volume to compensate, not sure if there's a function for that.

cmr624 commented 1 month ago

Hi there @DinoMC what godot version did you use to test this?

DinoMC commented 1 month ago

Pretty sure this was 4.2.2 stable. Just tried again with 4.3.beta3 and the issue is still there.

Looking at the code, it seems to me like it's not implemented, so issue should be the same in all Godot versions :

DinoMC commented 1 month ago

I was trying to make a pull request to fix this but I'm not sure how to go about a specific part, so instead here's some code, I hope it can help you.

For AppSettings.set_audio_from_config(), I think it can be fixed like this. I tried running a few test cases and it all seemed to work :

static func set_audio_from_config():
    for bus_iter in AudioServer.bus_count:
        var bus_name : String = AudioServer.get_bus_name(bus_iter).to_pascal_case()
        var bus_volume_db : float = AudioServer.get_bus_volume_db(bus_iter)
        var base_bus_volume : float = db_to_linear(bus_volume_db)
        var bus_volume : float
        bus_volume = Config.get_config(AUDIO_SECTION, bus_name, bus_volume)
        if is_nan(bus_volume):
            bus_volume = 1.0
            Config.set_config(AUDIO_SECTION, bus_name, bus_volume)
        bus_volume_db = linear_to_db(base_bus_volume * bus_volume)
        AudioServer.set_bus_volume_db(bus_iter, bus_volume_db)
    var mute_audio_flag : bool = is_muted()
    mute_audio_flag = Config.get_config(AUDIO_SECTION, MUTE_SETTING, mute_audio_flag)
    set_mute(mute_audio_flag)

Basically, multiply the new value by the default value (works well since it's linear values). So if the user set the slider to 80%, but the bus default value is already 0.8, then the final value will be 0.64.

Problem is once the config is done loading, it seems like the bus default volume is just gone, it's not saved anywhere. So when the user then move the slider again in the Audio menu, you don't have anything to multiply it with.

Possible fixes :

Vaguely related, but I would also suggest another small change. Right now, when starting the game for the first time, all sliders are at 100%, meaning that the user can lower the volume if the default is too high, but can't raise it if it's too low. This could be easily fixed by changing the HSlider.max_value to 1.5 rather than 1.0

Maaack commented 1 month ago

Thanks for the detailed bug report and suggested fix! I'll try working on it this week.