Death Defiance Timing
The Death Defiance revive prompt uses a non-linear “cheater timer” so that the visible drain bar appears to slow down at the end, giving the player extra real-world seconds to react after the bar has already crossed into the “almost gone” zone. The bar’s display position is a linear function of an internal clock; the internal clock is what gets warped. All constants live in src/starship-survivors/data/economy.ts.
The three phases
The prompt runs through three back-to-back phases on a single real-world wall clock:
| Phase | Display fraction | Real-time seconds | Behavior |
|---|---|---|---|
| Linear early | 1.0 → CHEAT_THRESHOLD (0.35) | PROMPT_DURATION × (1 - CHEAT_THRESHOLD) = 3.25 s | Bar drains at normal speed: 1 display-second per real-second. |
| Stretched cheater | CHEAT_THRESHOLD (0.35) → ~0.01 | PROMPT_DURATION × CHEAT_THRESHOLD × CHEAT_STRETCH = 3.50 s | Bar’s apparent speed is halved. The last 35% of display takes 2x as long in real time. |
| Linger at 1% | stays near 0.01 | LINGER_DURATION = 1.00 s | Bar sits sparking red, then auto-dismiss fires. |
Sum: DEATH_DEFIANCE_TOTAL_REAL_DURATION = 7.75 s of real time for a PROMPT_DURATION of 5 s.
Authoritative duration
DEATH_DEFIANCE_TOTAL_REAL_DURATION is the single source of truth for “how long is the prompt up.” Both consumers must use it:
- Bridge dismiss timer — the engine-side timeout that fires the auto-dismiss / auto-decline. If this fired off
PROMPT_DURATION(5 s) it would cut the prompt off mid-stretch, before the React bar reached zero. - React bar component — the visual drain bar. Its own internal animation runs against the same total so the bar reaches ~1% exactly when the linger phase begins, and the prompt closes exactly when linger ends.
The computed expression in economy.ts is the formula for that contract:
const cheatDisplay = PROMPT_DURATION * CHEAT_THRESHOLD;
const normalDisplay = PROMPT_DURATION - cheatDisplay;
return normalDisplay + cheatDisplay * CHEAT_STRETCH + LINGER_DURATION;If any of the four input constants change (PROMPT_DURATION, CHEAT_THRESHOLD, CHEAT_STRETCH, LINGER_DURATION), TOTAL_REAL_DURATION recomputes and both consumers stay in sync automatically — neither side ever hardcodes the 5 s display duration or the 7.75 s real duration.
Why cheater-timer exists
Death Defiance is the only paid in-run revive (gem cost escalates 20 / 40 / 60 per use; see deathDefianceCost). It triggers in the worst possible UX moment: the player just died, the “YOU DIED” cinematic ran for 3 s, and now a modal demands an immediate yes/no decision. A 5-second hard timer that drains linearly feels punitive — the player perceives the back half of the bar as faster than the front half because urgency compresses subjective time.
The cheater timer breaks that perception three ways:
- Front-loaded normal speed. The first 65% of the bar drains at the speed the player calibrates to. They build an internal model of “this bar takes ~3 seconds total” based on the first chunk.
- Stealth slowdown. As the bar enters the stretched portion the actual real-time rate drops by half, but the visual cue (bar position) keeps moving. The player thinks they’re getting faster at deciding; they’re actually getting more wall-clock time than they expected.
- Linger tension. The last second is the bar pinned at ~1% sparking red. This reads as dramatic “last chance” tension to the player while functionally being a free 1.0 s of decision time after the bar visually appears empty.
Net effect: the player perceives a tight 5-second decision window, gets 7.75 s of real time, and is more likely to make a deliberate purchase decision (either yes or no) instead of a panicked one. Panic decisions correlate with regret, regret correlates with refund requests and churn — both bad for a single-currency premium revive.
Related
deathDefianceCost— escalating gem cost per useDEATH_DEFIANCE_CINEMATIC_DURATION— the 3 s “YOU DIED” cinematic that runs before this promptDEATH_DEFIANCE_INVULN_SECONDS— 3 s post-revive iframes