Last updated: 13 Jun 24 14:15:03 (UTC)

Toggle sound on/off on all passages

…without using Settings

(I used this in conjunction with a Mouseover Macro for playing audio.)

In a passage titled “StoryInit” (title is important here - StoryInit is a special passage that Sugarcube 2 loads at the start of the game AND every time the page is refreshed), cache and label the audio files:

<<silently>>
<<cacheaudio "pron" "audio/pronunciation.mp3">>
<<cacheaudio "dete" "audio/deterioration.mp3">>
<</silently>>
<<silently>>
<<cacheaudio "pron" "audio/pronunciation.mp3">>
<<cacheaudio "dete" "audio/deterioration.mp3">>
<</silently>>

This step is important!!! This loads and labels the audio files FIRST thing, AND on any page refresh. So if the user refreshes the page, all the audio links won’t be broken the way they would be if you loaded them in a passage, like the start passage.

In first/title passage:

/% create a variable for audio and set it to on %/
<<set $Audio to true>>
/% create a variable for audio and set it to on %/
<<set $Audio to true>>

Create a “PassageHeader” (or footer) passage:

/% link to toggle sound on or off %/

/* This FIRST "if" condition places the ON speaker (or unmuted message) on the passage when it loads */

<<if $Audio is true>>
<<link '<span id="mute">Mute Audio</span>'>>
    <<if $Audio is true>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <<else>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <</if>>
<</link>>

/* This SECOND "if" condition places the OFF speaker (or muted message) on the passage when it loads */

<<elseif $Audio is false>>
<<masteraudio mute>>
<<link '<span id="mute">Unmute Audio</span>'>>
    <<if $Audio is false>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <<else>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <</if>>
<</link>>
<</if>>
/% link to toggle sound on or off %/

/* This FIRST "if" condition places the ON speaker (or unmuted message) on the passage when it loads */

<<if $Audio is true>>
<<link '<span id="mute">Mute Audio</span>'>>
    <<if $Audio is true>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <<else>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <</if>>
<</link>>

/* This SECOND "if" condition places the OFF speaker (or muted message) on the passage when it loads */

<<elseif $Audio is false>>
<<masteraudio mute>>
<<link '<span id="mute">Unmute Audio</span>'>>
    <<if $Audio is false>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <<else>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <</if>>
<</link>>
<</if>>

Note the “<<masteraudio mute>>” in the first line of the SECOND if condition. Not having this will BREAK the toggle switch if the user refreshes the page while $Audio is set to false(mute). Refreshing keeps the variables and the “speaker off/mute” setting, but it UNDOES all the audio, meaning it unmutes the audio. You don’t need anything in the FIRST if condition because it already aligns with the default setting that would exist if the user refreshed the page while $Audio is set to true(not mute).

I used a couple of images instead of text, so above, wherever it says “Mute Audio” or “Unmute Audio”, I put:

<img src=“speakeron.png” />
<img src=“speakeroff.png” />
<img src=“speakeron.png” />
<img src=“speakeroff.png” />

If you don’t want it to appear on certain passages, tag those passages with “nofooter” (or whatever) and wrap the above with:

<<if not tags().includes("nofooter")>>
PASSAGEHEADER/FOOTER CONTENT
<</if>>
<<if not tags().includes("nofooter")>>
PASSAGEHEADER/FOOTER CONTENT
<</if>>

Then to style, I wrapped the whole thing in a div in the passage:

<div class="header">
CONTENT
</div>
<div class="header">
CONTENT
</div>

… and in CSS, to place the little speaker in the top right corner:

.header img {
    position: fixed;
    top: 10px;
    right: 15px;
    max-width: 2.5%;
}
.header img {
    position: fixed;
    top: 10px;
    right: 15px;
    max-width: 2.5%;
}

OLD VERSION:

What was wrong with it: I discovered that if the player refreshes the page mid-game, it breaks the audio entirely. And then when I fixed that (by moving the audio caching to a StoryInit passage), it broke the mute toggle. The reason it broke the mute toggle was mysterious, as there seemed no rhyme or reason to it initially. It wasn’t that it broke the variable or the toggle link; it was that if the passage had LOADED the $Audio variable as “false” (so, the audio was muted), it would load the SECOND link in the header - the “muted” image. BUT the audio was reset to normal, unmuted! It drove me nuts. So don’t do it the way below. Do it as above.

In first/title passage:

/% create a variable for audio and set it to on %/
<<set $Audio to true>>
/% create a variable for audio and set it to on %/
<<set $Audio to true>>

Create a “PassageHeader” (or footer) passage:

/% link to toggle sound on or off %/
<<if $Audio is true>>
<<link '<span id="mute">Mute Audio</span>'>>
    <<if $Audio>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <<else>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <</if>>
<</link>>
<<else>>
<<link '<span id="mute">Unmute Audio</span>'>>
    <<if $Audio is false>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <<else>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <</if>>
<</link>>
<</if>>
/% link to toggle sound on or off %/
<<if $Audio is true>>
<<link '<span id="mute">Mute Audio</span>'>>
    <<if $Audio>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <<else>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <</if>>
<</link>>
<<else>>
<<link '<span id="mute">Unmute Audio</span>'>>
    <<if $Audio is false>>
        <<masteraudio unmute>>
        <<set $Audio to true>>
        <<replace '#mute'>>Mute Audio<</replace>>
    <<else>>
        <<masteraudio mute>>
        <<set $Audio to false>>
        <<replace '#mute'>>Unmute Audio<</replace>>
    <</if>>
<</link>>
<</if>>

I used a couple of images instead of text, so above, wherever it says “Mute Audio” or “Unmute Audio”, I put:

<img src=“speakeron.png” />
<img src=“speakeroff.png” />
<img src=“speakeron.png” />
<img src=“speakeroff.png” />

If you don’t want it to appear on certain passages, tag those passages with “nofooter” (or whatever) and wrap the above with:

<<if not tags().includes("nofooter")>>\
PASSAGEHEADER/FOOTER CONTENT\
<</if>>
<<if not tags().includes("nofooter")>>\
PASSAGEHEADER/FOOTER CONTENT\
<</if>>

Then to style, I wrapped the whole thing in a div in the passage:

<div class=header>
CONTENT
</div>
<div class=header>
CONTENT
</div>

… and in CSS, to place the little speaker in the top right corner:

.header img {
    position: fixed;
    top: 10px;
    right: 15px;
    max-width: 2.5%;
}
.header img {
    position: fixed;
    top: 10px;
    right: 15px;
    max-width: 2.5%;
}