/work Systems

Real-Money Gaming Backend

Backend systems for real-money gaming (Ludo + cards) — transaction integrity, fairness, anti-cheat, regulatory considerations.

Role
Senior Engineer
Period
2018 — 2021
Status
NDA-Trimmed
Distributed Systems Transactional Integrity Anti-Cheat Regulatory Compliance

Scope

Game-state and transaction systems where every balance-changing action must be explainable

Owned

  • Transactional integrity and idempotency
  • Game-state and wallet boundaries
  • Fairness, anti-cheat, and audit surfaces

Constraints

  • Retries must never duplicate a monetary effect
  • Game outcomes and wallet movements need durable traceability
  • Untrusted clients cannot own authoritative state

Decisions

  • Append-only ledger as the source of financial truth
  • Idempotency keys around every balance-changing command
  • Separate game simulation from wallet settlement

Outcome

  • Operated real-money game flows with auditable transaction boundaries

Volumes, providers, and security controls are intentionally omitted.


Case study narrative

Why the boundary matters

A real-money game joins two systems with different semantics. The game engine reasons about turns, timeouts, moves, and outcomes. The wallet reasons about immutable entries, balances, settlement, and reconciliation. Combining them into one mutable state object makes failures difficult to explain and retries dangerous.

The architecture separates game authority from monetary authority and connects them through idempotent commands and durable events.

System architecture

Game state and monetary state

  1. Untrusted client Submits signed intent; never submits an authoritative outcome Trust boundary
  2. Game service Validates membership, turn, rules, and server-owned state Game authority
  3. Outcome service Finalizes a result once and emits a durable settlement command Finality boundary
  4. Wallet service Applies idempotent debit and credit entries Money authority
  5. Ledger Append-only entries with references and reconciliation state Source of truth
  6. Audit/operations Explains a game, command, and balance movement end to end Evidence boundary
Illustrative logical architecture. Payment providers, security topology, and operating volumes are intentionally omitted.

Idempotent settlement

Networks retry. Workers restart. Clients repeat actions. The settlement path must treat duplication as a normal input rather than a rare bug. Every balance-changing command carries a stable key derived from the business event, not from an individual HTTP request.

type SettlementCommand = {
  idempotencyKey: string; // game:{gameId}:settlement:v1
  gameId: string;
  resultVersion: number;
  entries: Array<{ accountId: string; direction: "DEBIT" | "CREDIT"; amount: Money }>;
};

// Illustrative only — transaction details are simplified.
async function settle(command: SettlementCommand) {
  return database.transaction(async (tx) => {
    const existing = await tx.settlements.find(command.idempotencyKey);
    if (existing) return existing.result;
    assertBalanced(command.entries);
    const result = await tx.ledger.append(command.entries);
    await tx.settlements.record(command.idempotencyKey, result);
    return result;
  });
}

The ledger entries must balance and the idempotency record must be committed atomically with them. A retry returns the original result without creating a second financial effect.

Request sequence

Game completion and settlement

  1. 01
    Game servicefinalizes outcome

    Persists a server-authoritative result with an immutable result version.

  2. 02
    Outcome servicecreates settlement command

    Builds balanced entries and a stable idempotency key.

  3. 03
    Walletchecks prior execution

    Returns the existing result if this business command already succeeded.

  4. 04
    Ledgerappends entries

    Commits debit and credit records without mutating historical entries.

  5. 05
    Reconcilermatches result and money

    Flags missing, duplicate, or mismatched references for operations.

A settlement can be retried safely because the durable game result and wallet command each have stable versions and identities.

Fairness and anti-cheat surfaces

Fairness is a chain of custody. Randomness must be generated or verified on trusted infrastructure, game rules must be deterministic for the same authoritative inputs, and the server must reject client state that attempts to skip valid transitions.

Anti-cheat design focuses on signals rather than a single detector:

  • Impossible action sequences or timing.
  • Client state inconsistent with the authoritative version.
  • Repeated disconnect patterns around unfavorable outcomes.
  • Device or account relationships that require risk review.
  • Result distributions that diverge from expected game behavior.

The enforcement path should be separate from the signal path. Signals can be collected and scored without allowing one noisy rule to directly seize funds or permanently block a player.

Tradeoff matrix

Financial source of truth

OptionStrengthsCostsDecision
Mutable balance only Simple reads and minimal storageWeak auditability and difficult reconciliationRejected
Append-only ledger + balance projectionChosen Traceable entries, replay, reconciliation, and explicit correctionMore operational and consistency workSelected
Game record as wallet truth One domain recordCouples money to game lifecycle and retry semanticsRejected across the boundary
The selected append-only ledger makes correction explicit and preserves the historical explanation of a balance.

Audit and failure recovery

An operator should be able to start from a user-visible complaint and follow references through game, outcome, settlement command, ledger entries, and reconciliation status. Correlation identifiers are domain identifiers—game ID, result version, settlement key, ledger entry IDs—not just infrastructure trace IDs.

Corrections are compensating entries, never edits to history. If an outcome is overturned, the system records why, who authorized it, the original references, and the new entries. This preserves both the financial state and the explanation.

Representative failure handling includes:

  • Outcome persisted but command publication delayed: recover from an outbox or reconciliation scan.
  • Wallet applied but response lost: retry returns the existing idempotent result.
  • Invalid unbalanced command: reject before writing any entries.
  • Game and settlement disagree: quarantine for review instead of guessing.
  • Downstream reporting delayed: replay from the ledger without changing balances.

Outcome and lessons

The system supported real-money game operations with explicit transaction, fairness, and audit boundaries. Public details are intentionally limited to architecture and engineering decisions.

Bounded proof

Operational guarantees

Retries
One effect

Stable idempotency keys prevent duplicate balance changes.

Audit
End-to-end

Game results and ledger entries share durable business references.

Correction
Append-only

Compensating entries preserve the original financial history.

These describe design properties, not undisclosed transaction volume or security controls.

The most durable lesson was that “exactly once” is not a transport feature. It is a business invariant assembled from stable identities, atomic writes, durable evidence, and safe retries.


Want to discuss this work in more detail? Get in touch.

Back to all work