How we built Find Freedom: A browser game in React

Find Freedom is a browser-based interactive game built by Kormoan for India’s Independence Day 2026, using React, TypeScript, custom SVG illustrations, and a real-time game loop.

This year, instead of a greeting, Kormoan shipped a game.

Not a prototype. Not a concept. A fully playable browser experience live on the homepage for Independence Day built in React, rendered on a white canvas, and working on every device without a single download.

Here is how it came together.

A runner was all we needed to start

The centrepiece of Find Freedom is a running figure seen from behind, mid-stride, wearing a race bib that reads 80. Every detail is hand-coded SVG: the shirt’s spine crease, the shoulder-blade hints, the knee ellipses, the shoes at toe-off and heel-strike. No image files. No sprite sheets. Just <path> elements, stroke, strokeWidth, and fill=”white” the same editorial line-art language that runs through everything Kormoan produces visually.

When the runner moves, a bounce animation fires. When they stop, an idle sway takes over. Two dust puffs appear at the feet on each stride. None of this is a GIF. It is all CSS keyframes applied to a living SVG component.

Building a world that never ends

The ground is an infinite white plane. A pool of 100 decorative elements grass tufts, round bushes, pebble clusters, spiky plants surrounds the runner at all times. Each one is its own SVG component, six variants in total, drawn with the same bold line weight as the character.

The perspective system is custom. Every world object is projected to screen using a behind-the-camera model: forward distance and lateral offset are calculated relative to the runner’s current position and heading, then mapped to screen X and Y using a CAM_DIST / (fwd + CAM_DIST) scale factor. Objects close to the runner are large. Objects near the horizon are small. The horizon sits at 34% from the top of the screen. The runner sits at 68%. Everything between them is the world, scaling continuously as you move.

Ground elements recycle. The moment any item drifts beyond a set radius, it is respawned ahead of the runner’s current heading so the world never empties, regardless of how far or how long you run.

Not finding freedom was the whole point

One word exists in the world at any given time. It spawns between 900 and 1500 world-units ahead, within ±86 degrees of the runner’s forward direction. Always visible or near-visible on the horizon. It is projected to screen using the same perspective maths as the ground elements, scales as you approach, and dissolves when collected.

The font is Luckiest Guy. The word floats on a gentle sine animation. When the word is FREEDOM, it pulses differently with a stronger shadow, a thicker stroke, its own keyframe because it needs to feel like the thing worth chasing.

A direction arrow sits at the screen edge, ray-cast from center to the target’s projected position, rotated to point directly at it. When FREEDOM is the target, the arrow glows red.

When the runner reaches the word, it dissolves with a glitch animation, a full-screen overlay flashes the word at clamp(72px, 14vw, 160px), and a message banner drops from the top with what was actually found. FREEDOM, specifically, holds for a beat then glitches into something else entirely.

One thumb. Anywhere on the screen.

On desktop: arrow keys. On mobile: a virtual joystick built with Pointer Events. Touch anywhere on screen, drag vertical drag controls speed, horizontal controls steering. The knob clamps to a 56px radius and normalises the vector, so diagonal input splits cleanly between acceleration and turn. No separate buttons. No d-pad. One thumb, anywhere.

The joystick uses setPointerCapture so drag tracking continues even if the finger drifts off the element. touchAction: none on the overlay prevents scroll interference. visualViewport handles the keyboard-up resize on iOS without the layout jumping.

The stack

React with TypeScript. Vite for bundling. The entire game loop runs inside a useEffect with requestAnimationFrame. Physics, projection, collision detection, and ground recycling all happen in a single ref-driven loop that never touches React state keeping renders fast and the frame rate stable. State updates (messages, word count, overlays) are dispatched only on game events, not every frame.

The final build is one HTML file with inlined assets. No backend. No API. Deployed directly to WordPress via iframe. The game sits on the homepage, full viewport, no scrollbars, no chrome. Two lines of embed code.

What this demonstrates

Kormoan builds digital products and brand experiences for enterprises and growth-stage companies. The kind of work that has to function precisely, load fast, feel considered, and hold up under real users on real devices.

Find Freedom is a small demonstration of how that thinking applies even when there is no client brief. Custom rendering pipeline. Hand-drawn SVG assets. A physics loop decoupled from the render cycle. A mobile input system that actually works. A concept that communicates without explanation.

Every project we take on from UI/UX design to AI-integrated product experiences goes through the same rigour. The brief changes. The standard does not.

Play the game at kormoan.in. Arrow keys on desktop, hold and drag on mobile. Keep running.

If you are building something worth getting right.

Ask about us, your product, challenge, or idea...