All posts
Part 02 of 10
UI Layer99K linesServices42K linesModels38K linesData31K lines210K lines18K dead23 testsA 20-year codebase with fractures in every layer
Part 02 of 10

What I Found When I Opened the Hood

The forensic autopsy of a 20-year-old codebase.

For everyone·10 min read

For everyone. Technical terms explained in plain language.

After the crash report from Part 1, I knew the scheduler had a problem. But before I could fix it, I needed to understand the full codebase. I spent the first week reading code — not writing it.

What I found was both impressive and alarming.

01

The Scale

210K
Lines of code
18K
Dead code lines
23
Tests
66
Files importing WinForms
FIG 2.1
DEAD CODE BY CATEGORY Certificate Browser 4,986 3D Pie Chart 4,299 Cloud Storage 2,612 Logitech G15 LCD 1,668 Mineral Worksheet 1,525 In-Game Browser 1,091 IGB Headers 534 Battleclinic API 483 Google Calendar 421 Tray Popup 285
18,072 lines of dead code across 10 categories — features removed from EVE years ago

EVEMon was not a small project:

Total code:           210,002 lines across 1,363 files
Business logic:        83,656 lines in 846 files (one massive project)
Screen code:           99,073 lines in 251 files (Windows Forms UI)
Tools and generators:  14,717 lines
Tests:                    417 lines (23 tests in 4 files)

Two hundred and ten thousand lines of code built by fifty-seven people over twenty years. This isn't a weekend project. This is a significant application — comparable in size to many commercial software products.

02

The Good

Let me be clear: EVEMon worked. Millions of EVE players used it successfully for nearly two decades. The skill calculation engine is correct. The plan optimizer finds optimal training paths across hundreds of skills. The ESI integration handles CCP's API reliably. Peter Han's migration from the old XML API to ESI was skillfully done.

The fifty-seven contributors who built this created something genuinely useful that served a community for twenty years. That's rare in software. What I'm about to describe isn't a criticism of anyone's work — it's what happens to every codebase that outlives its original assumptions.

03

The Concerning

FIG 2.2
EveMonClient 1,856 lines 929 references across the codebase
The central god object: 929 references radiating outward

Twenty years of accumulated decisions had created structural problems. Not because anyone did anything wrong at the time — the technology and practices of 2006 were different from today. The problems came from building on top of decisions that made sense then but became constraints by 2026.

One Project to Rule Them All

All 846 files of business logic lived in a single project called EVEMon.Common. Think of it like a warehouse with no internal walls. Interfaces, data models, networking, serialization, settings, services, helpers, threading, and UI controls — all in one room.

This meant:

  • Changing how market orders display could accidentally break skill plan calculations
  • You couldn't work on the data layer without dragging in the entire Windows UI framework
  • There was no way to enforce rules about what code could talk to what

For comparison, EveLens splits this into seven separate projects with strict one-way dependencies. Like having labeled rooms with fire doors between them.

23 Tests for 210,000 Lines

Automated tests are the safety net that catches mistakes before users see them. The original codebase had 23 tests — for a 210,002-line application.

Here's what they covered:

  • 2 tests: Scan the code for dangerous threading patterns
  • 6 tests: Can you compress and decompress data?
  • 15 tests: Can you convert EVE time formats correctly?

That's it. No tests for characters. No tests for skills. No tests for plans. No tests for settings. No tests for market orders, contracts, industry jobs, mail, or any of the core features players actually use.

This is why the crash at sixty characters went undetected for years. There was no automated check that would have caught it.

The God Object

One class called EveMonClient was referenced by 150 out of 1,100 source files — over 13% of the entire codebase. It had 929 total references and held 69 static events that every part of the application subscribed to.

Imagine every announcement in an office building going through a single PA speaker. 218 rooms had their speakers turned on, but only 212 remembered to turn them off when they left. The other six leaked resources quietly, every time.

I'll go deep on this in Part 3. For now, just know that this single class was the reason the scheduler couldn't be fixed in isolation — everything in the app was connected through it.

18,072 Lines of Dead Code

This is the part that surprised me most. The codebase was carrying eighteen thousand lines of code for things that no longer exist:

Dead FeatureLinesWhy It's Dead
In-Game Browser web server1,091CCP removed the IGB from EVE in 2017
Certificate Browser4,986CCP removed certificates from EVE in 2014
Logitech G15 keyboard LCD driver1,668Hardware discontinued in 2008
Cloud storage sync2,612Deprecated SDKs, dead feature
Mineral price worksheet1,525EVE-Central shut down in 2016
3D pie chart renderer4,299Windows-only, can't work in modern frameworks
Hammertime structure API420API shut down around 2020
Osmium/BattleClinic loadouts223+Both sites shut down by 2019
Market price fetchers783+EVEMarketer shut down around 2020
Watchdog process monitor357Hardcodes "EVEMon" process name
Windows 7 feature detection108Windows 7 reached end-of-life in 2020

The In-Game Browser server contained code for a JavaScript API call that only existed inside a game feature CCP removed nine years ago. The Logitech G15 handler rendered to a 160x43 pixel monochrome LCD on a keyboard discontinued eighteen years ago. The Certificate Browser operated on game data CCP removed twelve years ago.

Every one of these lines was compiling, loading, and using memory — for things that haven't existed in years.

No Way to Run on Linux or Mac

66 files in the business logic project directly imported Windows-specific UI libraries. The character models had Windows-only image types baked into the domain layer. The settings system showed Windows dialog boxes directly from service code.

There was no path to Linux or Mac without untangling all of this first.

No Automated Build Pipeline

Zero continuous integration. No GitHub Actions. No build scripts. No automated anything. The project was built entirely through Visual Studio with no pipeline to catch regressions.

04

What This Meant

None of this was anybody's fault. EVEMon was built when .NET Framework 2.0 was current and Windows XP was the target platform. It was upgraded incrementally to .NET Framework 4.6.1, but the fundamental architecture stayed the same.

The result was a codebase that:

  • Worked for most users but had a ceiling that Ansza's sixty characters hit
  • Could not be tested because everything was tangled together
  • Could not run on Linux or Mac because Windows was in the DNA
  • Could not be themed because the UI was welded to the business logic
  • Was carrying 18,000 lines of dead weight from services that died years ago

To fix the crash — really fix it, not just patch the symptom — I would need to address all of this. Not because I wanted to rebuild an entire application. Because there was no way to fix the scheduler without untangling the event system, and no way to untangle the event system without splitting the project, and no way to split the project without separating the business logic from the Windows code.

One thread pulling another. Again.

Previous: Part 1 — One Thread Pulled Another

Next: Part 3 — The God Object Has 69 Static Events