fix: both-wrong draws + double TTS entrance fix
Scoring: both-wrong is now a DRAW — equal scores (3/3), no winner, symmetric minimal damage. Garbage answers no longer beat reasonable ones just by being faster. Both-wrong narrations reflect the draw. Entrance: removed duplicate announceDeepIntro() call from FightViewer (was already called inside playEntrance). Removed _resetPositions() after entrance (entrance already places fighters at home positions, the extra reset caused a visible snap/reset). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
017d0e3e4c
commit
6f0eb92ebb
@@ -3,7 +3,7 @@ import { ref, onMounted, onUnmounted, nextTick } from 'vue'
|
||||
import { createFightScene, type FightSceneController } from '../game/FightScene'
|
||||
import {
|
||||
fanfareRound, fanfareFight, announce, announceDeep, announceFast,
|
||||
announceDeepIntro, announceRandomHype, announceRoundHype,
|
||||
announceRandomHype, announceRoundHype,
|
||||
announceFinishHim, announceFlawlessVictory,
|
||||
sfxCrowdCheer, sfxCrowdGasp, sfxCrowdOoh, sfxApplause, sfxDrumRoll,
|
||||
setMusicIntensity, stopAllAudio,
|
||||
@@ -382,8 +382,7 @@ async function _doReplay() {
|
||||
}
|
||||
await sleep(300)
|
||||
|
||||
// Deep movie trailer intro
|
||||
announceDeepIntro()
|
||||
// Arena intro overlay (deep voice intro plays inside playEntrance)
|
||||
await showOverlay(props.fight.arenaInfo?.name || 'THE RING', '#b83dff', 900)
|
||||
logItems.value.push(
|
||||
{ type: 'system', round: 0, text: `ARENA: ${props.fight.arenaInfo?.name || 'THE RING'}`, color: 'neon-purple' },
|
||||
@@ -393,12 +392,9 @@ async function _doReplay() {
|
||||
scrollLog()
|
||||
await sleep(200)
|
||||
|
||||
// Entrance animations
|
||||
// Entrance animations (positions fighters at home, no reset needed after)
|
||||
if (scene) {
|
||||
await scene.playEntrance()
|
||||
// Safety: ensure fighters are visible after entrance (prevents invisible characters if entrance times out)
|
||||
// Re-check: scene could be destroyed during async playEntrance()
|
||||
scene?._resetPositions()
|
||||
if (!scene) return
|
||||
await sleep(300)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
MARGIN_TO_DAMAGE_SCALE, LOSER_DAMAGE_BASE, ARENA_DAMAGE_MULTIPLIER,
|
||||
MAX_COMBO_STACKS, COMBO_DAMAGE_PER_STACK,
|
||||
FACTUAL_FASTER_BASE, FACTUAL_SLOWER_BASE, SPEED_ADVANTAGE_MULTIPLIER, SPEED_RATIO_MULTIPLIER,
|
||||
ONE_CORRECT_WINNER_BASE, CONFIDENCE_BONUS, NO_ANSWER_SCORE, BOTH_WRONG_FASTER, BOTH_WRONG_SLOWER,
|
||||
ONE_CORRECT_WINNER_BASE, CONFIDENCE_BONUS, NO_ANSWER_SCORE, BOTH_WRONG_SLOWER,
|
||||
RETRO_SPEED_BONUS_CAP,
|
||||
LARGE_WIN_MARGIN, CLOSE_MATCH_MARGIN, WHIFF_NARRATION_THRESHOLD,
|
||||
TIMEOUT_WINNER_SCORE, SCORE_ROUNDING_FACTOR,
|
||||
@@ -145,11 +145,10 @@ export function scoreRound(
|
||||
scoreA = NO_ANSWER_SCORE + (responseA.answer ? 1 : 0)
|
||||
scoreB = ONE_CORRECT_WINNER_BASE + correctB * CONFIDENCE_BONUS
|
||||
} else {
|
||||
// Both wrong -- speed tiebreaker in low range
|
||||
// Both wrong -- DRAW, nobody wins for getting it wrong
|
||||
resultType = 'both-wrong'
|
||||
const aFaster = responseA.timeMs <= responseB.timeMs
|
||||
scoreA = aFaster ? BOTH_WRONG_FASTER : BOTH_WRONG_SLOWER
|
||||
scoreB = aFaster ? BOTH_WRONG_SLOWER : BOTH_WRONG_FASTER
|
||||
scoreA = BOTH_WRONG_SLOWER
|
||||
scoreB = BOTH_WRONG_SLOWER
|
||||
}
|
||||
} else {
|
||||
// No answers defined — both get base score (all challenges should be factual)
|
||||
@@ -175,6 +174,17 @@ export function scoreRound(
|
||||
|
||||
const narration = winnerId
|
||||
? generateNarration(challenge, winnerName!, loserName!, margin, isCritical, resultType)
|
||||
: resultType === 'both-wrong'
|
||||
? pick([
|
||||
`Both bots WHIFFED! ${botA.name} and ${botB.name} got it wrong. Nobody wins this one!`,
|
||||
`DOUBLE MISS! Neither ${botA.name} nor ${botB.name} could answer that. Embarrassing for everyone.`,
|
||||
`${botA.name} and ${botB.name} both hallucinated! Nobody scores. The crowd throws things.`,
|
||||
`Two wrong answers! ${botA.name} and ${botB.name} cancel each other out in wrongness.`,
|
||||
`NOBODY got it right! ${botA.name} and ${botB.name} both swing and miss. Draw!`,
|
||||
`${botA.name}: wrong. ${botB.name}: also wrong. The real winner is whoever stopped watching.`,
|
||||
`Both bots confidently stated incorrect answers! ${botA.name} and ${botB.name} share the L equally.`,
|
||||
`WRONG and WRONG! Neither ${botA.name} nor ${botB.name} had any idea. The crowd demands smarter bots.`,
|
||||
])
|
||||
: pick([
|
||||
`Dead even! ${botA.name} and ${botB.name} are perfectly matched. Like two politicians blaming each other.`,
|
||||
`IT'S A TIE! ${botA.name} and ${botB.name} cancel each other out like Congress!`,
|
||||
@@ -240,21 +250,6 @@ function generateNarration(
|
||||
const critPrefix = isCritical ? 'CRITICAL HIT! ' : ''
|
||||
const isFactual = challenge.scoring === 'factual'
|
||||
|
||||
// Both bots got it WRONG — narration must reflect that
|
||||
if (isFactual && resultType === 'both-wrong') {
|
||||
const bothWrong = [
|
||||
`${critPrefix}Both bots WHIFFED! Nobody got it right but ${winner} failed FASTER. Is that even a win?`,
|
||||
`${critPrefix}DOUBLE MISS! ${winner} and ${loser} both got it wrong! ${winner} wins on speed alone. Participation trophy energy.`,
|
||||
`${critPrefix}Two wrong answers! ${winner} was wrong FASTER than ${loser}. Speed isn't everything, but here we are.`,
|
||||
`${critPrefix}Neither bot had a clue! ${winner} guessed quicker. ${loser} took their time being equally wrong.`,
|
||||
`${critPrefix}BOTH WRONG! The only thing ${winner} beat ${loser} at was being wrong first. The crowd boos.`,
|
||||
`${critPrefix}${winner} AND ${loser} both hallucinated! ${winner} at least hallucinated with conviction. Speed win.`,
|
||||
`${critPrefix}NOBODY got the answer! ${winner} earns the world's saddest victory by responding faster. Tragic.`,
|
||||
`${critPrefix}Wrong and wrong! ${winner} speedran being incorrect! ${loser} at least took time to think about it. Both failed.`,
|
||||
]
|
||||
return pick(bothWrong)
|
||||
}
|
||||
|
||||
if (isFactual && margin > LARGE_WIN_MARGIN) {
|
||||
const bigWins = [
|
||||
`${critPrefix}${winner} NAILS IT! ${loser} didn't even come close. Embarrassing, honestly.`,
|
||||
|
||||
Reference in New Issue
Block a user