Basketball Data Platform
A unified system for basketball analytics, simulation, and interactive gaming — spanning a Python data pipeline, a C++ physics engine compiled to WebAssembly, a Vue 3 auto-battler, and a native SwiftUI iOS app.
Try the Simulation
Shooting Drill
Click a zone to shoot. Percentages are NBA averages.
The same shot-zone model powers the C++ simulation engine and game matchmaking.
Jumpshot Lab
Jumpshot Lab — HORSE
Set your form. Shoot. Don't spell HORSE.
Arc · release · backspin · footwork. The same variables the C++ engine uses to evaluate every shot.
System Layers
Data Pipeline
Python · Flask · nba_api · pandas
Real-time NBA data ingestion from stats.nba.com. 13 REST endpoints serving teams, players, standings, game logs, and box scores with in-memory caching and consistent JSON contracts.
- -True Shooting %, Effective FG%, Usage Rate, Net Rating, PIE, AST/REB%
- -Team dashboards with offensive/defensive ratings, pace, and lineup analysis
- -Last-night analytics — top performers with shooting splits and contest data
- -Session-scoped test cache with rate-limiting for CI-safe integration tests
Simulation Engine
C++17 · WebAssembly · Emscripten · nlohmann/json
Physics-based basketball simulation compiled to WASM. Handles player movement, shot probability with contest mechanics, ball physics with 3D arc trajectories, and a synergy buff system — all running at native speed in the browser.
- -Shot probability: exponential decay by distance with contest penalty from nearest defender
- -Ball physics: 3D position/velocity, gravity at 9.8 m/s², bounce damping at 0.6x
- -Synergy engine: Franchise, Twin Towers, Splash Family, 7 Seconds or Less archetypes
- -Game economy: 5-tier salary cap mapping, z-score stat normalization, draft lottery
Full-stack basketball autochess. Drag-and-drop formation planning, real-time WASM-driven match simulation rendered on canvas, ghost matchmaking against other players' boards, and a 10-round survival run with HP and gold economy.
- -Planning phase: 5x5 grid drag-and-drop with bench management and sell mechanics
- -Simulation: requestAnimationFrame loop parsing C++ engine state as JSON each tick
- -Matchmaking: PostgreSQL-backed ghost opponents from prior player board states
- -Deployed: GitHub Pages frontend + Fly.io API + managed PostgreSQL
Native iOS App
SwiftUI · async/await · MVVM · UIKit bridge
Native iOS/macOS/visionOS app with protocol-driven service architecture. Live roster stats from balldontlie.io, animated stat bar visualizations, and an interactive tactics board for diagramming plays with tap-to-place markers and drag-to-draw motion paths.
- -Service protocol pattern: LakersStatsService + PlayerStatsService with mock implementations
- -LoadState machine: idle → loading → loaded/failed driving pure SwiftUI views
- -UIViewRepresentable bridge for precise tap-coordinate capture on tactics board
- -Client-side aggregation of per-game stats into season averages with sample-size filtering
System Architecture
Data flows left to right: external APIs → service layer → engines & clients
Technology Stack
Languages
Frameworks
Data
Infra
Testing
Key Design Decisions
WASM for Simulation
C++ compiled to WebAssembly runs the physics engine at near-native speed in the browser. The 195KB binary is smaller than most JavaScript game frameworks, and Emscripten's embind provides type-safe interop with zero serialization overhead.
Protocol-Driven Services
Both the Swift and Python codebases use protocol/interface patterns for data services. This enables mock implementations for testing, runtime service switching, and clean dependency injection without external DI frameworks.
Ghost Matchmaking
Instead of real-time multiplayer (which requires always-on infrastructure), the auto-battler saves board states to PostgreSQL and matches players against ghosts of previous runs. Same competitive feel, a fraction of the infrastructure cost.
Shared Domain Model
PlayerEntity, SynergyEngine, ShotProbability, and GameEconomy are implemented identically in C++ and Swift. This shared domain model means game balance tuning in one language transfers directly to the other.
Let's Build Something Together
I'm pursuing senior engineering roles in sports tech and data strategy. If you're building at the intersection of sports and software, I'd love to talk.