Skip to main content

Documentation 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.

ShopView is ChefDash’s in-game economy screen, where players convert the coins they earn from completing burger orders into single-use power-ups called consumables. Each consumable grants a specific in-round advantage — more time on the clock, a head-start combo multiplier, or extra coins per perfect serve — and stacks in the player’s inventory until equipped in the pre-game modal on MainMapView. The screen becomes active when gameState.activeTab is set to "cart.fill". The header uses the same two-column HStack pattern seen on the Map screen. On the left, a monospaced SUMINISTROS DISPONIBLES label sits above the Tienda de Mejoras title. On the right, a neonYellow capsule shows the live coin balance from gameState.coins, updating immediately as purchases are made.

Shop Items

The three items are seeded directly into gameState.shopInventory at GameState.init() and rendered via ForEach(state.shopInventory). Each card is a rounded rectangle (cornerRadius: 18) with a cardBackground fill (0.14, 0.14, 0.18).

Available Items

ItemEmojiIDPriceUpgradeTypeEffect
Horno Industrial🌋oven50 🪙.extraTime+15 s extra time for the current round
Cuchillo Afilado🔪knife30 🪙.comboBoosterStart the round with combo ×2
Salsa Secreta🥫sauce40 🪙.instantServe+10 coins per perfect burger served
The UpgradeType enum has an instantServe case, but in GameState.triggerSuccess() the Salsa Secreta bonus is applied by checking shopInventory directly for a non-zero quantityOwned on the "sauce" item — it grants +10 coins per perfect order on top of the base 25-coin reward, multiplied by the current combo.

Shop Row Layout

Each row is built by the private shopRow(for:state:) view builder and contains four elements from left to right:
  1. Emoji icon — 34 pt inside a 64×64 pt RoundedRectangle tile with a dark background
  2. Text stackitem.title uppercased in white monospaced, item.description in 50% white, and "En inventario: X" count in orangeAccent
  3. Spacer
  4. Buy button — shows the label COMPRAR and the price (X 🪙)

Purchase Logic

The buy button is disabled when the player cannot afford the item:
let canAffordItem = state.coins >= item.price

Button(action: {
    if state.isHapticsEnabled {
        UIImpactFeedbackGenerator(style: .medium).impactOccurred()
    }
    if let index = state.shopInventory.firstIndex(where: { $0.id == item.id }) {
        state.coins -= item.price
        state.shopInventory[index].quantityOwned += 1
    }
}) { ... }
.disabled(!canAffordItem)
When canAffordItem is false, the button background switches from orangeAccent to Color.white.opacity(0.05) and the drop shadow is removed, giving clear visual feedback that the item is unaffordable. The purchase writes directly to state.shopInventory[index].quantityOwned inline — no separate method is called on GameState.

Haptics on Purchase

If gameState.isHapticsEnabled is true, a .medium style UIImpactFeedbackGenerator fires on every successful purchase. This is the same style used for level node taps on the map.
Buy upgrades before attempting higher levels. Levels 4 and above increase target orders and reduce base time — the Horno Industrial (🌋) is particularly valuable in the later stages of the procedurally generated levels (Kitchen Arcade Expo 10 onwards) where baseTime can drop as low as 30 seconds.

ShopItem Model

Items are defined by the ShopItem struct in ShopItem.swift:
struct ShopItem: Identifiable {
    let id: String
    let title: String
    let description: String
    let emoji: String
    let price: Int
    let type: UpgradeType

    var quantityOwned: Int = 0
}
quantityOwned is the only mutable property — all other fields are constants set at initialisation in GameState. There is no upper limit enforced on how many copies of a single item can be purchased.

Build docs developers (and LLMs) love