🎮 HLStatsX.NET
🚧
This project is in pre-alpha. It is not ready for production use. The rewrite is feature-complete for most of the public stats pages (~97% overall parity) but is still under active development. Expect rough edges, missing features, and breaking changes between releases. If you want to follow progress, check the Feature Parity Report — it's updated with every significant commit. Questions or feedback? Email info@hlstatsx.net.

🙏 Standing on the shoulders of giants

❤️
This project exists because of the people who built HLStatsX.

HLStatsX has been a labour of love for over 20 years. From its original authors to every contributor who filed issues, submitted patches, and kept servers running — the whole community deserves full credit for what it became. HLStatsX.NET carries that work forward: the same game tracking, the same skill system, the same data model — modernised, not replaced.

The legacy codebase was used as the authoritative specification throughout, ensuring every feature, edge case, and design decision carries forward faithfully. HLStatsX.NET is a drop-in replacement for the original PHP site and Perl daemon — the same database, the same game server log format, the same stat output. No data migration. No reconfiguration. Just a modern foundation that can be maintained and extended going forward.

🔗 Try it yourself

🤔 Is a rewrite actually the right call?

📋
This is not about discarding the old work. It's about honouring it properly.

The original team built something that ran reliably on thousands of servers for over two decades. That is the definition of success. HLStatsX.NET starts from a position of deep respect for that achievement — the goal is to take everything they figured out about stat tracking, skill ranking, and game event processing, and give it a home where it can be properly maintained, extended, and secured going forward.

⚠️
The honest concern: rewrites are famously risky.

Joel Spolsky's classic essay argues that the original code, however ugly, contains years of accumulated bug fixes and hard-won knowledge. Throwing it away risks rediscovering all those bugs from scratch. That concern is taken seriously here — the original PHP and Perl code is referred to in depth to ensure compatibility at every level.

📊 By the numbers

2001
Year the original HLstats was born
3,600+
Lines in hlstats.pl — 25 years of event-handling knowledge
27,000+
Lines of legacy PHP — the spec read before every feature
30,000+
Lines of .NET C#
228
Commits in the first 6 weeks
650+
Unit tests — vs zero in the original

🔬 Real problems, with evidence from the code

These aren't theoretical concerns. Each one is grounded in specific code from the legacy source.

✨ Beyond parity — features the original never had

Rewriting from scratch isn't just about cleaning up old code — it's an opportunity to add things that were never feasible in the original architecture. These are already shipped.

🔥
Interactive kill and death heatmaps
Kill and death positions are plotted as an interactive overlay on every map page. Pan, zoom, and toggle between kills and deaths. The original collected the data but never visualised it.
🗺️
Clan member world map
Clan profile pages show an interactive map of where members are located around the world. Nothing like this exists in the original.
Pages load fast — even under load
All data for a page is fetched in parallel. The original fetches everything one query at a time. On busy servers with large datasets, this is the difference between a snappy page and a timeout.
📦
Simple, modern deployment
The full stack starts with a single command. No web server to configure, no scripting language to install, no source files to hand-edit with passwords.
🧪
Hundreds of automated tests
Every change is validated automatically. Regressions cannot silently ship. The original has no automated tests — bugs are discovered by players noticing wrong stats.
as of May 2026
📈
Modern, interactive charts
Charts are rendered in the browser — responsive, zoomable, and interactive. The original generates static images on the server, which breaks on many hosting setups.
🔑
Proper admin security
Admin authentication uses modern password hashing and cross-site request forgery protection. The original relies on plaintext passwords and basic session checks.
📡
RCON broadcasting — fully reimplemented
Real-time in-game feedback is implemented for both Source Engine (TCP RCON) and GoldSrc (UDP challenge-response). Kill messages, connect announcements, and rank-kick all work across both engine generations from a single, pooled connection manager.
shipped May 2026
🔍
Live server querying via A2S_INFO
The daemon queries game servers directly using the Valve A2S_INFO protocol. Map names are auto-corrected from live server responses — no manual map entry required. The original daemon relied entirely on log-line text for map state.
shipped May 2026

🔧 Broken in the original — working again

Some features in the legacy installation are actively broken for many users today — not just outdated. These are restored in HLStatsX.NET.

🗺️
Maps work without a paid API key
The original requires a paid Google Maps billing account. Without one, maps show blank tiles. HLStatsX.NET defaults to free, open mapping with no account or billing required.
📊
Charts display correctly on all hosting setups
The original generates chart images on the server — a feature that silently fails on shared hosting without the right server extensions installed. Charts now render in the browser with no server-side requirements.
🎭
Kill and death heatmaps are actually shown
The original records kill positions on every map but never displays them. That data is now visualised as a fully interactive heatmap overlay.
👥
Clan member counts are correct
The clan leaderboard showed zero members for every clan. This is fixed — counts are now accurate and up to date.
🏷️
Player roles display proper names
Role names were showing as internal codes rather than readable labels. Player profiles now display role names correctly.
Activity indicators show meaningful colours
Activity bar indicators were rendering as a flat, uniform colour on all browsers. They now correctly show green, yellow, and red based on activity level.
🤖
Bot players display cleanly
Bots appeared on leaderboards with broken flag images. They are now correctly identified and displayed without any broken imagery.
🌐
No legacy JavaScript compatibility issues
The original bundles JavaScript libraries from 2006 that modern browsers have quietly broken. HLStatsX.NET uses no legacy framework dependencies.

🛡️ Security, integrity, and future-proof technology

The original was built in a simpler time, before modern web security practices were established. HLStatsX.NET treats security as a first-class concern, not an afterthought.

🚀 What's still to come

🚧
Pre-alpha — there is still a lot of work to do.

Feature parity with the PHP frontend is at ~97%, the daemon covers the full event pipeline including RCON broadcasting, and in-game pages are complete. A small number of admin tools remain. Below is an honest picture of what hasn't been done yet — and what's planned beyond mere parity.

Completing parity with the original

🗺️
Game dashboard — VoiceComm block
The game overview page is ~95% complete. The remaining gap is the VoiceComm server block (TeamSpeak / Mumble server links), which requires a separate admin management page that has not yet been ported.
partial
🔧
Admin utility tools
Three rarely-used admin tools are still outstanding: VoiceComm server management, the daemon control panel (send RELOAD/KILL to the running daemon), and the database collation reset utility.
not started

Planned improvements beyond the original

🎨
Refreshed UI and graphics
The current theme is a clean tech-modern redesign of the PHP site, but the underlying graphic assets (flag images, weapon icons, rank badges, game icons) are still the original 2001-era GIFs and PNGs. A full graphics refresh — vector icons, modern image formats, responsive layout improvements — is on the roadmap.
planned
🌍
Localisation (i18n)
HLStatsX has always had a global audience — many server communities are non-English-speaking. The PHP site has no i18n support whatsoever: every string is hardcoded in English. HLStatsX.NET is architected for ASP.NET Core's built-in localisation middleware. Adding a translation file for a new language will not require touching the application code.
planned
🗄️
Support for more databases
HLStatsX has always been tied to MySQL. The plan is to support PostgreSQL and SQL Server too — opening the door to cloud-managed databases without any code changes.
planned
📊
Richer analytics
Deeper player trends, weapon meta breakdowns over time, server health dashboards, and exportable reports.
planned
🔌
Public API
No public API exists in the original. A versioned REST API would enable Discord bots, server management panels, and third-party overlays without scraping HTML.
planned
🔔
Notifications and webhooks
Rank-ups, awards, and milestones are currently silent. Configurable notifications to Discord, Slack, or custom endpoints are on the roadmap.
planned

📋 Head to head

Aspect Legacy PHP + Perl HLStatsX.NET
Maintenance Lovingly built by a chain of contributors since 2001. No active maintainer today — kept alive by community dedication alone. Actively maintained. Issues tracked. Contributions welcome. A path forward exists.
SQL safety User input mixed into query strings. Relies on consistent sanitisation by every contributor on every code path. Safe queries are the only option — injection is structurally prevented by the framework.
Performance Blocking, sequential. Pages wait for every query and external call before rendering. Fully asynchronous. All independent work runs in parallel. Pages render as data arrives.
Architecture Database queries, business logic, and HTML mixed together. Global shared state throughout. Untestable by design. Clean layered architecture. Every component independently testable.
Error handling Database errors expose server details to every visitor in the browser. Safe error pages in production. Full details go to the application log only.
Log daemon A single large Perl script. No tests. No strict typing. Circa 2001. Structured async worker service. Typed event handlers. Full test coverage.
Deployment Multiple runtimes to install and configure. Credentials pasted into source files. Starts with a single command. Secrets kept outside the source tree.
Tests None. Bugs are found in production by players noticing wrong stats. Hundreds of automated tests. Regressions caught before they ship.
Open source GPL-2.0. No active contribution workflow or community review process. MIT licensed. Source publishing coming soon. Contributions welcome.
Charts Server-generated static images. Broken on many shared hosting setups. Client-side, interactive, and responsive. No server requirements.
JavaScript Legacy framework from 2006. Silently broken in modern browsers. No legacy framework dependencies.

🤝 Get involved

💬
This is a community project continuing a twenty-five year tradition. Contributions are genuinely welcome.

HLStatsX was built and sustained by a community that cared enough to keep it running. HLStatsX.NET carries that spirit forward with proper tooling, reviewed contributions, and tracked issues. The source will be published publicly once the project reaches a suitable milestone. If you run a Half-Life server community and want a modern stats platform, this is being built for you.

🐛
Found a bug?
Email info@hlstatsx.net with what you expected, what you saw, and which game you're running. Issues will be trackable publicly once the repository is open.
🔧
Want to contribute?
The repository will be published publicly soon. Email info@hlstatsx.net to be notified when it opens.
🎮
Running a game server?
Compatible with CS, DoDS, TF2, and all Source engine titles. If your game isn't working correctly, get in touch — broad compatibility is a priority.
✉️
General questions
Email info@hlstatsx.net for anything else — partnership enquiries, hosting questions, or just to say hi.