Skip to content

Repository files navigation

Touchline

A fast football management prototype focused on visible tactical consequences, squad mood, and a compact season loop.

Current Slice

  • 20-club Premier League snapshot with real player names, positions, and club badges
  • Club switching, board trust, fan mood, budget, standings, and fixtures
  • Matchday Hub with opponent brief, readiness checks, tactical plan, and team sheet
  • Manual starting XI selection with legal formation validation
  • One-click recommended XI
  • One-click full-season simulation that fills the remaining 38-match league schedule and lands on the final table
  • Tactical controls for formation, mentality, pressing, tempo, and defensive line
  • Training focus that affects player attributes, morale, and fitness
  • Phase-based match simulation with buildup, midfield duels, final-third entries, box entries, counters, xG, pressure, and tactical reports
  • Spatial replay trace with real starters, ball position, player intent, and phase-aware movement
  • Animated 2D canvas pitch on the match view
  • Captain selection, player form, morale, fitness, value, and wages
  • FIFA/Football Manager-style player model with 0–99 OVR, potential, and position-specific technical, mental, physical, defensive, attacking, and goalkeeper attributes
  • Local save/reset through browser storage
  • Season rollover after the fixture list completes
  • Analytics Lab with selected-club match, event, replay-frame, and player-rating aggregates
  • Season Command Center with ClickHouse-backed round charts, historical league-table slider, match replay links, and player development deltas
  • Run-aware season sync with a stable career/season ID, progress feedback, standings snapshots, and player development snapshots for ClickStack exploration
  • Brainstore signal room that combines ClickHouse football facts with PromQL health and performance lenses

The 2026/27 Premier League roster snapshot is pinned in src/game/premierLeagueData.ts. Player names, positions, age, availability, and recent form inputs come from the Fantasy Premier League bootstrap feed captured on 2026-08-02; badge images use the API-Football crest CDN. OVR and potential are derived game ratings rather than official EA or Football Manager ratings. Match events, player ratings, and tactical outcomes remain simulated so the local demo is deterministic and can feed the ClickHouse and Iceberg pipeline without live-match credentials.

Screenshots

Squad Room

Touchline Squad Room

Real Data Explorer

Touchline Real Data Explorer

Analytics Platform

The optional local stack turns the game into a small football data platform. It is designed to be easy to run locally and easy to inspect when something goes wrong.

Product data

  • Touchline app: sends match, event, player-rating, replay-frame, standings, and player-development streams.
  • Run-aware careers: every season sync gets a stable career/season ID, progress state, standings snapshot, and player-development snapshot.
  • Action feed: possession IDs, sequence IDs, player IDs, pass recipients, coordinates, outcomes, and qualifiers are stored for explainable football analysis.
  • Lakehouse path: Arrow-shaped batches are written through Iceberg REST to MinIO for source history and replayable snapshots.

Start it from the project root:

docker compose up --build

The service listens on http://localhost:8787. The game still runs without the stack; the Analytics Lab will show an offline state until the service is available.

Simulated-career analytics

  • Run registry: GET /api/analytics/runs shows season-sync progress and status.
  • Season comparison: GET /api/analytics/season-comparison?career_id=...&club_id=... compares seasons in one career.
  • Tactical matchup: GET /api/analytics/tactical-matchup?run_id=...&club_id=... compares every opponent; add opponent_id for one matchup.
  • Explainability: ClickHouse facts preserve tactic settings, player minutes, shots, goals, event xG, press wins, buildup failures, and box entries.
  • Self-join lab: the tactical matchup endpoint compares club-relative facts in ClickHouse, making the simulator's tactical ledger inspectable instead of hiding it in UI state.

Real event data

  • StatsBomb Open Data: node scripts/import-statsbomb.mjs --limit=20 imports a deterministic public 20-match slice.
  • Fast demo: node scripts/import-statsbomb.mjs --match-id=3754217 loads the Chelsea–Arsenal sample.
  • Real-data UI: the Analytics tab exposes a match selector, shot map, pass links, player action profiles, and source-event provenance.
  • SQL lab: analytics/real-data-lab.sql contains the matching ClickHouse/ClickStack exercises.
  • Tournament workload: node scripts/import-worldcup2026.mjs loads the 104-match, 48-team openfootball snapshot into separate match and goal facts.

The real-data path stays isolated from simulated career data. Every row retains provider, season, match, player, team, possession, coordinate-system, and source-event provenance. The importer also maps each involved player to a primary role from action evidence, which gives the future scouting and lineup systems a useful starting point.

Brainstore: ClickHouse + PromQL

  • ClickHouse is the fact store: raw events, simulated facts, real-data actions, and minute-level rollups live here.
  • The real-data rollup: touchline_real_match_team_minute_v2 aggregates additive actions by match, team, and minute before metrics are exported; distinct possessions stay at raw match/team grain.
  • Prometheus is the signal layer: the analytics service exports bounded team/match gauges instead of individual events, including a real-time ClickHouse reachability gauge.
  • PromQL recording rules: reusable ratios cover pass completion, pressure per possession, advanced-zone share, shot quality, and actions per possession.
  • Alerts: Prometheus watches ClickHouse reachability and exporter collection errors.
  • Brainstore UI: the tab shows manager-facing signals with the PromQL expression beside each number.
  • Boundary: ClickHouse answers detailed football questions; Prometheus answers “is this signal healthy or changing?” without becoming a second event warehouse.

The Action intelligence panel reads GET /api/analytics/action-insights and turns the structured feed into pass completion, progressive passing, possession volume, shot xG, action mix, passing connections, and a manager-facing analyst note.

Open http://localhost:9090 to explore raw PromQL, or use the Brainstore tab for the signal room. The backend also exposes simulated-career lenses for ClickHouse pulse, round progress, xG edge, press conversion, action density, and ingestion freshness.

The Real Data view extends the same pattern to imported StatsBomb matches. /api/analytics/real-data/brainstore?source=statsbomb&source_match_id=3754217 evaluates six real-match comparisons: xG edge, pass completion, pressure rate, advanced-zone share, shot quality, and actions per possession.

Real-data Brainstore smoke test

Use this flow to test the full StatsBomb → ClickHouse → Prometheus → PromQL path with a real fixture:

docker compose up --build -d
curl http://localhost:8787/health
node scripts/import-statsbomb.mjs --match-id=3754217

Start the frontend in another terminal with npm run dev, then open http://localhost:5173 and choose Analytics → Real Data. Select the Chelsea–Arsenal match to see the six real-match signal cards and their PromQL source. The raw service responses are also available here:

curl 'http://localhost:8787/api/analytics/real-data/matches?source=statsbomb&season=2015'
curl 'http://localhost:8787/api/analytics/real-data/brainstore?source=statsbomb&source_match_id=3754217'
curl http://localhost:8787/metrics | rg 'touchline_real_match_'
curl -G http://localhost:9090/api/v1/query \
  --data-urlencode 'query=sum(touchline_real_match_xg{source="statsbomb",source_match_id="3754217"})'

Prometheus is available at http://localhost:9090, ClickStack at http://localhost:8123/clickstack, and analytics logs at docker compose logs analytics prometheus if a service needs debugging. Prometheus scrapes the analytics exporter; the exporter checks ClickHouse directly and exposes touchline_clickhouse_up for PromQL. The importer can be rerun for the same match to replace its stored slice.

The Analytics Lab also reads http://localhost:8787/api/analytics/iceberg/history?table=player_match_facts and shows the Iceberg snapshot count, so the local stack exposes both the hot ClickHouse path and lakehouse history.

ClickHouse labs

  • ClickStack: after a full season sync, open http://localhost:8123/clickstack, copy the displayed career/season run ID into analytics/clickstack-queries.sql, and build final-table, season-story, points-race, xG, player-development, event-volume, and replay-density charts.
  • Season Command Center: the frontend reads the same round-level data from /api/analytics/timeline; the custom pitch heatmap stays in Touchline.
  • Performance lab: analytics/performance-lab.sql compares raw match facts with the materialized-view path, query-log metrics, index pruning, parts, merges, and data types.
  • Scale lab: analytics/scale-lab.sql replaces only scale-lab-* rows and generates 20 copies of the selected season.
  • Alert lab: analytics/clickstack-alerts.sql contains the xG-underperformance query. The local banner makes clear that alert scheduling is not included in this build.

In local ClickStack, the dashboard supports a global SQL WHERE filter, so the saved Touchline Season Command Center uses run_id and club_id without changing tile SQL.

Run

npm install
npm run dev

Then open the local URL printed by Vite.

Checks

npm run lint
npm test
npm run build
(cd analytics && go test ./...)
(cd analytics && go vet ./...)
docker compose config --quiet
docker compose run --rm --no-deps --entrypoint promtool prometheus check config /etc/prometheus/prometheus.yml
docker compose run --rm --no-deps --entrypoint promtool prometheus check rules /etc/prometheus/touchline-rules.yml

Next Systems

  • Transfer market and contracts
  • Scouting reports with incomplete information
  • Injuries, suspensions, and rotation pressure
  • Player relationship events
  • More explainable tactical counters between clubs
  • Save slots and named careers

About

A football management game with visible tactical consequences, real StatsBomb event data, ClickHouse and Prometheus analytics

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages