Development Diary #49: The Story of One Bug
During testing of
The Great Tribes, testers occasionally encountered a very strange issue: units appearing
on water. However, it was nearly impossible to reproduce this bug directly.
Jesus
The bug was so rare that we even had an internal meme — "This isn't a bug, it's the birth of a new religion in the game."
The problem remained a complete mystery. For six months, I couldn’t catch the bug — I simply couldn't reproduce it no matter what I tried.
Later, I introduced units with an extended line of sight — 25 tiles instead of the standard three — to make testing easier. With such a wide view, it became much easier to observe everything happening in the world, including AI behavior.
I went through all the code and double-checked every algorithm related to unit movement across the map. I found no issues — and still, I couldn't reproduce the bug.
Then, while preparing screenshots and gifs for the game's Steam page, I decided to increase the units’ line of sight even further — up to 50 tiles.
And that's when the bug started to pop up much more frequently.
During the search for beautiful locations for media content, I had to regenerate maps repeatedly.
And only
during this series of quick map generations, without restarting the game through the IDE but simply going back to the main menu and generating again, I finally caught the bug in action.
At that point, a pattern became clear:
Usually, I would launch the project from the IDE, generate a map, test a few things, exit the game completely, and restart.
But when regenerating maps
without leaving to the desktop, the bug appeared consistently.
All server-side world interactions passed through a global singleton: ServerContainer.
When a new server was launched for a new map, the
old ServerContainer remained, keeping old links to units and map data — leading to this broken behavior.
Luckily, I already had a cleanup() method inside ServerContainer, which was supposed to clear all critical data after exiting a game session. Some resources (like cached templates and configurations) were intentionally preserved to speed up new world generation.
And then it hit me — the cause was obvious:
I simply forgot to
call cleanup() when exiting the server session.
Lesson learned:
Don't make mistakes like that!
Wishing you all smooth code and great mood!