Replay from an older engine version — result may differ from the recorded score.
GOAL!
Guide
What is this?
A 4v4 top-down arcade soccer game. You can play it yourself (1 or 2 players on one
keyboard), but the heart of it is the AI League: everyone's team runs on
the exact same game engine — what makes your team yours is the configuration you
build in the Team Builder. Tune it, publish it, and climb the Elo leaderboard by beating
other people's teams in simulated matches.
Playing a match
Controls are listed on the main menu and the pause screen (Esc pauses). The mechanics behind them:
Shooting — hold the shoot key to charge power; the aim arrow (toggle on the menu) shows the direction while charging.
Sprint & stamina — sprinting drains your stamina bar; completing a pass refills it. Manage it or you'll be jogging when it matters.
Stealing — press shoot while not holding the ball to lunge for a steal from a nearby carrier. Missing puts steals on cooldown for your team.
Player switch — Auto switches you to the player nearest the ball; Stay keeps your player and the pass key cycles teammates.
Keeper box — the small inner box in front of each goal. While a keeper holds the ball inside it, possession is protected: no steals, a moment to pick a clearance.
Goalie — Swappable lets you jump to/from your keeper; Always AI leaves keeping to the machine.
Team Builder
Your team is a config document: a formation, seven tactic dials, and player attributes.
The engine is identical for everyone, so matches are decided purely by how you tune it.
Formation — where your three outfielders anchor (Standard, Attacking, Defensive, Wide). Anchors shift with the ball and push up in possession.
Shot range — how far from goal your AI is willing to shoot. Long range means more shots, worse ones.
Press distance — how close an opponent must be before your carrier feels pressed and looks to move the ball.
Possession push — how far the whole formation pushes upfield when you have the ball (and drops back when you don't).
Through-pass gain — how much further upfield a teammate must be to earn a through ball. Lower = more ambitious passing.
Steal cooldown — how often your defenders attempt steals. Aggressive stealing wins balls and gets beaten.
Keeper clear delay / keeper hold — how long your keeper waits before clearing, and how long they'll hold the ball in the protected box.
Attributes — each of your 4 players gets pace, stamina, power, and control (0–10, 5 is neutral), from a shared 80-point budget. You can't max everything: a fast team is a weak-shooting team somewhere else.
Test before you publish: Watch Match pits your team against a preset
(Aggressive, The Wall, Balanced, Default) AI-vs-AI, and Play Match lets
you take the field against your own creation. Your team saves locally in the browser —
no account needed until you publish.
AI League
Publishing — sign in with an email magic link, pick a username, and publish. Your team immediately plays ~5 placement matches against similarly rated teams.
Ratings — standard Elo, everyone starts at 1000, K=32, zero-sum: what you win, your opponent loses. Beating stronger teams pays more.
Challenges — hit Challenge on any leaderboard row to play them now. Each team is capped at 10 ranked matches per hour.
Fair play — ranked matches are simulated on the server with a server-chosen random seed. Your browser never reports results, so there's nothing to cheat.
Replays — the sim is deterministic: from the stored seed and both configs, your browser re-runs any ranked match move-for-move. Use match history to scout why you lost.
Play — the Play button on any leaderboard row starts an unranked match: you, against their published team.
Updating — re-publishing uploads your latest tuning; old matches keep the config snapshot they were actually played with.
Bot teams — leaderboard owners starting with house- (like house-default or house-wall) are built-in bot opponents seeded to populate the ladder, not real players.
Under the hood
The game is a static site (vanilla JS + Canvas). Accounts, the leaderboard, and ranked
simulation run on Supabase; the server runs the same engine code your browser does.
Because every match is reproducible from its seed, replays need no video and the
leaderboard needs no trust in players. Inspired by Berkeley Pac-Man capture tournaments —
same agents, different weights, may the best config win.