Week 14
The Final Push
In my little mind, open source represents the clash between hope and fear. The idea that a third-year computer science student, like myself, could contribute to a repository where more than 110, 000 lines of code were committed within a month is tantalising. Let me make myself clear – I dislike game development; it is messy, has to deal with a graphical user interface, the calculations are arbitrary, code design is usually all over the place, abstraction layers are inconsistent, and so on. In other words, it is utter chaos. But that is what we dreamed of, right? To see the metaphorical phoenix rise out of the chaotic ashes? Then, that is what we shall do.
Recce
One of my teammates, Yi Zong, took a good look at the code we were supposed to fix. Before that, we had posted on the forums, texted on the IRC channels and contacted the developers through Discord.
All this to make sure we, as newcomers, do not break the code’s design and squeeze out every ounce of goodwill we can from the veterans. It was a brilliant attempt at letting the experienced guide the young, and avoid any callous behaviour. Learning from my previous assignments, the last thing we ever wanted was to infuriate an open source community. We sifted through the code relatively quickly – if by quick you mean two weeks – and came up with a recipe for the fix. “Flawless,” we told ourselves.
Recipe For Disaster
Our issue was simple; at least, theoretically. When unloading an ammo belt, the player should be able to interrupt the unloading. The files in question were game.cpp
, activity_handlers.cpp
, and player.cpp
. The rest of the changes were aesthetic. Once an item
was passed onto an activity handler, it would become interruptable, and we would be done. Easy, right? Well, we quickly realised that we could not just move an item
into the activity_handler
instead, we would have to pass it through a variable called item_location
and later on extract it back inside the activity_handler
. Once I drew up the pseudocode on my whiteboard, I was thrilled. “This is brilliant engineering,” I chuckled, “maybe even cunning”.
It wasn’t.
Manoeuvre
The function that actually unload
s the item from the player’s inventory was inside game.cpp
. Specifically, it was localised there. There was no way to access this function from any other file or even the game
class itself. “Helper functions, for the win,” I said sarcastically. We were now at a crossroads, Yi Zong with his talents and experience thought it best to move game::unload()
and the relevant sub-functions into the player
class; in fact, he even made a separate branch for that purpose. It was time for mild discord – no, not Discord, the software. We wrestled with the idea of keeping the game’s API change to a minimum. Despite respectful disagreements from Yi Zong, I implemented the handler function without major changes to the API. A critical function, add_or_drop_with_msg()
had to be moved, so we compromised on that. We put all the relevant code in the same place, and we felt satisfied with our execution. Alfred, then went on to make some revisions on the code and Yi Zong refactored some function calls into their proper place. All done, then.
Well, that’s not how software engineering works. There is always a catch. And ours was a big one.
The Big Catch
Aflred diligently downloaded the latest commits and tested on his computer to see if the issue was fixed – whether unloading the ammo belt was interruptible. He went through the standard reproducing behaviour, and it worked! We did it! We fixed the issue that we have been working on for the past few days! Or, so we thought. Yi Zong quickly found out that when there are no monsters nearby, unloading the ammo would send the player to oblivion (i.e. the game crashed). Alfred, then, uncovered that as soon as you access the inventory after unloading the item, it was back to the nether – the game crashed again. All we could discover were some crash logs and error outputs. We fell into the old software switcheroo – you fix one bug, you make ten.
Applying the Band-Aid
We issued the Pull Request and marked it as a work-in-progress (WIP) while we kept sifting through the code and conceiving of every possible scenario. Alfred, moreover, was testing through all the other scenarios and edge cases to make sure there are no unwanted behaviours. Finally, Yi Zong pushed another commit to the branch that fixed the issue of unloading the ammo belt when there are no monsters nearby. The other one, however, remained. Did we bite off more than we could chew? Maybe. Although our celebrations were cut short, we quickly began to appreciate the thrilling nature of open source software – you never know what repercussions your actions will have.