Mid-week I ran into something that made me stop and take stock: was I building on a foundation I already knew was cracked?
Most of the click-based path drawing was done by then — starting a path, extending it in a direction, blocking it when it ran into another color, refusing to let it cross itself. All of that was tested and working. The last piece on the list was letting the player undo part of a path by clicking back onto a point it had already passed through. It sounded like the simplest rule of the bunch. It wasn't, mostly because of how everything before it had been built.
Up to that point, every rule just edited the current path directly — added a cell here, removed one there, always working on the same object sitting in memory. That was fine as long as no rule needed to remember what things looked like before the current click happened. Undo breaks that assumption completely: it has to reach back to "the path as it stood right before this click" and rebuild from there, and if you've been quietly editing that same object the whole time, there's no earlier version left to reach back to. The data just says what it currently says.
So the actual fix wasn't really about the undo rule itself — it meant going back through everything I'd already built and changing the underlying pattern it was written in: instead of editing state in place, every step now has to produce a brand new copy of the game state and hand that off, leaving the old one completely untouched. That touched code across five already-tested rules, not just the new one, which meant redoing work I'd already called finished for the week. I didn't want to. But patching around the problem instead of fixing the pattern felt like it would just resurface later in a worse spot, probably right when I start animating state changes on screen, which is coming up soon. Doing the rebuild properly also surfaced a bug I hadn't caught on my own — a leftover, empty entry that could get left behind in the data after certain clicks. Harmless by itself, but the kind of thing that's confusing to debug later if it stays hidden long enough.
Separately, I misjudged a self-intersection test case — the rule where clicking back over a point your own path already crosses should invalidate the whole move — and was confident it was actually a different rule firing, undo instead. It wasn't. I'd misread which cell the click sequence actually landed on once I traced it out step by step. Easy enough to fix once I saw it clearly, but a good reminder of how easy it is to be wrong about grid coordinates specifically, in a way that feels obvious only after someone points at the right cell.
One visual bug also got fixed this week: the small "bounce back" animation that plays whenever a click gets rejected was cutting off partway through its motion instead of completing it, so a rejection read as a brief freeze rather than a clear "no." Rewriting it to track elapsed time properly, instead of skipping frames under load, fixed that.
Outside those threads, the week was mostly foundation work: the project now builds and deploys automatically, the grid and dots render with a colorblind-friendly palette, and all of the click-based path rules are built and checked against tests. I closed the week starting on the logic that decides when a level counts as solved, which felt like a natural place to stop.
Top comments (0)