Skip to content

Latest commit

ย 

History

History
371 lines (297 loc) ยท 9.65 KB

File metadata and controls

371 lines (297 loc) ยท 9.65 KB

๐Ÿ… Updated Achievement Medal Guide

Here's the complete guide for adding new medal tracks to your system!


Adding New Achievement Medals to TacoTracker

This guide shows you how to add new progressive medal tracks (Bronze โ†’ Silver โ†’ Gold โ†’ Platinum) to the TacoTracker app.


๐Ÿ“‹ Table of Contents

  1. Understanding the Medal System
  2. Step-by-Step: Adding a New Track
  3. Example: Weekend Warrior Track
  4. Testing Your New Track
  5. Common Patterns & Tips

๐ŸŽ“ Understanding the Medal System

Medal Tiers

Every track has 4 progressive tiers:

  • ๐Ÿฅ‰ Bronze - Easy to achieve, gets users started
  • ๐Ÿฅˆ Silver - Moderate effort, regular users
  • ๐Ÿฅ‡ Gold - Significant achievement, dedicated users
  • ๐Ÿ’Ž Platinum - Ultimate goal, hardcore fans

How It Works

User logs tacos โ†’ Repository calculates progress โ†’ Unlocks new tiers โ†’ Shows celebration

Key Files

  • Achievement.kt - Define the track and tier requirements
  • AchievementRepository.kt - Calculate current progress
  • No other files need changes! ๐ŸŽ‰

๐Ÿš€ Step-by-Step: Adding a New Track

Step 1: Define Your Track in Achievement.kt

Open app/src/main/java/com/dinorawrger/tacotracker/data/Achievement.kt

Add your new track to the AchievementTrack sealed class:

sealed class AchievementTrack(
    val id: String,
    val title: String,
    val description: String,
    val emoji: String,
    private val bronzeReq: TierRequirement,
    private val silverReq: TierRequirement,
    private val goldReq: TierRequirement,
    private val platinumReq: TierRequirement
) {
    // ... existing tracks ...
    
    // โญ ADD YOUR NEW TRACK HERE:
    data object YourTrackName : AchievementTrack(
        id = "your_track_id",                    // Unique ID (lowercase, underscores)
        title = "Your Track Title",              // Display name
        description = "What this tracks",        // Short description
        emoji = "๐ŸŽฏ",                            // Fun emoji icon
        bronzeReq = TierRequirement(
            description = "Do X 10 times",       // What user needs to do
            targetValue = 10                     // The number to reach
        ),
        silverReq = TierRequirement(
            description = "Do X 25 times",
            targetValue = 25
        ),
        goldReq = TierRequirement(
            description = "Do X 50 times",
            targetValue = 50
        ),
        platinumReq = TierRequirement(
            description = "Do X 100 times",
            targetValue = 100
        )
    )
    
    // Don't forget the getAll() function at the bottom!
    companion object {
        fun getAll(): List<AchievementTrack> = listOf(
            TacoVolume,
            TacoTuesday,
            Explorer,
            // ... other tracks ...
            YourTrackName  // โญ ADD IT HERE TOO!
        )
    }
}

Step 2: Add Calculation Logic in AchievementRepository.kt

Open app/src/main/java/com/dinorawrger/tacotracker/data/AchievementRepository.kt

Find the calculateCurrentValue() function and add your case:

private fun calculateCurrentValue(
    track: AchievementTrack,
    allMeals: List<MealWithTacos>,
    allFavorites: List<FavoriteMeal>
): Int = when (track) {
    // ... existing cases ...
    
    // โญ ADD YOUR CALCULATION HERE:
    is AchievementTrack.YourTrackName -> {
        // Write code to calculate current progress
        // Examples below!
        allMeals.count { /* your condition */ }
    }
}

๐Ÿ“š Example: Weekend Warrior Track

Let's add a complete track for tacos eaten on weekends!

Step 1: Define the Track

data object WeekendWarrior : AchievementTrack(
    id = "weekend_warrior",
    title = "Weekend Warrior",
    description = "Tacos consumed on Saturdays and Sundays",
    emoji = "๐ŸŽ‰",
    bronzeReq = TierRequirement(
        description = "Eat 25 tacos on weekends",
        targetValue = 25
    ),
    silverReq = TierRequirement(
        description = "Eat 50 tacos on weekends",
        targetValue = 50
    ),
    goldReq = TierRequirement(
        description = "Eat 100 tacos on weekends",
        targetValue = 100
    ),
    platinumReq = TierRequirement(
        description = "Eat 250 tacos on weekends",
        targetValue = 250
    )
)

Step 2: Add to getAll()

companion object {
    fun getAll(): List<AchievementTrack> = listOf(
        TacoVolume,
        TacoTuesday,
        Explorer,
        Adventurer,
        Carnivore,
        Herbivore,
        BreakfastChampion,
        Perfectionist,
        Collector,
        NightOwl,
        WeekendWarrior  // โญ Add here
    )
}

Step 3: Add Calculation Logic

is AchievementTrack.WeekendWarrior -> {
    // Count tacos from meals on Saturday or Sunday
    val calendar = Calendar.getInstance()
    
    allMeals
        .filter { mealWithTacos ->
            calendar.timeInMillis = mealWithTacos.meal.eatenAtEpochMillis
            val dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)
            dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY
        }
        .sumOf { it.meal.totalTacos }
}

Done! ๐ŸŽ‰ The track will automatically appear in the Achievements screen!


๐Ÿงช Testing Your New Track

1. Build and Run

Build โ†’ Clean Project
Build โ†’ Rebuild
Run app

2. Navigate to Achievements

Your new track should appear in the grid!

3. Log Test Data

  • Go to New Entry
  • Log meals that match your criteria
  • Return to Achievements
  • Progress should update!

4. Check Medal Unlocks

  • When you hit a threshold, celebration dialog should appear
  • Tap the medal card to see detail screen
  • All 4 tiers should show with correct status

๐Ÿ’ก Common Calculation Patterns

Count Total Tacos (Simple)

is AchievementTrack.TacoVolume -> {
    allMeals.sumOf { it.meal.totalTacos }
}

Count Meals with Condition

is AchievementTrack.BreakfastChampion -> {
    allMeals
        .filter { it.meal.mealType.equals("Breakfast", ignoreCase = true) }
        .sumOf { it.meal.totalTacos }
}

Count Unique Values

is AchievementTrack.Explorer -> {
    allMeals
        .map { it.meal.location.trim().lowercase() }
        .filter { it.isNotBlank() }
        .distinct()
        .size
}

Count by Ingredient Match

is AchievementTrack.Carnivore -> {
    val meatKeywords = listOf("beef", "chicken", "pork", "steak", "carnitas", "barbacoa")
    
    allMeals
        .flatMap { it.tacos }
        .count { taco ->
            taco.ingredients.any { ingredient ->
                meatKeywords.any { keyword ->
                    ingredient.name.contains(keyword, ignoreCase = true)
                }
            }
        }
}

Count by Date/Time

is AchievementTrack.TacoTuesday -> {
    val calendar = Calendar.getInstance()
    
    allMeals
        .filter { mealWithTacos ->
            calendar.timeInMillis = mealWithTacos.meal.eatenAtEpochMillis
            calendar.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY
        }
        .sumOf { it.meal.totalTacos }
}

Find Maximum Value

is AchievementTrack.SpeedRunner -> {
    // Tracks most tacos in a single meal
    allMeals.maxOfOrNull { it.meal.totalTacos } ?: 0
}

Count Favorites Usage

is AchievementTrack.Collector -> {
    allFavorites.size
}

๐ŸŽฏ Design Tips for Good Tracks

โœ… DO:

  • Progressive difficulty: Bronze easy โ†’ Platinum challenging
  • Clear criteria: Users understand what to track
  • Achievable Bronze: Get users started quickly (10-25 tacos)
  • Ambitious Platinum: Real dedication required (100-500 tacos)
  • Interesting patterns: Reveal habits (time, location, ingredients)

โŒ DON'T:

  • Binary achievements: Either you have it or you don't
  • Impossible Platinum: No one will reach it
  • Too easy Bronze: Everyone gets it immediately
  • Confusing metrics: Users don't understand progress
  • Require missing features: Don't track things you don't store

๐Ÿ“Š Recommended Target Values

Based on typical usage patterns:

Tier Easy Track Medium Track Hard Track
๐Ÿฅ‰ Bronze 10-25 5-15 3-10
๐Ÿฅˆ Silver 50-75 25-40 15-25
๐Ÿฅ‡ Gold 100-150 50-75 30-50
๐Ÿ’Ž Platinum 250-500 100-200 75-150

Easy tracks: Total volume (tacos, meals)
Medium tracks: Specific categories (breakfast, locations)
Hard tracks: Rare events (perfect meals, streaks)


๐Ÿ› Troubleshooting

Track doesn't appear in UI

  • Did you add it to getAll()?
  • Clean and rebuild the project
  • Check for typos in track ID

Progress not updating

  • Check your calculation logic returns correct Int
  • Log test data that matches your criteria
  • Add debug logging: println("Progress: $value")

Crash when tapping medal

  • Make sure id is unique (no duplicates)
  • Check track is in getAll() list

Wrong progress value

  • Verify your filter conditions are correct
  • Check data types (Int vs Long)
  • Test calculation with known data

๐ŸŽ‰ You're Done!

Your new medal track is live! Users will:

  1. See it in the Achievements grid
  2. Watch progress update as they log tacos
  3. Get celebration dialogs when unlocking tiers
  4. View all tier details in the detail screen

No database migrations needed! The track evaluates dynamically from existing meal data.

Happy tracking! ๐ŸŒฎ๐Ÿ…

โšก