I'm a solo dev and I just shipped Efectazo, a free free-kick football game that runs in the browser, on phones and desktop: https://efectazo.pages.dev
You swipe to shoot, and the shape of your swipe becomes curl on the ball. Here's how the main pieces work.
The ball: gravity, drag and a Magnus force
The physics module is plain JS with no three.js in it, so I can run it headless in tests. Each substep adds three forces to the ball:
// Magnus: CM * (w x v)
export function accel(b, wind) {
const [vx, vy, vz] = b.v;
const rx = vx - wind[0], rz = vz - wind[1];
const sp = Math.hypot(rx, vy, rz);
const [wx, wy, wz] = b.w;
const mx = wy * rz - wz * vy, my = wz * rx - wx * rz, mz = wx * vy - wy * rx;
return [-KD * sp * rx + CM * mx,
-G - KD * sp * vy + CM * my,
-KD * sp * rz + CM * mz];
}
Quadratic drag slows the ball, and the cross product of spin and velocity pushes it sideways (side spin) or down (topspin dip). Spin decays exponentially, so the bend gets stronger late in the flight, which is what makes a good free kick look right.
From swipe to shot
- Direction comes from the first 40% of the swipe
- Power from swipe speed, height from swipe length
- Side spin from how much the swipe curves
So if you draw a banana, the ball bends like one.
The goalkeeper
The keeper has a reaction delay, predicts where the ball will cross the line (better keepers read the curl better), and dives with limited speed and reach. A save only happens when the ball actually hits his limbs, so it never feels scripted. The wall (0 to 6 players) jumps when you kick.
Rendering
- three.js r160, MeshStandard/Physical materials, PMREM image-based lighting
- Two shadow-casting "floodlight" directional lights with PCF soft shadows
- A procedural grass shader (mowing stripes plus detail noise) instead of a big texture
- ACES filmic tone mapping, bloom, and a slow-motion replay with depth of field after goals
- Quality tiers with an Auto mode that drops a tier if the frame rate stays under ~47 fps for 2 seconds, which matters a lot on phones
The game around it
40 career levels, a seeded Daily Challenge (5 shots, with an emoji grid you can share), an endless Arcade mode and Cups. Coins unlock balls, boots, kits, stadiums (night, day, sunset, rain, snow) and celebrations. English and Spanish. It's free, with an optional one-time Pro upgrade.
Play it here: https://efectazo.pages.dev (also on itch: https://nightlit.itch.io/efectazo)
I'd love to hear how it runs on your device and how the curl feels. Happy to go deeper on any part in the comments.













