TECHNICAL · DELIVERY · LEAD ·
iOS · WEB · AUTOMATION · AI · DOCKER · REACT · NODE ·
PRODUCT ARCHITECTURE · TEAM LEADERSHIP · MANAGEMENT ·
0%
←All projects
Mini-Games Inside the Zetter Loyalty Programme — Three Games, Three Ways to Prove Fair Play

Mini-Games Inside the Zetter Loyalty Programme — Three Games, Three Ways to Prove Fair Play

2026Full Cycleb2c-apps

Role

Full cycle: product decisions, anti-cheat architecture, development and acceptance.

Tech

Layer Choice
Games and engines TypeScript in a shared package, one body of code on client and server
Stacker physics Custom, integer-based: fixed step, six solver iterations, square root the only floating-point operation
Fair play Server as the opponent, hidden solution, replay from a seed and a move log
Puzzle Ported donor engine — all 82 of its tests passed without a single edit
Client React, Telegram Mini App, canvas for the stacker, CSS grid for the rest
Server Node and Prisma, PostgreSQL
Economy An idempotency key on every charge, compensating credit when a payout fails

Key features

  • 01Three new games alongside match-3
  • 02Three different models of proving fair play
  • 03Physics written in integer arithmetic
  • 04Shared economy and quests
  • 05Analytics and segments per game
01

Problem

A loyalty programme needs a reason to be opened today, not eventually. One match-3 game gave people that reason — and then ran out of it: once you had played through it, you stopped coming back.

Adding more games sounds simple right up to the moment you ask what people are playing for. Progress earns keys, keys buy real gifts — candles, tote bags, merch. So every new game is not entertainment, it is a new place where cheating pays. And each one has to be checked on its own terms: what works for a logic puzzle is meaningless for a physics stacker.

There was a second problem, visible only from the inside. The code already assumed there was exactly one game: an event belonged to a game if its name carried the right prefix. That field did not feed analytics — it fed the player activity state that the mailing automation reads. Somebody playing a different game every day would have been filed as "hasn't played in a while" and sent an email asking them to come back.

02

Audience

Role Use case
Brand manager More reasons to return: four games rather than one, and weekly quests can be run per game.
Marketer Mailing segments by progress in a specific game — "reached level 10", "Suika record of at least N".
Product manager Per-game metrics: who plays what, where they drop off, which mechanic holds attention.
The next developer One slug per game across every layer — event, route, idempotency key, asset catalogue. A new game goes into the registry, not into seven separate lists.
03

What's different

Compared to bolting on an off-the-shelf game: A ready-made game arrives with a client-side score you cannot trust. Here each genre got the trust model that fits it, and in none of the three does the client report its own result.

Compared to physics on a general-purpose library: General-purpose engines compute in floating point, and floating point does not reproduce identically across machines. A replay would drift from the original, and the system would read honest wins as cheating. So the physics is written in integers: fixed time step, fixed iteration order over bodies. The side benefit is 90 KB off the bundle.

Compared to "one game, then another one": The games were added through a shared registry rather than bolted on beside each other — and that registry fixed a defect the mailing pipeline already had. Economy, quests and progress are common, so a new game inherits them for free.

Balance verified by simulation, not by feel: Adaptive difficulty in tic-tac-toe behaved like a ratchet. The player always moved first and lost 0.3% of games, so the "lost a game, ease off" branch almost never fired, and the ladder was climbed in four games. The first move now alternates, there are five rungs instead of three, and a loss steps down one rung instead of two. The balance is pinned by a simulation test.

04

Screenshots

05

Customization

  • 01The set of games — a registry in one file, one slug across every layer
  • 02Game names and their order on the selection screen
  • 03Quest conditions: score, tier, merge count, wins in a row, levels solved
  • 04Prices of paid actions — undo, hint, piece reroll
  • 05Opponent difficulty: number of rungs, step up and step down
  • 06Character and background assets — swapped by filename, no code changes

Need something like this?

Tell me about the task — I'll suggest an approach, pick a stack and scope it out.