A comprehensive tool for analyzing Counter-Strike 2 demo files with interactive visualization and detailed statistics.
CS2 Reviewer parses CS2 demo files (.dem) and provides an interactive web interface to analyze matches, visualize kill positions on maps, and review detailed statistics including player positions, economic data, and round-by-round breakdowns.
- Comprehensive Demo Parsing: Extract all match data including teams, players, rounds, kills, and economics
- Interactive Map Visualization: Click kill events to see victim/attacker/assister positions overlaid on actual CS2 maps
- 3D Position Tracking: Every kill includes X/Y/Z coordinates for spatial analysis
- Economic Analysis: Track equipment values, money spent, and economic decisions
- Split-Level Map Support: Proper handling for Nuke and Vertigo (upper/lower floors)
- Type-Safe Architecture: Full TypeScript support with runtime validation
- Modern & Legacy UIs: Choose between modern Svelte SPA or server-rendered Haml templates
de_ancient, de_anubis, de_dust2, de_inferno, de_mirage, de_nuke, de_overpass, de_vertigo
The project consists of three interconnected components:
┌─────────────────────────────────────────────────────────────┐
│ CS2 Reviewer System │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ demo_parser │─────▶│ web_server │◀─────│web_client │ │
│ │ (Go CLI) │ │ (Ruby/Sinatra)│ │(Svelte SPA)│ │
│ └──────────────┘ └──────────────┘ └───────────┘ │
│ │
│ • Parses .dem • HTTP API • Modern UI │
│ • Event-driven • File uploads • TypeScript │
│ • JSON output • Subprocess calls • Interactive │
│ • Serves both UIs • Type-safe │
└─────────────────────────────────────────────────────────────┘
User uploads .dem file
↓
web_server receives upload
↓
Calls demo_parser (Go binary)
↓
Parses demo → JSON output
↓
Ruby processes JSON
↓
┌──────────────────┬──────────────────┐
│ │ │
Haml templates Svelte SPA JSON API
(legacy UI) (modern UI) (for clients)
| Component | Language | Framework/Tools | Purpose |
|---|---|---|---|
| demo_parser | Go 1.21.7 | demoinfocs-golang | Binary parsing of CS2 demos |
| web_server | Ruby 3.3.4 | Sinatra, Puma, Haml | API + legacy UI |
| web_client | TypeScript 5.6 | Svelte 5, Vite 6, Zod | Modern SPA with type safety |
- Go 1.21.7 or higher
- Ruby 3.3.4 or higher
- Node.js 18+ (for web_client)
- Bundler (Ruby gem manager)
- npm (Node package manager)
# Install Go
brew install go
# Install Ruby (using rbenv recommended)
brew install rbenv
rbenv install 3.3.4
# Install Node.js
brew install node# Install Go
wget https://go.dev/dl/go1.21.7.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.7.linux-amd64.tar.gz
# Install Ruby (using rbenv recommended)
sudo apt install rbenv
rbenv install 3.3.4
# Install Node.js
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejsgit clone <repository-url>
cd cs2-reviewercd demo_parser
make build
cd ..cd web_server
bundle install
cd ..cd web_client
npm install
cd ..Option A: Quick Start (Legacy UI)
cd web_server
bundle exec rackup
# Access at http://localhost:4567Option B: Full Stack Development (Modern UI)
# Terminal 1 - Start web server
cd web_server
bundle exec rerun -- rackup
# Terminal 2 - Start web client dev server
cd web_client
npm run dev
# Access at http://localhost:5173Option C: Production-like Setup
# Build web client
cd web_client
npm run build
cd ..
# Start web server
cd web_server
bundle exec puma
# Access Haml UI at http://localhost:4567
# Access Svelte SPA at http://localhost:4567/appcs2-reviewer/
├── demo_parser/ # Go binary for parsing CS2 demos
│ ├── cmd/ # CLI entry point
│ │ └── cs2-reviewer/ # Main application
│ ├── internal/ # Parser implementation
│ │ └── counter_strike/ # CS2-specific logic
│ ├── out/bin/ # Build output
│ ├── Makefile # Build automation
│ └── README.md # Parser documentation
│
├── web_server/ # Ruby Sinatra backend + legacy UI
│ ├── main.rb # Sinatra application
│ ├── views/ # Haml templates
│ │ ├── layout.haml # HTML wrapper
│ │ ├── index.haml # Upload form
│ │ └── upload.haml # Results display
│ ├── public/ # Static assets
│ │ ├── css/ # Bootstrap
│ │ ├── js/ # JavaScript
│ │ ├── maps/ # CS2 map images
│ │ └── app/ # Built web_client (generated)
│ ├── lib/ # Ruby modules
│ ├── spec/ # Tests
│ └── README.md # Server documentation
│
├── web_client/ # TypeScript/Svelte SPA
│ ├── src/
│ │ ├── main.ts # Entry point
│ │ ├── App.svelte # Root component
│ │ ├── lib/ # Svelte components
│ │ └── models/ # Type-safe data models
│ ├── vite.config.ts # Build to ../web_server/public/app/
│ └── README.md # Client documentation
│
└── README.md # This file
Perfect for: Batch processing, scripting, data extraction
cd demo_parser
./out/bin/cs2-reviewer /path/to/demo.dem > output.jsonOutput: Structured JSON with all match data
Perfect for: Quick demos, simple usage, server-side rendering
cd web_server
bundle exec rerun -- rackup
# Visit http://localhost:4567
# Upload demo → View resultsFeatures:
- File upload interface
- Server-side rendering
- Bootstrap UI
- Auto-reload on changes
Perfect for: Frontend development, type-safe coding, modern tooling
# Terminal 1 - Backend
cd web_server
bundle exec rerun -- rackup
# Terminal 2 - Frontend
cd web_client
npm run dev
# Visit http://localhost:5173Features:
- Hot Module Replacement (HMR)
- TypeScript type checking
- Zod runtime validation
- Component-based architecture
- ESLint + Prettier
Perfect for: Deployment, testing final build
# Build everything
cd demo_parser && make build && cd ..
cd web_client && npm run build && cd ..
# Start production server
cd web_server
bundle exec pumaAccess:
- Legacy UI: http://localhost:4567
- Modern SPA: http://localhost:4567/app
Each component has detailed documentation:
- demo_parser/README.md - Go binary architecture, data structures, event handlers
- web_server/README.md - Ruby API, routes, Haml templates, integration
- web_client/README.md - Svelte components, TypeScript models, build config
./demo_parser/out/bin/cs2-reviewer ~/demos/match.dem > match.json- Start web_server:
cd web_server && bundle exec rackup - Open http://localhost:4567
- Click "Upload a demo"
- Select .dem file
- View interactive results with map visualization
- Build web_client:
cd web_client && npm run build - Start web_server:
cd web_server && bundle exec puma - Open http://localhost:4567/app
- Click kill events to visualize positions on map
- View detailed round-by-round statistics
Error: No such file or directory: '../demo_parser/out/bin/cs2-reviewer'
Solution: Build the Go binary first
cd demo_parser
make buildError: Address already in use - bind(2) for "127.0.0.1" port 4567
Solution: Kill process using port or change port
# Find process
lsof -i :4567
# Kill it
kill -9 <PID>Issue: web_client fetches from /test endpoint which requires cached demo data
Solution: Either:
- Use the legacy UI to upload a demo first
- Place test JSON in
web_server/tmp/de_nuke.json - Modify
web_client/src/App.svelteto use a different endpoint
Error: go.mod requires go >= 1.21.7
Solution: Update Go
go version # Check current version
# Install Go 1.21.7+ using your package managerError: Your Ruby version is X.X.X, but your Gemfile specified 3.3.4
Solution: Use rbenv or rvm
rbenv install 3.3.4
rbenv local 3.3.4Issue: Type mismatches or Zod validation failures
Solution: Run type checking
cd web_client
npm run check # Runs svelte-check and tsc✅ Working:
- Go demo parser (fully functional)
- Ruby web server with file upload
- Legacy Haml UI with map visualization
- Modern Svelte SPA with type safety
- Interactive kill position visualization
- Migration from Haml templates to Svelte SPA
- Two parallel frontends (transitional state)
❌ Missing:
- File upload in web_client (relies on cached data)
- Environment configuration (hardcoded URLs)
- Test coverage
- CI/CD pipeline
- Deployment documentation
- ✨ Complete TypeScript rewrite with Zod validation
- ✨ Svelte 5 with new runes API
- 🐛 Fixed API/client integration issues
- 🔧 Restored Makefile for simplified builds
- Add file upload to web_client
- Environment-based configuration
- Extract map metadata to config files
- Add error handling and user feedback
- Write tests for all components
- Complete migration to Svelte SPA (deprecate Haml)
- Add round timeline scrubber
- Player statistics dashboard
- Heatmaps for common positions
- Export functionality (PDF, images)
- Real-time demo analysis (stream processing)
- Machine learning for strategic insights
- Multi-demo comparison
- Team performance tracking over time
- Integration with CS2 Game State Integration (GSI)
- Post-match analysis and review
- Identify strategic mistakes
- Analyze opponent tendencies
- Economic decision analysis
- Personal performance review
- Positioning improvement
- Aim analysis (headshot %, accuracy)
- Highlight identification
- Statistical analysis
- Machine learning datasets
- Strategic research
- Content creation (highlight reels)
This is a personal project, but contributions are welcome!
- Fork the repository
- Follow the Quick Start guide
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Go: Follow
gofmtformatting - Ruby: Follow Ruby Style Guide
- TypeScript: Use ESLint + Prettier (configured in web_client)
This project uses map assets derived from Boltobserv (GPL-3 licensed).
- demoinfocs-golang - CS2 demo parsing library
- Boltobserv - Map assets and coordinate systems
- SimpleRadar - High-quality radar images
For issues, questions, or feature requests, please open an issue on GitHub.
Note: This project was created for educational and analytical purposes. It is not affiliated with Valve Corporation or Counter-Strike 2.