Overly engineered redundancy

I just had a fairly textbook bug pop up, so I thought I’d write about it while it was still fresh on my mind. Unlike most “interesting” bugs, this one was both easy to locate and easy to fix – but it came about as a direct result of the way I had setup a system.

In this project, I have a 3D world divided up into cells and each cell can have a single structural frame or be empty and in order to place a frame in a cell, there has to be a frame in a cardinally adjacent cell. I have a global manager which handles creation and deletion of these frames, and I was investigating why creating or deleting frames from cells wasn’t properly triggering the creatability/deletability of frames in adjacent cells. It turned out that a reference to the cell itself wasn’t being passed around, and in fixing that issue I realised there was something I was forgetting – I hadn’t actually setup the system to ensure that there could only ever be a single frame in a cell.

So what I did was added a check to the manager’s creation function for any other frames, and if there were it would delete them. Unfortunately, I placed it after the new frame was created but before the new frame was initialized (I’d setup delayed initialization as an option to make larger or frequently resizing worlds lighter on the processor). Obviously that was completely the wrong place to put the check, as it not only attempted to delete the frame I’d just created, but it hadn’t been fully created so it was crashing every time.

Easy find, easy fix, simple mistake, but I see it as a direct symptom of a system that I engineering to not only be capable of everything I wanted it to do now, but also everything I thought I would want years down the track while still making it simple and modular enough to be expandable and adhere semi-strictly to OOP (or my garden-hedge understanding of it).

After about 12 hours over the past few days spent restructuring and cleaning up how frames and cells are handled, I’ve been reconsidering my policy of rewriting systems to be better under the hood. As a self-analysis process, this has been ongoing ever since I discovered Unity and Winforms coding over a year ago (quote “You don’t need to make the code good, because this is scrub coding land”) but I’m still on the fence with my conclusion – that a combination of the end product and the goals for making it are what justifies the approaches, procedures and technology used.

In case of this project, I wanted to make a well designed and robust system to account for complex gameplay and in doing so improve the quality and speed of designing/implementing systems that I work on… while working on it in my spare time. In other projects, if I wanted to create a game with specific gameplay and timeframe to work in, then I clear deliverables which override my desire to learn and work at my own pace in doing so. Where this has been an issue for me in the past is with university projects – it’s a learning environment where I want to maximise the convenience of being able to make frequent mistakes and effectively analyse them, but still succeed (the latter was essentially my approach for final project).

In a commercial environment it strikes me that the deliverables would be the goal, but for viability of long term usage/expansion the system under the hood needs be clean and maintainable. Anyway, I guess it’s just a line which everyone needs to work out before they start.