Football played by Jev, TypeSafe AI's System One model

22 models. One ball.

Every player on this pitch is its own Jev call. A few times a second each one gets a typed multiple-choice question — shoot, pass to the 7, press, run in behind — and answers with a probability for every option. Watch all 22 think, or press J and take the number 9 yourself.

Tactics board

Every touch is a multiple‑choice question.

Jev doesn't invent moves. The simulation works out a player's realistic options locally — at most 14 — each with a short label and numeric features: distance, lane clearance, receiver space, success estimate, xG, ETA against the nearest opponent, offside margin. Jev picks among them and returns a probability for each.

h8 CM · has the ball · kind: carrier
1 4 5 6 3 2 8 9 10 7 11 6 8 shoot 5% 5% pass_h10 9% 9% dribble_left 13% 13% pass_h7 27% 27% through_h9 46% 46%
chosen option risky shot run Illustrative position and probabilities. In the match these are 3D ribbons on the grass.
POST /v1/systemone
{ "model": "jev-latest",
  "state": { /* sent once per call: clock, score, ball,
             22 player rows, each asker's option table */ },
  "questions": {
    "h8": {
      "type": "choice",
      "instructions": "You are h8 (home CM). You have
        the ball. Choose the action most likely to
        lead to a goal for your team without losing
        the ball cheaply.",
      "criteria": {
        "through_h9": "Through ball for h9 (ST) · 23 m · open",
        "pass_h7": "Pass to h7 (RM) · 24 m · open",
        "dribble_left": "Dribble left · 7 m space",
        "pass_h10": "Pass to h10 (ST) · 13 m · tight",
        "shoot": "Shoot · 29 m · xG 0.03"
      }
    },
    "a6": { /* press, mark_h9, cover, shape … */ },
    "h9": { /* run_behind, support_near … */ }
  }
}

Request shape from the JevBall source. Values are an illustrative example, not a recorded call. Point at an arrow or a line to match them up.

  1. Options are computed locally

    Geometry, physics and candidate generation never leave the simulation. Offside passes aren't offered at all; a decision with one legal option is never sent.

  2. One batched Jev call

    Everyone whose decision is due shares a single request: match state once, then one question per player. Up to 10 per batch, at most 2 requests in flight. Your API key stays on the dev server.

  3. The choice is applied

    The picked option becomes the player's intent and kicks happen immediately. If an answer is late — 0.9 s, or 0.45 s for the ball carrier — the local policy steps in. Play never stalls.

  4. Reflexes never wait

    Meeting a pass, keeper saves, the first touch, restart distances: plain rules in the simulation. A model round trip is too slow for them, and there is nothing to choose.

Team sheet

22 × Jev

No manager model calls the plays. Each disc is its own question, with its own options and its own probabilities: eleven for Jev United in a 4-4-2, eleven for System One FC in a 4-3-3. Whatever teamwork you see comes out of 22 separate answers.

Jev United 4-4-2 · ids h1–h11

    System One FC 4-3-3 · ids a1–a11

      Hover a disc questions.h9 → { type: "choice", instructions: "You are h9 (home ST). …", criteria: { ≤ 14 options } }
      Ball carrier
      every 0.30 s
      Within 15 m of the ball
      every 0.55 s
      Everyone else
      every 1.2 s

      Cadence is in match time. A turnover or a restart pulls everyone in at once, slightly staggered.

      Touchline

      Watch from the gantry. Or take the number 9.

      Watch

      • Broadcast
      • Tactical
      • Follow
      • Behind goal
      K Decision arrows
      The focused player's options drawn on the grass, with a probability chip on each.
      Player card
      Click a dot on the radar. Every option shows as a probability bar, with a mark on what the local policy would have picked, so you can compare the two.
      Jev feed
      A live ticker of decisions around the ball: h8 CM → pass h9 · 62%
      Under the hood

      The exact Jev payload of the last batch, the response, every player's latest decision, the full match state, and the session cost computed from the token usage Jev reports. Live at 4 Hz, with Freeze, Copy and Download.

      Play

      Press J and the home striker is yours. The other 21 stay on Jev. Press it again to hand him back.

      JTake over #9 / hand back to Jev
      WASD Move, relative to the camera arrow keys work too
      ShiftSprint
      SpacePass
      FShoot or Enter
      QSwitch to the player nearest the ball
      CKP Camera · arrows · pause

      On a phone a thumbstick appears with Pass, Shoot and Switch buttons. Push the stick to the edge to sprint.

      Match stats

      Numbers, honestly labelled.

      Two kinds of figure on this board. A solid line is published by TypeSafe AI about Jev. A dashed line is JevBall's own measurement from one short live run (30 match-seconds, 70 calls, September 2026) — a single sample, not a benchmark.

      Published by TypeSafe AI

      70–500ms
      Response time per call
      $0.042
      Per million input tokens
      $0
      Output tokens are free
      255
      Choices per question, at most. JevBall uses 14.

      Measured by JevBall one short run

      366ms
      Average response per batched call, about six questions each
      ~1,700
      Input tokens per call, as billed by Jev
      ~$0.01
      Per match-minute with all 22 players on Jev
      44%
      How often Jev picked what the local policy would have. It plays its own game.

      In a match, the dock shows the real session total from the token usage Jev reports. On the hosted site, signed-in visitors get a small free credit of live Jev on the house.

      No key?

      The local policy plays instead. A utility + softmax over the same candidates runs all 22 players. Free, and nothing is sent anywhere. It's also what's playing behind the headline on this page.

      Warm-up

      Four lines to kick‑off.

      JevBall is local only: no login, no signup, no credits. Jev calls use your own TypeSafe AI key and billing. The key lives in a gitignored .env and never reaches the browser.

      • No key? Skip line three. The local policy plays all 22.
      • Opens on localhost:5173
      • ?seed=1234 replays the same match
      • ?local=1 forces the local policy even with a key
      ~/jevball
      $ git clone https://github.com/atarikcaliskan/jevball.git
      $ cd jevball
      $ npm ci
      $ cp .env.example .env
      # set TYPESAFE_API_KEY in .env
      $ npm run dev