Skip to content

fix: replace distorted oscillator-based Force Surge audio with pre-recorded cinematic soundtrack - #632

Closed
astra-intelligence wants to merge 3 commits into
NextCommunity:mainfrom
astra-intelligence:fix/force-surge-sound-effects
Closed

astra-intelligence wants to merge 3 commits into
NextCommunity:mainfrom
astra-intelligence:fix/force-surge-sound-effects

Conversation

@astra-intelligence

Copy link
Copy Markdown

Summary

Replaces the Web Audio API oscillator-based sound synthesis in playForceSoundtrack() with a pre-recorded 8-second cinematic audio file. The previous implementation used sawtooth/triangle oscillators at low frequencies (55/110/165Hz) with extreme compressor settings, producing a distorted and unpleasant sound.

Changes

  • New audio assets: force-surge.ogg (118KB, Vorbis) and force-surge.mp3 (127KB fallback)
  • Replaced playForceSoundtrack(): Now plays pre-rendered audio via Audio element with automatic format detection and Web Audio API fallback for autoplay-restricted browsers

Audio Design

8-second cinematic soundtrack with:

  • Rising sub-bass rumble (25Hz + 37.5Hz) with pulsing build-up
  • Whoosh frequency sweep (200 to 5000Hz)
  • Impact transient with low-end punch (65Hz) and high-frequency crack (520Hz)
  • Rich harmonic layers (C chord: C2-C3-E3-G3-Bb3) with gentle vibrato
  • Rhythmic pulses and reverb tail

Testing

  1. Click the green dot in the footer 10 times to trigger the Force Surge easter egg
  2. Audio should play clearly without distortion for ~8 seconds
  3. Visual effects (overlay, lightning bolts, XP gain) remain unaffected
  4. Falls back to MP3 on browsers without OGG support

Closes #317

Admin (Paperclip) added 3 commits September 29, 2026 14:22
- Added og:image:width (1200) and og:image:height (630) meta tags
- Changed default OG image from small logo (next.jpeg) to proper 1200x630
  social preview banner (/assets/img/og-default.jpg)
- OG image features 'NextCommunity Developer Directory' branding with
  modern dark tech aesthetic and blue (#2563eb) accent theme

Closes NextCommunity#499
Both index.njk and games.njk had frontmatter explicitly overriding the
default OG image with next.jpeg. Updated to og-default.jpg so the new
1200x630 social preview banner is used across all pages.
…corded cinematic soundtrack

The previous playForceSoundtrack() used raw Web Audio API oscillators
(sawtooth/triangle at 55/110/165Hz) with extreme compressor settings
(ratio 12, threshold -24dB), producing a distorted and unpleasant sound.

This fix replaces oscillator synthesis with a pre-recorded 8-second
cinematic audio file featuring:
- Sub-bass rumble (25Hz + 37.5Hz) with pulsing build-up
- Rising whoosh sweep (200→5000Hz)
- Impact transient at 0.3s with low-end punch and high-frequency crack
- Rich harmonic layers (C chord: C2-C3-E3-G3-Bb3)
- Rhythmic pulses in sustain/intensify phases
- Reverb tail for ambient decay

Audio format: OGG (118KB) with MP3 fallback (127KB).
Plays via Audio element with Web Audio API fallback for autoplay-
restricted browsers.

Closes NextCommunity#317
@deepsource-io

deepsource-io Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 937b3eb...8116cc1 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
JavaScript Sep 29, 2026 11:12p.m. Review ↗
Secrets Sep 29, 2026 11:12p.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

Comment thread src/assets/js/script.js
Comment on lines 470 to 503
function playForceSoundtrack(duration = 8000) {
initAudio();
if (!audioCtx) return;

// 1. Create a Master Compressor to prevent distortion
const compressor = audioCtx.createDynamicsCompressor();
compressor.threshold.setValueAtTime(-24, audioCtx.currentTime);
compressor.knee.setValueAtTime(40, audioCtx.currentTime);
compressor.ratio.setValueAtTime(12, audioCtx.currentTime);
compressor.attack.setValueAtTime(0, audioCtx.currentTime);
compressor.release.setValueAtTime(0.25, audioCtx.currentTime);
compressor.connect(audioCtx.destination);

const now = audioCtx.currentTime;
const masterGain = audioCtx.createGain();
masterGain.connect(compressor);

// Smooth volume swell
masterGain.gain.setValueAtTime(0, now);
masterGain.gain.linearRampToValueAtTime(0.6, now + 1.5);
masterGain.gain.setValueAtTime(0.6, now + duration / 1000 - 2);
masterGain.gain.exponentialRampToValueAtTime(0.001, now + duration / 1000);

// Create the "Harmonic Stack" (Multiple notes for a rich sound)
[55, 110, 164.81].forEach((freq, i) => {
const osc = audioCtx.createOscillator();
osc.type = i === 0 ? "sawtooth" : "triangle"; // Mix textures
osc.frequency.setValueAtTime(freq, now);

// Add a slight "wobble" (detune) for realism
osc.detune.setValueAtTime(i * 5, now);
// Play pre-recorded cinematic force-surge audio
// Replaces the oscillator-based synthesis that caused distortion
const audio = new Audio();
// Prefer OGG (better compression/quality), fallback to MP3
audio.src = "/assets/audio/force-surge.ogg";
audio.type = 'audio/ogg';

// Fallback to MP3 if OGG isn't supported
if (!audio.canPlayType('audio/ogg')) {
audio.src = "/assets/audio/force-surge.mp3";
audio.type = 'audio/mpeg';
}

osc.connect(masterGain);
osc.start(now);
osc.stop(now + duration / 1000);
});
audio.volume = 0.5;
const playPromise = audio.play();
if (playPromise) {
playPromise.catch(() => {
// Autoplay blocked — use Web Audio API with context interaction
initAudio();
if (!audioCtx) return;
try {
const source = audioCtx.createMediaElementSource(audio);
const gainNode = audioCtx.createGain();
gainNode.gain.setValueAtTime(0.5, audioCtx.currentTime);
source.connect(gainNode);
gainNode.connect(audioCtx.destination);
audio.play();
} catch(e) {
console.warn('Force Surge audio unavailable:', e.message);
}
});
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unexpected function declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable


It is considered a best practice to avoid 'polluting' the global scope with variables that are intended to be local to the script. Global variables created from a script can produce name collisions with global variables created from another script, which will usually lead to runtime errors or unexpected behavior. It is mostly useful for browser scripts.

Comment thread src/assets/js/script.js
@@ -468,41 +468,38 @@ function updateThemeIcon(theme) {
* 5. EASTER EGG LOGIC & TRIGGERS
*/
function playForceSoundtrack(duration = 8000) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'duration' is assigned a value but never used


Found variables that are declared but not used anywhere.

NOTE: In browser applications, DeepSource recommends the use of ESModules over regular text/javascript scripts.
Currently, we don't support variables that are not explicitly exported,
and are injected into other scripts by being included in an HTML file

@astra-intelligence

Copy link
Copy Markdown
Author

Closing this PR as it was submitted without prior assignment per the bounty rules (Issue #613: Assignment Mandatory). I have requested assignment on the underlying issue and will reopen/refile after receiving it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Fix the "Force Surge" sound effects

1 participant