League Match Analysis
I built the ingestion pipeline, match calculations, and interface for reviewing League of Legends matches. Compare two champions’ gold, creep score (CS), and experience over time alongside recorded events.
Look up a player, or choose “Explore sample match” to try the app with synthetic data.
From final score to match timeline
A final scoreboard tells you how a match ended. The timeline adds a way to inspect when a lead grew or shrank, compare opponents, and see which events were recorded in that interval.
The same view brings together team results, player builds, and timestamped kills, objectives, item changes, and ward events. Player, opponent, metric, and interval selections are stored in the URL, so a comparison can be reopened or shared.
System design
The browser talks to Next.js. Server-side requests authenticate to the Spring backend, which retrieves Riot data and stores it in PostgreSQL. API keys and database credentials stay on the server.
Next.js + TypeScript
Pages, interactive timelines, and shareable URL state.
Java + Spring Boot
Riot API ingestion, validation, and match calculations.
PostgreSQL
Source captures and normalized match records.
Raw provider responses are stored separately from normalized records so calculations can be traced to their source. Flyway manages schema migrations. The frontend is hosted on Vercel, with the backend and database on Railway.
Keeping missing evidence visible
A missing observation is different from a recorded zero. The app preserves that distinction in tables and chart gaps, instead of inventing values to make the timeline look complete.
Suggested intervals highlight changes in recorded gold difference. They offer places to inspect, without claiming that a nearby event caused a change or that the player made a good or bad decision.
Testing the complete workflow
Backend and frontend tests cover calculations, response handling, and unavailable data. Browser tests exercise comparisons, metric changes, and URL restoration after navigation and reload.
The CI workflow also includes production builds, visual regression checks, and a container smoke test against a clean database. The synthetic sample provides a repeatable way to exercise match review without depending on live Riot lookups.
Results and limitations
The app supports live player lookup and a synthetic sample match. Match history loads up to 20 games at a time across all queues; the interface reports incomplete results and Riot API cooldowns.
Timeline samples describe recorded points in time, not continuous game state. Displayed ranks are current queue-specific snapshots, rather than historical ranks or MMR. The app supports reviewing evidence; it does not measure coaching quality or predict future performance.
Explore the app and source
Try the sample match, or read the architecture and development guide in the repository.
LoL Match Analysis isn’t endorsed by Riot Games. League of Legends and associated properties are trademarks or registered trademarks of Riot Games, Inc. Third-party notices.