feat: communicate quest failure mechanics in the UI (#82)
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m2s
CI / Lint, Build & Test (push) Successful in 1m8s

## Summary

Addresses recurring community confusion about quests failing — multiple players asked whether it was a bug or intended behaviour with no in-game explanation.

- **Exports `zoneFailureChance`** from `tick.ts` so the quest panel can read it
- **Quest cards** now show a `🎲 X% failure chance` note on all available quests, with a brief explanation that a failure resets the quest with no rewards
- **"Last attempt failed" hint** now reads `"⚠️ Last attempt failed — no rewards were granted."` so players understand the consequence immediately
- **About panel** updated to document the failure mechanic, including the 10%–40% range across zones

Closes #80

 This PR was created with help from Hikari~ 🌸

Reviewed-on: #82
Co-authored-by: Hikari <hikari@nhcarrigan.com>
Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #82.
This commit is contained in:
2026-03-19 17:57:17 -07:00
committed by Naomi Carrigan
parent 161127dc21
commit 0057cfeaaa
3 changed files with 18 additions and 3 deletions
+12 -1
View File
@@ -10,6 +10,7 @@
/* eslint-disable max-statements -- Many local variables needed for quest state */
import { useState, type JSX } from "react";
import { useGame } from "../../context/gameContext.js";
import { zoneFailureChance } from "../../engine/tick.js";
import { cdnImage } from "../../utils/cdn.js";
import { LockToggle } from "../ui/lockToggle.js";
import { ZoneSelector } from "./zoneSelector.js";
@@ -143,8 +144,18 @@ const QuestCard = ({
: null}
</>
}
{quest.status === "available"
&& <p className="quest-failure-chance">
{"🎲 "}
{String(Math.round((zoneFailureChance[quest.zoneId] ?? 0) * 100))}
{"% failure chance — if failed, the quest resets"}
{" and must be retried."}
</p>
}
{quest.status === "available" && quest.lastFailedAt !== undefined
&& <p className="quest-failed-hint">{"⚠️ Last attempt failed"}</p>
&& <p className="quest-failed-hint">
{"⚠️ Last attempt failed — no rewards were granted."}
</p>
}
{quest.status === "available"
&& <button