Page 1 of 1

Confused trying to manage ambient sounds / save games

Posted: Tue Oct 09, 2018 3:02 pm
by Gambit37
I have a small function that starts/stops ambient sounds for each level the player enters:

Code: Select all

sound_ambience_handle = -1

ambience_table = {
	level1_amb = "amb_low_wind", level1_vol = 50,
	level2_amb = "amb_dungeon_wind_drips", level2_vol = 30,
	[... etc ...]
}

function level_ambience(level)
	local level_amb = "level" .. level .. "_amb"
	local level_vol = "level" .. level .. "_vol"
	if (sound_ambience_handle > -1) then
		dsb_stopsound(sound_ambience_handle)
	end
	sound_ambience_handle = dsb_sound(snd[ambience_table[level_amb]], true)
	dsb_set_soundvol(sound_ambience_handle, ambience_table[level_vol])
end
I then call this function within the reserved function sys_enter_level:

Code: Select all

function sys_enter_level(level)
	level_ambience(level + 1)
end
This basically works fine, but I seem to get into an incredible mess when saving / restoring a game:

DSB seems to continue playing whatever ambient sound it was playing when it was saved. This means that I get multiple sound streams playing together, because the sys_enter_level function is run upon a save game reload, and plays another sound on top of what was playing when it was saved.

This seems to be because the sound_ambience_handle was lost when reloading.

I tried saving the sound handle in an exported variable, so that the sound channel is retained between saves/reloads, but this doesn't seem to work reliably.

Code: Select all

dsb_export("save_data")
save_data = {
   sound_ambience_handle
}
I think the problem is related to where sound_ambience_handle is initialised. I think it's being reset and therefore the exported value never gets read? I don't really understand how to get around that?

How should I construct this so that I can reliably manage the ambience across both level changes and saves/reloads?

Re: Confused trying to manage ambient sounds / save games

Posted: Wed Oct 10, 2018 7:42 pm
by Sophia
You are correct that the problem is that sound_ambience_handle is never saved, and that's because you never actually exported it. You exported a table called save_data that the current global variable sound_ambience_handle is not actually part of.

Try changing your dsb_export line to

Code: Select all

dsb_export("sound_ambience_handle")
Although it might be better in the long run (if you plan on having a lot of saved variables) to keep the export the way you have it now and instead change sound_ambience_handle to save_data.sound_ambience_handle in your other code.

As an aside, you can nest tables, which makes your whole ambience structure a bit cleaner and more elegant.

Code: Select all

ambience_table = {
   1 = { amb = "amb_low_wind", vol = 50 },
   2 = { amb = "amb_dungeon_wind_drips", vol = 30},
   -- whatever
}
Then you can just do

Code: Select all

dsb_sound(snd[ambience_table[level+1].amb], true)

Re: Confused trying to manage ambient sounds / save games

Posted: Wed Oct 10, 2018 11:45 pm
by Gambit37
Hmm, OK, weird, I tried it your way too by using save_data.sound_ambience_handle in my code, and that didn't work either.

I think I'm missing a conceptual understanding of what actually happens with exported data? How and where does it "return" into my code when loading a save game? Is the order of the export code and initialisation of the original variables important?

I guess I just don't really understand how to use dsb_export? Should it be defined once globally, or called every time I need to ensure a variable gets saved?

Please can you give a code example of a working approach to dsb_export? Because I just don't get this at all. :?

As for the sound handle, maybe it would be easier to have a stop_all_sounds() function that I can call in sys_enter_level, rather than having to mess about with sound handles anyway? Of course, that comes with it's own problems (for example, what if the party is screaming as they fall down multiple pits and entering/exiting many levels in quick succession...)

Re: Confused trying to manage ambient sounds / save games

Posted: Thu Oct 11, 2018 6:01 am
by Sophia
You can see some variables that are exported in base/startup.lua. It's a bunch of individual variables rather than a global variable table (which is a better way of doing it) because early versions of DSB didn't support exported tables... but it's enough that you can still get the idea.

As for how it works conceptually, inside of DSB there's a chunk of memory called the Lua State, which contains everything having to do Lua: all of the code, variables, and whatever. When you dsb_export a variable name, it adds that variable name to an internal list. Then, when you save the game, every variable that is on that list has its value pulled out of the Lua State and saved in the save game. Conversely, when you load a save game, it reads the values of all of the variables that are exported in that savefile and pushes them back into the Lua State. Since all dsb_export actually does is just add the variable's name to a list of variables to be pulled out of the Lua State and saved when you save the game, it only needs to run once globally for each variable, ideally at startup.

As it happens, the exact same code is used to save the exvar table, so I guess that's the most complex example of an "export," though it's always automatically done and thus doesn't actually need a dsb_export.

Re: Confused trying to manage ambient sounds / save games

Posted: Thu Oct 11, 2018 9:11 am
by Gambit37
OK, great thanks, I'll check that stuff out and try to unpick the mess I've created! :-D