These are the methods that drive ChefDash’s gameplay loop. Together they manage the full lifecycle of a round: initialising state before play begins, validating each ingredient tap in real time, generating fresh orders, rewarding or penalising the player, and writing the final star score back to the level map when the round ends. Public methods are callable by any view that has access toDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ImLukzy/ChefDash/llms.txt
Use this file to discover all available pages before exploring further.
GameState via @EnvironmentObject; private helpers are documented here for completeness so you can understand the internal flow without reading the source.
startNewRound()
Prepares GameState for a brand-new round. This method is the entry point called by RecipesView (or whichever view hosts the countdown timer) immediately before the timer starts.
What it does, in order:
- Resets
ordersCompletedInSessionto0and clearscurrentBurgerStack. - Sets
comboMultiplierto1. If"knife"(Cuchillo Afilado) is present inselectedUpgradesForRound, it overrides the multiplier to2instead. - Iterates over
selectedUpgradesForRoundand decrementsquantityOwnedby 1 for each matching item inshopInventory, but only if the current quantity is greater than 0 — preventing underflow on stale IDs. - Clears
selectedUpgradesForRoundso the same upgrades cannot be spent twice. - Calls
generateNextOrder()to prepare the first recipe.
generateNextOrder()
Picks the next recipe the player must assemble and updates the relevant published properties. This method is called both by startNewRound() at the beginning of a round and by triggerSuccess() after each completed order.
What it does:
- Clears
currentBurgerStackto give the player a fresh slate. - Reads
currentLevel.possibleRecipesand selects one at random usingrandomElement(). - Assigns the chosen recipe array to
targetRecipeEmojis. - Derives
currentRecipeNamefrom the recipe contents:- Contains
🥓→"Mega Bacon Burger" - Contains
🥬(and no bacon) →"Fresh Veggie Burger" - Anything else →
"Classic Cheeseburger"
- Contains
addIngredient(_ emoji: String)
The main real-time validation entry point. Every ingredient button in RecipesView calls this method when tapped.
The emoji string representing the tapped ingredient (e.g.
"🥩", "🧀"). This must match one of the emojis in currentLevel.availableIngredients for the tap to make logical sense, though the method itself does not enforce that — it validates against targetRecipeEmojis directly.- Appends
emojitocurrentBurgerStack. - If the stack length now exceeds
targetRecipeEmojis.count, callstriggerError()and returns immediately — the player added too many ingredients. - Loops over every index in the current stack and checks
currentBurgerStack[i] != targetRecipeEmojis[i]. The first mismatch callstriggerError()and returns. - If the stack exactly equals
targetRecipeEmojis(same length, all elements match), callstriggerSuccess().
currentLevel (computed property)
Returns the Level object that corresponds to selectedLevelIndex.
selectedLevelIndex is somehow out of range (e.g. during initialisation before setupLevels() has finished), the guard clause safely falls back to levels[0] — Level 1, Burger Station — rather than crashing with an index out-of-bounds error.
finishRound(starsEarned: Int)
Records the result of a completed round: persists the earned stars to the current level and unlocks the next level if the player earned at least one star.
The number of stars awarded for this round (0–3). A value of
0 means the round ended without earning any stars; the level’s existing starsEarned is not touched and no unlock happens.- If
starsEarned > 0andselectedLevelIndexis within bounds:- Updates
levels[selectedLevelIndex].starsEarnedusingmax(existing, starsEarned)so a replay can never reduce a previously earned star count. - Computes
nextLevelId = currentLevelId + 1. - Searches the
levelsarray for the entry whoseidequalsnextLevelIdusingfirstIndex(where:)and sets itsisUnlocked = true.
- Updates
finishRound(starsEarned:) runs its entire body inside DispatchQueue.main.async. This means all state mutations — including starsEarned and isUnlocked updates — are dispatched asynchronously. Do not read back levels synchronously immediately after calling this method; the changes will not yet be committed on the current run-loop tick. Observe the levels array reactively through SwiftUI’s @Published binding instead.The unlock logic deliberately uses
id-based lookup (firstIndex(where: { $0.id == nextLevelId })) rather than selectedLevelIndex + 1 arithmetic. This makes the unlock safe against any future reordering of the levels array — as long as each Level retains its correct id, the right entry will be found.Private Helpers
These methods are markedprivate and cannot be called directly from views, but they form the core of the real-time feedback loop and are documented here so the full game loop is transparent.
triggerSuccess()
Called by addIngredient(_:) when currentBurgerStack perfectly matches targetRecipeEmojis.
- Increments
ordersCompletedInSessionby 1. - Sets
showPerfectMessage = trueto trigger the success overlay inRecipesView. - Calculates the coin reward: checks whether
shopInventorycontains a"sauce"item withquantityOwned > 0; if so, adds a 10-coin bonus to the base 25. The total is multiplied bycomboMultiplier. Adds the result tocoins. - Increments
comboMultiplierby 1, capped at a maximum of5. - Calls
onRecipeSuccessBonusTime?()unconditionally. IfRecipesViewhas assigned this closure (which it does when the Horno Industrial upgrade is active), the closure fires and adds bonus time; if it isnil, the call is a no-op. - After a 0.8-second
DispatchQueue.main.asyncAfterdelay, resetsshowPerfectMessagetofalseand callsgenerateNextOrder().
triggerError()
Called by addIngredient(_:) when a tap results in an oversized stack or a positional mismatch.
- Sets
showErrorMessage = trueto trigger the error overlay inRecipesView. - Resets
comboMultiplierto1, ending any active combo streak. - After a 0.8-second delay, resets
showErrorMessagetofalseand clearscurrentBurgerStack— the same order remains active so the player tries again from scratch.
setupLevels()
Called once inside init() to populate the levels array. It is never called again at runtime.
- Builds 3 hand-crafted levels with fixed ingredient sets and curated recipe lists (Burger Station, Green Diner, Bacon & Grill).
- Generates levels 4–20 procedurally: ingredient count scales with level number (capped at the full pool of 8 ingredients),
targetOrdersgrows with4 + (i / 2), andbaseTimedecreases usingmax(30, 55 - (i * i / 15))to ensure even the hardest levels always have at least 30 seconds. - Assigns the completed array to
self.levels.