GoalForge is a research project that predicts the outcome of a soccer match from the starting lineups of the two teams. Given the two XI's, it aims to predict:
- the final score,
- who scores each goal, and
- who assists each goal (when there is one).
The approach combines each player's recent performance (≈ last 3 seasons), the two coaches' track records, and opponent strength into a probabilistic match-simulation engine: a team-level model estimates how many goals each side is expected to score, and a player-level model distributes those goals (and assists) across the lineup. Thousands of Monte-Carlo simulations of the match then yield score, scorer, and assister probabilities.
The first target is the FIFA World Cup; the design generalizes to any match (club or international) for which both starting lineups are available.
Status: early scaffold. The full design — data sources, models, and the prediction pipeline — lives in docs/workflow.md. A working Phase-0 pipeline (Dixon–Coles scoreline + Monte-Carlo scorer/assist allocation) is implemented and runs on both synthetic data and real StatsBomb World Cup data — see Quickstart.
A deployed build predicts the 48-team 2026 FIFA World Cup end-to-end (static frontend + stdlib serverless API on Vercel), from real data:
- Squads — the official 26-man rosters (48 teams) with each player's caps and international
goals, scraped from Wikipedia (
scripts/scrape_wc2026.py). - Team strength — Dixon–Coles fit on martj42 international results (honest held-out backtest);
win/draw/loss odds blend it 50/50 with a LightGBM outcome model — the winner of a walk-forward
bake-off over 11 major tournaments (
scripts/team_bakeoff.py, RPS 0.1980 vs 0.2000 DC-alone). All layers are cut off at the 2026 WC kick-off (2026-06-11): a genuine pre-tournament forecast. - Scorers — each player's real international goals-per-cap, shrunk to a position prior.
- Assists — a position-based estimate (no public international assist dataset — the weakest layer).
- Venue — neutral by default; the three hosts (USA / Canada / Mexico) get home advantage.
The default XI is the most-capped player per position (4-3-3), editable per match. Only the team
layer is validated on match outcomes; the scorer/assist layers are history/prior-based. Pipeline:
scripts/build_wc2026_model.py → api/model.json; see DEPLOY.md.
The site has four pages (bright, animated UI; hub at /):
- Match Predictor (
match.html) — any two teams + editable XIs → score, scorers, assisters. - Full Tournament (
tournament.html) — the whole 2026 World Cup on the most-likely path: all 72 group matches with standings (official Art. 13 tiebreakers), third-place ranking, and the real knockout bracket (FIFA Annex C third-place slotting, M73–M104 incl. the third-place match). Built offline byscripts/build_tournament.py→public/tournament.json. - Honors (
honors.html) — Golden Boot / Playmaker races accumulated along the predicted path + Golden Glove, alongside Monte-Carlo probabilities from 20k simulated tournaments (scripts/simulate_wc2026.py→public/forecast.json). - Prediction vs Actual (
compare.html) — since the model is frozen at kick-off, every real 2026 match is out-of-sample. Group-stage scorecard (outcome accuracy, exact-score rate, RPS vs base-rate, qualifiers called) with predicted-vs-actual tables and knockout results as they land (scripts/build_actual.py→public/actual.json).
The end goal is an automated agent: hand it two lineups, and it fetches the required historical data, builds features, runs the simulation, and returns a structured prediction — no manual steps in between.
configs/ YAML run/experiment configs
data/ Local data cache (raw/interim/processed/external) — contents git-ignored
docs/ Design docs; start with docs/workflow.md
models/ Saved model artifacts — contents git-ignored
notebooks/ Exploratory analysis
reports/ Generated figures and prediction outputs
app/ Streamlit web UI
public/ static web frontend (HTML/CSS/JS; served by FastAPI locally & Vercel)
api/ Vercel serverless functions (Python stdlib only) + model.json
scripts/ CLI entry points (run_pipeline / train / run_worldcup)
slurm/ Great Lakes (Slurm) job templates
src/goalforge/ Main Python package
data/ ingestion & loaders (synthetic, StatsBomb, martj42)
features/ feature engineering (player form, ratings, coach effects)
models/ scoreline (Dixon-Coles, hierarchical) & player models
simulation/ Monte-Carlo match engine
prediction/ end-to-end agent + checkpoint + likely-XI
evaluation/ temporal split, baselines, metrics, backtest
api/ FastAPI backend
utils/ shared helpers
tests/ test suite
TBD.