incrementProgress method
Adds amount to questId's progress for the current period —
rebasing to 0 first if the stored record belongs to a period that
has since rolled over. Safe to call after the quest is already
completed: progress keeps accumulating, isCompleted stays true,
never throws or "un-claims".
Throws StateError if questId was never registered — unlike
AchievementService, the reset period must be known up front for
every increment, so there's no safe "track it anyway" fallback.
Implementation
void incrementProgress(String questId, int amount) {
_validateId(questId);
final def = _defs[questId];
if (def == null) {
throw StateError('quest "$questId" was not registered');
}
if (amount <= 0) {
throw ArgumentError.value(amount, 'amount', 'must be greater than 0');
}
final periodKey = _currentPeriodKey(def.period);
final records = _records;
final existing = records[questId];
final stale = existing == null || existing.periodKey != periodKey;
final base = stale ? 0 : existing.progress;
if (amount > _maxInt - base) {
throw RangeError('progress overflow for $questId');
}
records[questId] = _QuestRecord(
periodKey: periodKey,
progress: base + amount,
claimed: stale ? false : existing.claimed,
);
_scheduleSave();
}