Quick answer: Feature flag systems start simple and become permanent infrastructure. A 30-line JSON-backed implementation handles 90% of indie use cases - here's the shape that doesn't grow into a problem.

Most studios don't need LaunchDarkly. They need a flag file the server can update and the client can poll on launch.

Single JSON, polled on launch

{ "new_matchmaker": true,
  "dlc_rev2_enabled": false }

Fetch once on startup; cache locally as a fallback for offline. 95% of flag use cases boil down to this.

Per-user gates via hash

For staged rollouts: hash(user_id + flag_name) < rollout_percent * 1.0. Stable across launches, no per-user record needed.

Sunset every flag

Add a created_at field. Any flag older than 90 days requires removal-or-rejustification. Otherwise flags accumulate forever.

Avoid feature-flagged code paths in hot loops

Read the flag once, branch the whole subsystem. Per-frame flag reads are cheap but they encourage permanent branching that's hard to audit.

“Feature flags are tech debt with a paper trail.”

If you find yourself needing per-customer flags, segmented rollouts, and A/B test integration, then buy. Until then, the 30-line version is enough.