diff --git a/packages/frontend/src/pages/drop-and-fusion.vue b/packages/frontend/src/pages/drop-and-fusion.vue
index f585519459e8a8f353abdeda697372ad392aaa4c..c5ab7a33f5feeb93f994a83f6f6760d116864f5a 100644
--- a/packages/frontend/src/pages/drop-and-fusion.vue
+++ b/packages/frontend/src/pages/drop-and-fusion.vue
@@ -1028,6 +1028,7 @@ definePageMetadata({
 	bottom: 10px;
 	padding: 6px 8px;
 	color: #f00;
+	font-weight: bold;
 	background: #0008;
 	border-radius: 6px;
 	pointer-events: none;
diff --git a/packages/frontend/src/scripts/drop-and-fusion-engine.ts b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
index a59eb271ec76ea2bcafe6f457cc0db2a5f7545bd..342e8189053f9e07c833d6607e8f5557452fc102 100644
--- a/packages/frontend/src/scripts/drop-and-fusion-engine.ts
+++ b/packages/frontend/src/scripts/drop-and-fusion-engine.ts
@@ -157,6 +157,7 @@ export class DropAndFusionGame extends EventEmitter<{
 
 		//#region walls
 		const WALL_OPTIONS: Matter.IChamferableBodyDefinition = {
+			label: '_wall_',
 			isStatic: true,
 			friction: 0.7,
 			slop: 1.0,
@@ -254,12 +255,14 @@ export class DropAndFusionGame extends EventEmitter<{
 			const additionalScore = Math.round(currentMono.score * comboBonus);
 			this.score += additionalScore;
 
-			// TODO: 効果音再生はコンポーネント側の責務なので移動する
-			const pan = ((newX / this.gameWidth) - 0.5) * 2;
+			// TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
+			const panV = newX - this.PLAYAREA_MARGIN;
+			const panW = this.gameWidth - this.PLAYAREA_MARGIN - this.PLAYAREA_MARGIN;
+			const pan = ((panV / panW) - 0.5) * 2;
 			sound.playUrl('/client-assets/drop-and-fusion/bubble2.mp3', {
 				volume: this.sfxVolume,
 				pan,
-				playbackRate: nextMono.sfxPitch,
+				playbackRate: nextMono.sfxPitch * this.replayPlaybackRate,
 			});
 
 			this.emit('monoAdded', nextMono);
@@ -293,7 +296,7 @@ export class DropAndFusionGame extends EventEmitter<{
 		this.tickRaf = null;
 		this.emit('gameOver');
 
-		// TODO: 効果音再生はコンポーネント側の責務なので移動する
+		// TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
 		sound.playUrl('/client-assets/drop-and-fusion/gameover.mp3', {
 			volume: this.sfxVolume,
 		});
@@ -377,14 +380,19 @@ export class DropAndFusionGame extends EventEmitter<{
 				} else {
 					const energy = pairs.collision.depth;
 					if (energy > minCollisionEnergyForSound) {
-						// TODO: 効果音再生はコンポーネント側の責務なので移動する
+						// TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
 						const vol = ((Math.min(maxCollisionEnergyForSound, energy - minCollisionEnergyForSound) / maxCollisionEnergyForSound) / 4) * this.sfxVolume;
-						const pan = ((((bodyA.position.x + bodyB.position.x) / 2) / this.gameWidth) - 0.5) * 2;
+						const panV =
+							pairs.bodyA.label === '_wall_' ? bodyB.position.x - this.PLAYAREA_MARGIN :
+							pairs.bodyB.label === '_wall_' ? bodyA.position.x - this.PLAYAREA_MARGIN :
+							((bodyA.position.x + bodyB.position.x) / 2) - this.PLAYAREA_MARGIN;
+						const panW = this.gameWidth - this.PLAYAREA_MARGIN - this.PLAYAREA_MARGIN;
+						const pan = ((panV / panW) - 0.5) * 2;
 						const pitch = soundPitchMin + ((soundPitchMax - soundPitchMin) * (1 - (Math.min(10, energy) / 10)));
 						sound.playUrl('/client-assets/drop-and-fusion/poi1.mp3', {
 							volume: vol,
 							pan,
-							playbackRate: pitch,
+							playbackRate: pitch * this.replayPlaybackRate,
 						});
 					}
 				}
@@ -518,11 +526,14 @@ export class DropAndFusionGame extends EventEmitter<{
 		this.emit('dropped');
 		this.emit('monoAdded', head.mono);
 
-		// TODO: 効果音再生はコンポーネント側の責務なので移動する
-		const pan = ((x / this.gameWidth) - 0.5) * 2;
+		// TODO: 効果音再生はコンポーネント側の責務なので移動するべき?
+		const panV = x - this.PLAYAREA_MARGIN;
+		const panW = this.gameWidth - this.PLAYAREA_MARGIN - this.PLAYAREA_MARGIN;
+		const pan = ((panV / panW) - 0.5) * 2;
 		sound.playUrl('/client-assets/drop-and-fusion/poi2.mp3', {
 			volume: this.sfxVolume,
 			pan,
+			playbackRate: this.replayPlaybackRate,
 		});
 	}
 
diff --git a/packages/frontend/src/scripts/sound.ts b/packages/frontend/src/scripts/sound.ts
index 142ddf87c95517538c45246573c7c1b1cf0cae59..05c8977ecfb35e528d85e57ead66e791ed31e290 100644
--- a/packages/frontend/src/scripts/sound.ts
+++ b/packages/frontend/src/scripts/sound.ts
@@ -99,7 +99,6 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
 	}
 	if (options?.useCache ?? true) {
 		if (cache.has(url)) {
-			if (_DEV_) console.log('use cache');
 			return cache.get(url) as AudioBuffer;
 		}
 	}
@@ -128,7 +127,6 @@ export async function loadAudio(url: string, options?: { useCache?: boolean; })
  */
 export function playMisskeySfx(operationType: OperationType) {
 	const sound = defaultStore.state[`sound_${operationType}`];
-	if (_DEV_) console.log('play', operationType, sound);
 	if (sound.type == null || !canPlay) return;
 
 	canPlay = false;