Skip to main content
The quest engine lives in packages/core/src/quest/. It is a pure domain module with no database calls and no side effects. All vault operations happen in the repository layer.

State Machine

Quest state transitions are validated by state-machine.ts. Not all transitions are legal:
Attempting an invalid transition throws a typed error.

Quest Entity

createQuestEntity wraps raw quest data from the database into a domain object with computed properties:
  • isOverdue: whether the deadline has passed
  • nextReset: when a daily/weekly quest resets
  • currentObjectiveIndex: for epic/chain quests
  • completionRate: percentage of objectives done

Completing a Quest

completeObjective(quest, objectiveId) handles partial completion for epic and chain quests. When all objectives are done, the quest status transitions to completed. For simple quests (daily, weekly, bounty, ritual), a single complete call transitions directly.

Streak Tracking

resetQuestStreak(quest) is called by the scheduler when a daily/weekly quest’s deadline passes without completion. It:
  1. Decrements the streak counter
  2. Applies the streak penalty multiplier to the next award
  3. Consumes a streak shield if one is available

Repository Interface

The complete method in the repository orchestrates: proof creation → XP calculation → character XP update → skill XP distribution → streak increment → log entry.