From 3ef53a6f9ef81e90f32f6f09e9e309f24eddd47c Mon Sep 17 00:00:00 2001 From: how4rd <15080656+how4rd@users.noreply.github.com> Date: Fri, 30 Jan 2026 22:51:58 -0800 Subject: [PATCH 01/12] Begin web version --- squingo.html | 554 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 554 insertions(+) create mode 100644 squingo.html diff --git a/squingo.html b/squingo.html new file mode 100644 index 0000000..530da36 --- /dev/null +++ b/squingo.html @@ -0,0 +1,554 @@ + + + + + SQUINGO + + + + + +
+ + + + + \ No newline at end of file From 06ffcb6bfb927ea048677e88c7e290cec4aa6161 Mon Sep 17 00:00:00 2001 From: how4rd <15080656+how4rd@users.noreply.github.com> Date: Sat, 31 Jan 2026 00:39:16 -0800 Subject: [PATCH 02/12] Add sound effects to web version --- squingo.html | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/squingo.html b/squingo.html index 530da36..a5ee84e 100644 --- a/squingo.html +++ b/squingo.html @@ -229,6 +229,54 @@ HE DO BE TERRORIZING THE SEVEN SEAS THOUGH 👀 ` + // relative paths to filler sound effects to play immediately after input is entered + SFX_INPUT_PATHS = [ + "sfx/input/Robot_blip-Marianne_Gagnon-120342607.wav" + ] + + // relative paths to beep sound effects to play when a processing a hand + SFX_BEEP_PATHS = [ + "sfx/beep/Bleep-SoundBible.com-1927126940.wav" + ] + + // relative paths to miscellanous filler sound effects to play when processing a hand + SFX_MISC_PATHS = [ + "sfx/misc/Alien Brain Scanner-SoundBible.com-2034590144.wav", + "sfx/misc/Computer Error Alert-SoundBible.com-783113881.wav", + "sfx/misc/Martian_Death_Ray-Mike_Koenig-937891031.wav", + "sfx/misc/Monster Growl-SoundBible.com-344645592.wav", + "sfx/misc/Time Warp-SoundBible.com-634766493.wav", + "sfx/misc/WilhelmScream.wav" + ] + + // relative paths to sound effects to play when a hand is squingo + SFX_SQUINGO_PATHS = [ + "sfx/squingo/cartoon-telephone_daniel_simion.wav", + "sfx/squingo/Computer_Magic-Microsift-1901299923.wav", + "sfx/squingo/Warning Siren-SoundBible.com-898272278.wav", + "sfx/squingo/Zombie In Pain-SoundBible.com-134322253.wav", + ] + + // relative paths to sound effects to play when a hand is not squingo + SFX_NOT_SQUINGO_PATHS = [ + "sfx/not_squingo/Burp 2x-SoundBible.com-1895509911.wav", + "sfx/not_squingo/Cat Scream-SoundBible.com-871191563.wav", + "sfx/not_squingo/Laugh Evil-SoundBible.com-1059217446.wav", + "sfx/not_squingo/Warning Siren-SoundBible.com-898272278.wav", + ] + + // relative paths to sound effects to play when a hand is monkey pirate + SFX_MONKEY_PIRATE_PATHS = [ + "sfx/monkey_pirate/monkey_pirate.wav" + ] + + // the inclusive min amount of time in milliseconds to wait + // between playing consecutive non-blocking sound effects + INCLUSIVE_MIN_SFX_PAUSE_MS = 1000 + // the exclusive max amount of time in milliseconds to wait + // between playing consecutive non-blocking sound effects + EXCLUSIVE_MAX_SFX_PAUSE_MS = 3000 + /** * Return the given input element's text when the user presses enter. */ @@ -282,6 +330,7 @@ consoleElement.appendChild(inputScreenElement) const cardHand = await waitForInput(inputScreenElement, "Enter the card hand: ") + await playRandomSfxFromPathsBlocking(SFX_INPUT_PATHS) return cardHand } @@ -306,6 +355,40 @@ ) } + /** + * Play a random sound effect from the given list of sound effect paths, + * blocking until the sound finishes. + */ + function playRandomSfxFromPathsBlocking(sfxPaths) { + const sfxPath = randomItemInArray(sfxPaths) + return new Promise(resolve => { + let audio = new Audio(sfxPath) + audio.onended = resolve + audio.play() + }) + } + + /** + * Without blocking execution, repeatedly wait a random amount of time + * and then play a random sound from the given list of sound effect paths. + * During each iteration, update the value in timeoutWrapper.timeout + * with the current iteration's timeout, so that this function's original caller + * can stop sounds from playing by calling cancelTimeout(timeoutWrapper.timeout). + * (The caller created the timeoutWrapper object and then passed it by reference + * into this function. Thus, the caller will see any edits that this function makes to + * timeoutWrapper. If instead this function took a timeout primitive that wasn't contained + * in a wrapper object, then this function would take the timeout by value, so the caller would + * not see edits to the caller.) + */ + function repeatRandomSfxFromPathsNonBlocking(sfxPaths, timeoutWrapper) { + const delayTimeMs = randomIntInRange(INCLUSIVE_MIN_SFX_PAUSE_MS, EXCLUSIVE_MAX_SFX_PAUSE_MS) + timeoutWrapper.timeout = setTimeout(() => { + playRandomSfxFromPathsBlocking(sfxPaths) + repeatRandomSfxFromPathsNonBlocking(sfxPaths, timeoutWrapper) + }, delayTimeMs) + } + + /** * Display a bunch of junk characters. */ @@ -355,6 +438,12 @@ * each made by combining a random verb and noun. */ async function runLoadingMessages(loadingScreenElement) { + let miscTimeoutWrapper = { timeout: null } + repeatRandomSfxFromPathsNonBlocking(SFX_MISC_PATHS, miscTimeoutWrapper) + await delay(1000) + let beepTimeoutWrapper = { timeout: null } + repeatRandomSfxFromPathsNonBlocking(SFX_BEEP_PATHS, beepTimeoutWrapper) + const numLoadingMessages = randomIntInRange(4, 10) for (let loadingMessageIndex = 0; loadingMessageIndex <= numLoadingMessages; ++loadingMessageIndex) { let loadingMessageRowElement = document.createElement("div") @@ -382,6 +471,9 @@ loadingMessageRowElement.classList.remove("active-loading-message") await delay(500) } + + clearTimeout(miscTimeoutWrapper.timeout) + clearTimeout(beepTimeoutWrapper.timeout) } /** @@ -501,12 +593,18 @@ squingoTextElement.classList.add("outcome-text", "outcome-text-squingo") squingoTextElement.textContent = TEXT_SQUINGO outcomeElement.appendChild(squingoTextElement) + + await playRandomSfxFromPathsBlocking(SFX_SQUINGO_PATHS) + break; case Outcome.NOT_SQUINGO: let notSquingoTextElement = document.createElement("div") notSquingoTextElement.classList.add("outcome-text", "outcome-text-not-squingo") notSquingoTextElement.textContent = TEXT_NOT_SQUINGO outcomeElement.appendChild(notSquingoTextElement) + + await playRandomSfxFromPathsBlocking(SFX_NOT_SQUINGO_PATHS) + break; default: // monkey pirate let monkeyPirateTextElement = document.createElement("div") @@ -518,10 +616,11 @@ monkeyPirateGraphicElement.classList.add("outcome-graphic", "outcome-graphic-monkey-pirate") monkeyPirateGraphicElement.textContent = GRAPHIC_MONKEY_PIRATE outcomeElement.appendChild(monkeyPirateGraphicElement) + + await playRandomSfxFromPathsBlocking(SFX_MONKEY_PIRATE_PATHS) + break; } - - await delay(2500) } /** From 841795fafac94b6491aacf9b932a99ef6b7d7380 Mon Sep 17 00:00:00 2001 From: how4rd <15080656+how4rd@users.noreply.github.com> Date: Sat, 31 Jan 2026 00:45:20 -0800 Subject: [PATCH 03/12] Specify char encoding in web version Fix character rendering in Safari --- squingo.html | 143 +++++++++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/squingo.html b/squingo.html index a5ee84e..fb9e814 100644 --- a/squingo.html +++ b/squingo.html @@ -3,6 +3,7 @@ SQUINGO +