DEV Community

Taehyun Kim
Taehyun Kim

Posted on

Traceroute devlog #3

This week didn't feel like forward motion most of the time. It felt like trying the same door from four different angles and only getting it open on the last try, and then, separately, building something I was genuinely proud of and taking it back apart with my own hands a few days later.

 The difficulty problem started simple. The puzzles felt too easy, and worse, they didn't get noticeably harder as you moved deeper into the set. My first fix was to add a rule to the generator itself: keep the two endpoints of the same color from landing too close together, since that felt like the obvious source of the "too easy" feeling. I shipped it, ran the full batch, and watched the pipeline that had been reliably producing almost every level in the set collapse down to producing barely a quarter of them. Turning on detailed logging showed why. Almost the entire retry budget was getting burned on the generator rejecting its own boards for being "too close," and that rule was fundamentally at odds with how the generator fills a grid in the first place. It doesn't place two dots and connect them. It grows a full board and only pulls the endpoints out afterward, so telling it "don't let these end up close" was fighting its whole approach rather than nudging it.

 What actually broke the problem open was a question I asked myself in the middle of debugging it: why was I trying to bias the generator toward bent, spread-out paths at all, when the solver's own best solution for a board has nothing to do with the shape the generator happened to grow? The generator's internal path is thrown away anyway. Difficulty should be judged from what the solver actually finds, not from what the generator's random walk looked like on its way there. That reframing killed the endpoint-distance rule entirely and replaced it with a rule that checks the solver's real answer after the board exists, rejecting boards whose best solution turns out too simple, instead of trying to steer the generator toward simple-looking boards in the first place. It's a small shift on paper. It changed how I thought about every difficulty lever after that.

 The second attempt at making things feel harder was raising how heavily the scoring formula weighted the number of turns in a solution. I bumped it up expecting the puzzles to read as noticeably trickier. Nothing changed, and it took me a while to understand why: that weight only affects how already-generated puzzles get sorted and labeled after the fact. It doesn't make harder puzzles exist, it just reorders the ones I already had. I'd been polishing the label on the jar instead of changing what was in it.

 The version that actually worked was introducing a real floor on solver difficulty, tossing out any generated board whose best solution came in under a threshold for its tier, before it ever entered the pool. That worked, in the sense that the puzzles genuinely got harder to solve. It also immediately tanked the generation success rate again, in the same shape as the endpoint-distance failure, just for a more legitimate reason this time. So I raised the retry ceiling again to compensate, watched success recover, and by the end of the week I'd internalized that "make it harder" and "still be able to generate enough levels" aren't two problems you solve once each. They're the same knob, and every real difficulty change costs you something on the generation side that you have to go pay back.

 The other thread this week was smaller in scope but heavier to sit with. I built the feature that lets you start drawing a color's path from either of its two endpoints and have the two halves merge in the middle, the full logic, fully tested, verified working in the browser. It felt done. Then I actually played through it the way a real player would, drawing from one end, bending the path, and clicking toward the far endpoint expecting the two halves to connect. Instead the click got read as starting a brand new, independent path from that far endpoint going backward. On paper it followed the spec exactly. In practice it felt like the game had misunderstood what I was doing, every time. I pulled the entire feature back out, all of it, and put the simpler original behavior back. That's a strange kind of finished, work that passes every test you wrote for it and still turns out to be the wrong thing once a real hand is on the mouse.

 By the end of the week the generation pipeline was producing a full, working pool of levels, the obstacle system was actually wired into gameplay instead of just existing in the data, and two real solver bugs that had been quietly producing wrong answers were gone. But if I'm honest, most of what I'll remember about this week isn't any of that. It's how many times I built something correctly and still had to throw it out because correct and right aren't the same thing until someone actually plays it.

Top comments (0)