Drag the players. Watch the value.

Every position below is scored by a trained neural-network value function V(s) ∈ [−1, +1] — the model's estimate of who scores next. Drag any player or the ball and the value updates instantly. Alongside it you can read interpretable shape descriptors (stretch, width, block area, line height). runs entirely in your browser

research preview Trained on a symmetric soccer simulator, with the x-flip + team-swap symmetry enforced (a mirrored position is exactly negated, so a balanced shape reads 0). See About for the model and its limits.

redevenblue

How to read it: open goals and overloads register clearly (±0.6); a lone attacker against an intact block reads near 0 — the model is possession-aware, not a naïve "ball is forward, so good." Pull the keeper or a defender out of position and watch the value climb.

What am I looking at?

MettleNet — a small demo network. A permutation-invariant Deep-Sets value net: a per-player encoder summed over each team, feeding a value head. V = 2·σ(logit) − 1 is then antisymmetrized over the x-flip + team-swap symmetry, so a mirror-balanced position reads exactly 0 and V(s) = −V(swap s) holds by construction. +1 means blue is favored to score next, −1 means red.
The probes. Interpretable formation descriptors — stretch (spread about the centroid; low = compact), width, depth, convex-hull area, line height — computed live so you can connect a shape change to a value change.

The exact same network runs three ways — PyTorch (training), numpy (the pitchperfect package), and the JavaScript on this page — verified identical to ~1e-6 by the parity test. See About for how it fits together, or the free-kick application for a related value-based study.