Slogicmind StudioGet in Touch
Case Study

How We Built an Offline-First Cricket Scorer App with 0ms Latency

May 18, 2026
18 min read
Written by Slogicmind Engineers

How We Built an Offline-First Cricket Scorer App with 0ms Latency

When Slogicmind Studio set out to engineer CricFlow Scorer, our primary design principle was non-negotiable: 100% offline-first reliability.

Cricket matches are played on wide grassy plains, concrete public parks, and remote sports clubs. These are notorious dead zones for cellular networks. If our app required an active internet connection to record scores, calculate strike rotations, or add extras, it would fail tournament coordinators the moment a signal dropped.

Here is the exhaustive engineering walkthrough of how we built a highly reliable, zero-latency offline scoring engine.


1. The Offline Caching Architecture (SQLite Core Engine)

To guarantee that match data is protected against unexpected battery drainage, phone calls, or app suspensions, we bypassed unstable browser memory in favor of an embedded SQLite Database Engine.

  • **Structured SQLite Schemas**: Every delivery, extra run, boundary, wicket, and bowler switch is recorded as an immutable row entry.
  • **Transaction Locking**: Match events are wrapped in secure transactions, ensuring database hydration completes in less than **1 millisecond**.
  • **State Recovery Hydration**: Upon cold launch, the engine reads the active match table, reconstructing the exact player states, run counts, strike coordinates, and bowler registers instantly.
  • -- Explicit SQL database schema models for CricFlow Scoring Engine
    CREATE TABLE IF NOT EXISTS matches (
      id TEXT PRIMARY KEY,
      team_a_name TEXT NOT NULL,
      team_b_name TEXT NOT NULL,
      overs_limit INTEGER DEFAULT 20,
      status TEXT DEFAULT 'active'
    );
    
    CREATE TABLE IF NOT EXISTS players (
      id TEXT PRIMARY KEY,
      name TEXT NOT NULL,
      team_id TEXT NOT NULL
    );
    
    CREATE TABLE IF NOT EXISTS ball_deliveries (
      id TEXT PRIMARY KEY,
      match_id TEXT NOT NULL,
      over_number INTEGER NOT NULL,
      ball_number INTEGER NOT NULL,
      striker_id TEXT NOT NULL,
      non_striker_id TEXT NOT NULL,
      bowler_id TEXT NOT NULL,
      runs INTEGER DEFAULT 0,
      extra_runs INTEGER DEFAULT 0,
      extra_type TEXT CHECK(extra_type IN ('none', 'wide', 'no_ball', 'bye', 'leg_bye')),
      wicket_type TEXT CHECK(wicket_type IN ('none', 'bowled', 'caught', 'run_out', 'stumped')),
      FOREIGN KEY(match_id) REFERENCES matches(id)
    );

    2. Solving The Strike-Rotation Algorithm

    In cricket scoring, tracking which batter faces the next delivery (the striker) and who stands at the opposite crease (the non-striker) is highly complex due to rapid game shifts:

  • **Odd Runs Scored**: A single or three runs require the players to physically swap creases.
  • **Over Completion**: When 6 valid deliveries are bowled, the over ends. The striker and non-striker do not change creases, but a new bowler bowls from the opposite end, meaning the facing batsman swaps positions.
  • **Extras Boundary Cases**: Wides and No-Balls do not count as valid deliveries in the over but can still cause strike shifts if runs are run or boundaries are hit.
  • To ensure 100% mathematical accuracy under MCC regulations, we structured a pure, fully testable TypeScript scoring matrix:

    export interface BatterState {
      strikerId: string;
      nonStrikerId: string;
    }
    
    export interface DeliveryInput {
      runs: number;
      extraType: 'none' | 'wide' | 'no_ball' | 'bye' | 'leg_bye';
      isWicket: boolean;
      wicketType: 'none' | 'bowled' | 'caught' | 'run_out' | 'stumped';
    }
    
    export function computeNextStrikeState(
      current: BatterState,
      input: DeliveryInput,
      ballsInOver: number
    ): BatterState {
      let nextStriker = current.strikerId;
      let nextNonStriker = current.nonStrikerId;
    
      // 1. Calculate physical crease swaps during the delivery runs
      const isCreaseSwapRequired = input.runs % 2 !== 0;
      if (isCreaseSwapRequired) {
        const temp = nextStriker;
        nextStriker = nextNonStriker;
        nextNonStriker = temp;
      }
    
      // 2. Handle specific wicket rotation rules (e.g. Run Out)
      if (input.isWicket && input.wicketType === 'run_out') {
        // Under custom league rules, the surviving batter is calculated based on run coordinates
      }
    
      // 3. Handle over boundary swap (Valid balls only, Wides/No-Balls don't count)
      const isValidBall = input.extraType !== 'wide' && input.extraType !== 'no_ball';
      const nextBallsCount = isValidBall ? ballsInOver + 1 : ballsInOver;
    
      if (nextBallsCount === 6) {
        // Over completes. Rotate striker crease facing side
        const temp = nextStriker;
        nextStriker = nextNonStriker;
        nextNonStriker = temp;
      }
    
      return { strikerId: nextStriker, nonStrikerId: nextNonStriker };
    }

    3. High-Density UI and Hardware Acceleration

    Operating entirely offline allowed us to achieve sub-millisecond rendering loops.

  • **State Decoupling**: Visual components never perform database access. The UI acts as a pure, responsive listener to a fast Zustand memory cache synced to SQLite.
  • **120Hz Animations**: Score summaries, batsman stats cards, and match progress animations utilize **React Native Reanimated** UI-thread worklets to prevent JavaScript main-thread bottlenecks, delivering natively smooth layouts.

  • 4. Key Takeaways for Offline-First Mobile Architectures

  • **Avoid AsyncStorage for Complex Relational Data**: It lacks transaction safety. Use SQLite or WatermelonDB.
  • **Decouple Game Logic from View Trees**: Keep mathematical loops in pure, functional files that can be fully covered by unit tests.
  • **Optimistic UI Synchronization**: Queue match payloads locally when offline. Hydrate these queues silently to the cloud API when cellular networks resume.
  • Liked our engineering breakdown?

    We white-label full custom architectures for mobile apps, Next.js sitemaps, and score engines.

    Inquire About Custom Projects