Mobile Game Daily Quests System Development
Daily quests—main mechanism for daily app return. While achievements provide long-term goals, daily quests answer "why open game today?" For casual games with DAU under 100k, properly implemented dailies increase Day-7 retention 1.5–2x—if quests are actually interesting, not "open game 3 times."
Quest Generation: Static vs Dynamic
Static quests — fixed pool, randomly select 3–5 per day. Simple to implement, predictable for players, gets stale fast.
Dynamic quests — generated based on player progress and activity. New players get "complete 3 levels," veterans get "collect 500 resource X." Complex implementation, better retention.
Data schema for dynamic system:
[Serializable]
public class QuestTemplate
{
public string templateId;
public string type; // "complete_levels", "collect_items", "defeat_enemies"
public int[] targetValues; // difficulty variants: [3, 5, 10]
public string[] targetParams; // for collect: ["wood", "stone", "gold"]
public QuestRewardTier[] rewardTiers; // reward by difficulty
public int minPlayerLevel;
public int maxPlayerLevel; // -1 = no limit
}
[Serializable]
public class ActiveQuest
{
public string questId;
public string templateId;
public string type;
public string targetParam;
public int targetValue;
public int currentValue;
public bool isCompleted;
public bool rewardClaimed;
public DateTime expiresAt;
}
DailyQuestManager: Generation and Tracking
public class DailyQuestManager : MonoBehaviour
{
private const int QUEST_SLOTS = 3;
private List<ActiveQuest> _activeQuests = new();
private QuestDatabase _database;
public void GenerateDailyQuests()
{
_activeQuests.Clear();
var playerLevel = PlayerData.Level;
var random = new System.Random(GetDailySeed()); // seed = date, same for all
var eligibleTemplates = _database.Templates
.Where(t => playerLevel >= t.minPlayerLevel &&
(t.maxPlayerLevel == -1 || playerLevel <= t.maxPlayerLevel))
.ToList();
var selectedTemplates = eligibleTemplates
.OrderBy(_ => random.Next())
.Take(QUEST_SLOTS)
.ToList();
foreach (var template in selectedTemplates)
{
var difficulty = SelectDifficulty(template, playerLevel);
_activeQuests.Add(CreateQuestFromTemplate(template, difficulty));
}
SaveQuests();
}
private int GetDailySeed()
{
// All players get same quest set per day
// (or different - design decision)
return DateTime.UtcNow.Date.GetHashCode() ^ PlayerData.UserId.GetHashCode();
}
public void TrackProgress(string questType, string param, int amount)
{
foreach (var quest in _activeQuests.Where(q => !q.isCompleted && q.type == questType))
{
if (!string.IsNullOrEmpty(quest.targetParam) && quest.targetParam != param) continue;
quest.currentValue += amount;
if (quest.currentValue >= quest.targetValue)
{
quest.isCompleted = true;
OnQuestCompleted(quest);
}
}
SaveQuests();
}
}
Gameplay Integration
Quest tracking should be seamless—player doesn't think "need to press count button," just plays:
// In combat system:
void OnEnemyDefeated(Enemy enemy)
{
DailyQuestManager.Instance.TrackProgress("defeat_enemies", enemy.type, 1);
AchievementsManager.Instance.TrackEvent("enemy_defeated", 1);
// ...
}
// In resource collection:
void OnResourceCollected(string resourceId, int amount)
{
DailyQuestManager.Instance.TrackProgress("collect_items", resourceId, amount);
// ...
}
Single call from gameplay system—all matching quests update automatically.
Reward System and Streak
Daily quests work better with completion streak:
// On all daily quests completed
void OnAllQuestsCompleted()
{
var streak = PlayerPrefs.GetInt("daily_quest_streak", 0);
var lastCompletedDate = PlayerPrefs.GetString("quest_last_completed", "");
var yesterday = DateTime.UtcNow.Date.AddDays(-1).ToString("yyyy-MM-dd");
var today = DateTime.UtcNow.Date.ToString("yyyy-MM-dd");
streak = (lastCompletedDate == yesterday) ? streak + 1 : 1;
PlayerPrefs.SetInt("daily_quest_streak", streak);
PlayerPrefs.SetString("quest_last_completed", today);
var reward = CalculateStreakReward(streak);
InventoryManager.Instance.AddReward(reward);
GameAnalytics.NewDesignEvent("DailyQuests:StreakCompleted", streak);
}
Day 7 gets special reward. Day 30 gets exceptional. Creates long-term goal over daily quests.
Server Generation vs Client
For games without cheating threat—client generation simpler. For games with real rewards (IAP equivalent)—generation and reward granting only through server (PlayFab Cloud Script). Client requests quests, server returns generated list and verifies progress before reward grant.
What's Included
- Design quest templates and difficulty system
-
DailyQuestManagerimplementation with generation and tracking - Tracking integration into gameplay systems
- Streak system with escalating rewards
- Quest reset by schedule (UTC midnight)
- UI: quest list, progress bars, reward screen
- Server generation and validation (PlayFab, if needed)
Timeline
Client system with basic quests: 4–7 days. Full system with server generation, streak and complex UI: 2–3 weeks. Cost calculated individually.







