Revisiting Heroes with AI (and fixing a crash I could never have fixed alone)
I guess I’m using AI to fix my childhood.
When I was young I was a Mac gamer in a mostly PC world. I spent most of my time in Escape Velocity and Harry the Handsome Executive, but one of the games that stuck was Heroes of Might and Magic II. I fell for the music (with an amazing score by Paul Romero / Rob King / Steve Baca) and the art: gorgeous hand-crafted VGA-era 2D—town screens and creatures that to my childhood felt like illustration. HoMM II brought the series to prominence in the mid‑90s; but I wasn't tracking the market… for me it was the one that felt like I was playing inside the Michael Hague-illustrated version of The Hobbit. It was a complete fantasy toy box when I played it on my family's Bondi blue iMac.
As a kid, I didn't notice that the gameplay was unbalanced. In fact, I was more interested in the story than competitive play, so with most games I would find the GameFAQ guide, and use ResEdit to alter my savedgame files to add black dragons. While I was happily playing my game Heroes III (The Restoration of Erathia, 1999) was released and updated the design: adding towns and units, offering a random map generator, improving support for multiplayer, and giving birth to a scene that could actually sustain itself. Heroes III really solidified the franchise because it offered more strategic factions and balance, official and fan maps, LAN and later online play. Also, because the game was capable of running on relatively low-end hardware, it was also popular outside of North America. The Russian localization by Buka landed in 1999, and it became a phenomenon in Eastern Europe.
So during COVID, when I returned to gaming in a small way, I drifted to HOMMIII for playing, even when HOMMII stayed my favorite for atmosphere. The story of how the publisher—New World Computing—was eventually acquired by 3DO is a fascinating story, but beyond the scope of this small post :-)
If you're just in it for the art, HOMMIII probably isn't the game for you.
Heroes III moved toward higher-resolution (though definitely not high-resolution) sprites based on pre-rendered creature models, and a busier isometric battle board. To me, it’s an awkward blend of 2D presentation and early 3D-era rendering. It's sometimes interesting, but never gorgeous and usually muddier than the painted clarity of HOMMII. Some people disagree; but I don't think the position is very defensible.
Either way, today's community lives in III—tournaments, the Horn of the Abyss mod is seemingly the most popular but doesn't support the mod most popular in online competition ("Duel"). If I want to play in the ecosystem today, HOMMIII (or something compatible with it) is the table everyone’s sitting at.
VCMI is the way to play
VCMI ("Vinyar Callor Meletya Ingole" or "New Heroes of Might and Magic" in Quenya) is an open-source reimplementation of the Heroes III engine: the same general idea as “run the classic with modern platforms, mods, and AI,” complete with forums, Discord, and development on GitHub. I’m not good enough to play competitively (probably, I've never tried). so I don’t live in the ladder scene. For a long time that made me feel like a tourist in a game I’ve loved for decades.
Cursor, a crash, and feeling less like a tourist
Recently VCMI on my Mac started crashing randomly after I ended turns. I would get annoying macOS crash report windows that pointed at Metal / OpenGL being the culprit on the main thread. I had no idea how to interpret it, but I dumped the logs in Cursor and learned about what causes that kind of thing:
When a background thread throws and the process aborts, the UI thread can still be inside a frame update. macOS Crash Reporter showed the main thread first—plausible, but misleading. The real stack was on the embedded server thread:
BattleResultProcessor::endBattleConfirm → StatisticDataSet::getPlayerAccumulator.
I turned up logging and restarted from my safe. After one of the computer players battled some random creature, the log printed `Disaster happened.` and:
Invalid player color -1 for statistics accumulator
In VCMI, `-1` is `PlayerColor::NEUTRAL`. `getPlayerAccumulator` only accepts real map players; it expects `isValidPlayer()`, not “we checked `== NEUTRAL` somewhere and hoped.” The battle-end statistics path had that mismatch—plus a few related spots (strongest hero, surrender, escape) that assumed the loser was always a player color.
With Cursor (and the VCMI source tree), I could search the error string, read the throw site, patch `server/battles/BattleResultProcessor.cpp`, rebuild `vcmiclient`, and verify the same scenario no longer crashed. The fix went upstream as PR #7214. While others had already fixed the same class of bug elsewhere, the other fixes were for a different callsite. Phew! my work wasn't duplicative. I was happy I checked the upstream commits and other branches before committing the PR.
So the AI didn’t “auto-fix” the game in a vacuum. I had to reproduce, read the log, decide the patch was right, and own the PR. What Cursor changed was friction: faster navigation, less time lost to boilerplate, and enough confidence to touch a codebase I’d have treated as read-only a few years ago.
It was the second time I fixed a bug (the first was enabling the user to press the "escape" key to exit the inventory screen), but the first time I felt like I’d contributed to the VCMI side of the community.
I'm now no longer a tourist. I hope you can use the new tools to make some community improvements yourself!














