farkle

Farkle — Dev Design

Implementation companion to FUNCTIONAL_SPEC.md. This document is implementation-only; functional rules live in the spec.

1. Stack

2. Repository layout

farkle/
  Farkle.xcodeproj
  Farkle/
    App/
      FarkleApp.swift                 // @main + scene + ModelContainer wiring
      RootView.swift                  // routes onboarding / home
    DesignSystem/
      Theme.swift                     // colors, typography
      Fonts.swift                     // font registration
      PaperBackground.swift           // paper-grain modifier
      FeltBackground.swift            // felt-table modifier (future)
      Buttons.swift                   // WalnutButton, ChipButton
      DieView.swift                   // bone die with pips
      AvatarView.swift                // initial-circle avatar
      BigScoreText.swift              // tabular display number
      Confetti.swift                  // particle overlay
    Models/
      Player.swift
      HouseRules.swift
      Game.swift
      Turn.swift
      ActionLog.swift                 // ActionLogEntry + Undo
      ScoreHelperEngine.swift         // combo detection
      Persistence.swift               // SwiftData ModelContainer factory
    Features/
      Onboarding/OnboardingView.swift
      Home/HomeView.swift
      NewGame/NewGameView.swift
      ActiveGame/
        ActiveGameView.swift
        NowRollingBanner.swift
        PendingTurnCard.swift
        StandingsLadder.swift
        RecentActionsLog.swift
        BankConfirmSheet.swift
        ScoreHelperSheet.swift
        KeypadSheet.swift
      GameOver/GameOverView.swift
      History/HistoryView.swift
      Stats/StatsView.swift
      Settings/SettingsView.swift
      Rules/RulesView.swift
    Resources/
      Fonts/                          // .ttf files bundled
      Assets.xcassets                 // colors, app icon
  FarkleTests/
    ScoringTests.swift
    GameFlowTests.swift
    UndoTests.swift
  README.md
  FUNCTIONAL_SPEC.md
  DEV_DESIGN.md

3. Data model

3.1 SwiftData entities

@Model final class Game {
    @Attribute(.unique) var id: UUID
    var name: String                // auto-generated "Tuesday Night Roll"
    var createdAt: Date
    var endedAt: Date?
    var targetScore: Int
    var rules: HouseRules           // value-type, codable, stored as JSON
    @Relationship(deleteRule: .cascade) var players: [Player]
    @Relationship(deleteRule: .cascade) var actions: [ActionLogEntry]  // ordered
    var activePlayerIndex: Int
    var pendingTurnScore: Int       // dice-not-banked-yet
    var pendingRollCount: Int
    var finalRoundTriggeredBy: UUID?  // player id; nil until target hit
    var finalRoundTurnsRemaining: Int
}

@Model final class Player {
    @Attribute(.unique) var id: UUID
    var name: String
    var avatarIndex: Int            // 0..7 maps to AVATAR_COLORS
    var orderIndex: Int             // turn order in this game
    var bankedScore: Int            // derived but cached for perf
}

@Model final class ActionLogEntry {
    @Attribute(.unique) var id: UUID
    var game: Game?
    var playerId: UUID
    var kind: ActionKind            // .bank, .bust, .startFinalRound, .endGame
    var amount: Int                 // 0 for bust
    var timestamp: Date
    var orderIndex: Int             // monotonic per game
    var roundNumber: Int
    var hotDice: Bool               // marked at bank time
}

enum ActionKind: String, Codable {
    case bank, bust, startFinalRound, endGame
}

struct HouseRules: Codable, Equatable {
    var threePair: Bool = true
    var straight: Bool = true
    var twoTriples: Bool = false
    var mustOpenWith: Int? = 500    // nil = no minimum
}

3.2 In-memory state vs. persisted state

3.3 Banked score recomputation

4. Undo system

4.1 Mechanism

4.2 Edge cases

4.3 Logging cost

5. Score helper engine

Pure value-type engine, fully unit-tested.

struct ScoreHelperEngine {
    let rules: HouseRules
    func score(dice: [Int]) -> ScoreBreakdown
}

struct ScoreBreakdown {
    let combos: [Combo]   // [(name: "Three 5s", points: 500)]
    let total: Int
    let usesAllDice: Bool // for Hot Dice marking
}

Rules implemented:

6. Design system implementation

6.1 Colors (Theme.swift)

Hard-coded Color extensions mapped to the Felt & Bone palette. Defined for both light only (v1 has no dark mode — paper is the brand).

6.2 Typography

6.3 Backgrounds

6.4 Components

6.5 Animation

7. Navigation

8. Persistence and migration

9. Accessibility

10. Testing strategy

11. Out-of-scope reminders

Anything in FUNCTIONAL_SPEC.md §2.1. When in doubt, ship the spec, not the design canvas. The canvas has 14 screens; we ship 11.


Change log