Linken’s Sphere: Evolution, Mechanics, Bugs and Fixes
Introduction: The Evolution of Linken's Sphere
In early versions of DotA, the item
Linken's Sphere (hereafter — Linken, Linken's Sphere) was based on the
Amulet of Spell Shield (hereinafter — Spell Shield) which blocked standard spells. However, a problem quickly emerged: how to distinguish default abilities from custom ones.
Default Abilities
These are abilities built into the Warcraft III engine, for example:
Storm Bolt —
Mountain King
Slow —
Sorceress
Blizzard —
Archmage
Their behavior can only be modified by patching the game.dll file — a complex task.
Custom Abilities
They were created by DotA map authors using map scripting.
For example, the custom ability
Magic Missile used by
Vengeful Spirit is actually just a modified
Storm Bolt (hereafter — Bolt). You can change the icon, projectile, description, and animations, but you can’t make Bolt both stun and slow the target simultaneously.
The solution was found quickly: use one default ability as a base and overlay a second effect via code.
Example —
Void used by
Balanar.
- Damage and ministun are provided by the Bolt.
- The slow is based on Slow, which is cast by a Dummy unit (hereafter — dummy).Dummy is an invisible, invulnerable unit created by code, performs a specific action, and is usually removed afterward.
Amulet of Spell Shield cannot block such a spell. Since dummy has no cast animation and Slow has no projectile, the slow effect is applied first and breaks Spell Shield, and only then does Bolt hit (with speed 10000 and no projectile animation).
Linken's Sphere Rune and Its Mechanics
Since the game engine doesn’t allow checking whethe
Amulet of Spell Shield is active or on cooldown, IceFrog created a custom version of
Linken in one pf the map updates.
The item itself is a placeholder that blocks nothing, but upon pickup, the hero receives the
Linken's Sphere Rune (hereafter — Rune).
You may have seen the old bug where the Rune drops on the ground when granted: https://www.youtube.com/watch?v=kii4c_I1YVU
This happened if the hero was off the map during the item handoff (for example,
Astral Imprisonment,
Disruption,
Burrowstrike,
Supernova), or had a locked inventory (
Meat Hook during the throw). The Rune would remained on the ground near the hero.
IceFrog partially fixed this by implementing logic: if the hero fails to pick up the Rune, it’s deleted and the handoff is retried until successful.
In fact,
Rune is based on another standard item
Rune of Shielding, which grants a shield that blocks one enemy spell.
Its behavior is similar to Spell Shield, but the key difference is that it applies a status buff, which can be checked via code.
IceFrog introduced a function, whose name is unknown due to code obfuscation, but we assume it looked like this:
function IsUnitHasNegation takes unit u returns boolean
return GetUnitAbilityLevel(u, 'B0BI') > 0
or GetUnitAbilityLevel(u, 'BNss') > 0
or GetUnitAbilityLevel(u, 'B0EV') > 0
endfunction
This function checks whether the unit has the Rune buff ('B0BI').
From then on, custom abilities began checking for the Rune buff. If present, the rest of the code — dummy creation, slow application, or other effects — is skipped. The buff is consumed, blocking the base ability.
However, IceFrog missed a few dozen abilities that lacked this check, resulting in incomplete implementation. In our map, all identified problematic abilities have been fixed and now interact correctly with Linken.
Bug with Dummy and AOE Abilities
Other issues arose: some abilities don’t target units but affect areas.
Example —
Shrapnel used by
Dwarven Sniper. It’s based on a channeling ability — essentially a placeholder where targeting type and targets can be configured. Since the base ability does nothing, its entire effect is implemented via map code.
The slow effect in Shrapnel (DotA by IceFrog) is again the same
Slow, applied by a dummy. However, IceFrog made a mistake and assigned the dummy’s owner as Dwarven Sniper himself, instead of the hero being slowed. As a result, the
Rune buff would trigger and be consumed. Fortunately, we’ve corrected this error.
Bug with Linken's Sphere After Selling
https://www.youtube.com/watch?v=ORKW3tgYXgE
It’s tied to how
Linken's Sphere is implemented. Since it’s coded into the map, it doesn’t technically reflect anything — the actual blocking is done by the Rune buff granted to the hero. The cooldown animation is nothing more than a visual illusion created by extensive scripting.
Technical Details
The map script includes a loop that runs every 0.33 seconds from game start, checking each hero’s status: alive, present on the map, and Linken cooldown counter.
If the counter is greater than 0, the hero is alive and present on the map, but does not have the reflecting buff, an additional function is triggered. This function scans the entire inventory, looks for Linken Spheres (if there happen to be more than one), drops them on the ground, and deletes them. Then it creates fake Linkens in the inventory of a Dummy unit with the same stats. These fake Linkens have no targeting and cannot be used on allies. When clicked, they go on cooldown. The script simulates a click, the Linkens go on cooldown, and then they are handed back to the hero.
All of this happens almost instantly — the player doesn’t notice anything and simply sees the cooldown animation. Meanwhile, a timer is created that waits for the
Linken cooldown duration, or until the hero revives (if they died during that time), in order to grant the Rune and replace the item in the inventory.
But why did the
Rune buff remain even after selling the item?
The reason is that due to a bug in the item drop and pickup code, recursion (repetition) occurs in the trigger that tracks Linken counters. With each recursive call, the counter increases, and the code doesn’t check whether the hero still has Linken in their inventory — it’s enough for the counter to be greater than 0.
Fixing the Problem with a Global Variable
Why such “band-aid” solutions were needed is unclear. But we found a fix.
By adding a global *boolean variable ItemBool, and checking its value in the trigger that reacts to item pickup and drop, we now:
- change the variable’s value before starting Linken’s cooldown,
- reset the value after the cooldown is triggered,
- prevent recursion,
- and keep the counter equal to the actual number of Linken Spheres the hero owns.
Let’s be honest — no one really wants to buy more than one Linken.
Conclusion
This wraps up our overview of this wonderful item. We’ve examined its mechanics, the problems it carried through the years, and an elegant solution. Reading all this is like building a Linken from scratch — and you did it 🙂
