October 16, 2025 By WBG Development Team
wildermine technical game-design debugging tower-mechanics

Ghost Towers and Fragile Webs: Untangling a Sneaky Build-Radius Bug

How we debugged a phantom tower dependency bug that only appeared after a precise choreography of placements, and discovered that coverage-first thinking solved what graph theory couldn't.

Ghost Towers and Fragile Webs: Untangling a Sneaky Build-Radius Bug

Ghost Towers and Fragile Webs: Untangling a Sneaky Build-Radius Bug

If you’ve ever chased a phantom bug that only appears when the stars align, you’ll appreciate this one. Our tower puzzle game had a doozy. The first bug we wanted to fix can be seen in the hero image of this article: “Can’t remove tower! 2 buildings depend on it.”

Well, that was not correct. Or at least, that wasn’t the intended behavior. Towers placed within the starting buildings radius are not / should not be dependent on other towers.

In trying to fix that bug, we then ran into an issue where towers that should have been mutually redundant would happily let you bulldoze the entire safety net, leaving “orphaned” structures sitting on tiles that had no direct connection back to the starting building. It only surfaced after a very particular choreography of placements—exactly the kind of edge case players discover five minutes after launch.

Build Radius Bug
Tower A, B, and C showing overlapping building radii

The Tell-Tale Symptom

Here’s the dance that revealed the bug:

  1. Drop Tower A inside the starting hub’s buildable radius.
  2. Stretch outward with Tower B, landing it on tiles enabled solely by Tower A.
  3. Place Tower C also inside the starting radius, overlapping both A and B.
  4. Delete Tower A. Then delete Tower C.

Tower C should not have been destructible because it left Tower B stranded and illegally placed. Our dependency system clearly wasn’t following the intended logic.

Attempt #1 – Dependency Lists and Wishful Thinking

We began with a straightforward “tree-of-dependents” approach: each provider kept a set of placements it enabled. In theory, removing a tower was as simple as checking whether its dependent set could fall back to another provider. In practice, a tree of dependents isn’t additive—it can’t express that overlapping radii (A ∪ C) keep B alive even if neither A nor C alone covers B. Treating dependencies like a strict tree ignored those conjunctive relationships.

We tweaked the sets, reversed parent pointers, and even tried walking up a “most recent provider” chain. Each iteration handled a few more cases but still crumbled when multiple towers jointly sustained a dependent footprint.

Diagram showing set overlaps vs. single-provider dependency tree
Tower A, B, and C showing overlapping building radii

Attempt #2 – Classic Graph Theory, With a Catch

We next considered modeling towers as a graph and using articulation-point logic to ask “what breaks if we pull node X?” Conceptually neat, but it can’t express that a building’s footprint might be kept legal by A + C together. That limitation would misreport certain cases, so we pivoted to a coverage-first approach.

The Breakthrough – Reachability in Coverage Space

The fix arrived once we stopped thinking in terms of “who depends on me?” and started asking “which tiles stay legal if I vanish?” We built a coverage frontier:

  1. Start with the base’s radius as the seed coverage.
  2. Iteratively promote towers whose entire footprint is already inside the current coverage union.
  3. Each promoted tower adds its radius to the union, possibly enabling more towers, and so on until no new coverage appears.

When evaluating Tower X, we run the process twice: once with everybody present, and once with X temporarily removed. Anything that was reachable before but not after is a genuine dependency. That includes other towers and any building whose footprint tiles drop out of the coverage union. The same routine powers both the actual deletion check and the UI toast that warns players which structures would be stranded.

Why It Works

  • Coverage-first: We reason about tiles, not graph edges, so overlapping radii combine naturally.
  • Single source of truth: The deletion UI and the simulation share the same reachability function, eliminating stale dependency lists.

Lessons Learned (and Retold)

Reframing the problem from “ownership” to “coverage” gave us a richer mental model and a robust system. It’s a reminder that spatial mechanics often demand spatial solutions; forcing them into graph or tree metaphors can hide what is actually a simple problem.

Next time your game world lets a building exist on an island of impossibility, take a step back and ask: what actually keeps this tile alive? Odds are, the answer is hiding in the geometry of your simulation, not the edges of your data structures.

WBG Logo

Written by WBG Development Team

Part of the passionate team at Wrinkled Brain Games, creating innovative gaming experiences.