Sentry Ward
Contract
Aeye is ROC/TFT CAbilityEvilEye (parent AAsm). AIsw is an item alias whose
code is Aeye, so it shares the procedure and reads its own row through
abilityitem_t.code. APwt (Rune of the Watcher) uses the same code=Aeye family but is an
automatically consumed power-up with a permanent Watcher Ward summon.
| Rawcode | Archive | Notes |
|---|---|---|
Aeye |
ROC and TFT | Witch Doctor Sentry Ward |
AIsw |
ROC and TFT | item Sentry Ward (code=Aeye) |
APwt |
TFT | Rune of the Watcher — registered power-up; permanent ward |
Point cast summons an invisible timed detection ward. True sight comes from the
ward unit's Adt1 (CAbilityDetector, code=Adet) detect range (Rng), not
from Aeye Data cells (Aeye has no DataA–I).
Authoritative Fields
| Field | Meta | Stock Aeye TFT | Stock AIsw TFT | Runtime meaning |
|---|---|---|---|---|
UnitID |
Ward Unit Type (hwdu, shared with Ahwd) |
oeye |
oeye |
ward unit (S_SpellUnitId) |
Dur / HeroDur |
600 |
300 |
ward timed life (BTLF) |
|
BuffID |
Beye |
Beye |
summoned-ward presentation; not required for detect | |
Cost |
50 |
0 |
ROC omits UnitID / BuffID on both rows.
oeye UnitAbilities: Adt1,Aeth. Stock Adt1 TFT: Rng=1100, DataA=3
(detectionType). OpenWarcraft exposes a player-aware S_UnitIsDetectedByPlayer query. A Sentry Ward contributes its stored Adt1 range only to its owner and viewers receiving that owner's shared vision; the legacy S_UnitIsDetected helper remains as an aggregate compatibility query.
Data Flow
AbilityData.slk (Aeye / AIsw)
-> UnitID, Dur
CAbilityEvilEye
-> S_SummonAt(caster, UnitID, point, Dur)
-> ward.summon_ability = cast rawcode; RF_HIDDEN
-> ward.wait = Adt1 Rng (detect radius)
S_UnitIsDetectedByPlayer(unit, viewer)
-> viewer owns/shares vision with detector
-> target is enemy to detector and inside authored detection radius
-> viewer-specific visibility/selection/targeting may reveal known gameplay invisibility
-> outgoing snapshot clears RF_HIDDEN locally without changing authoritative entity state
FOW reveal while the ward itself is RF_HIDDEN is still a separate gap (invisible wards should still grant owner vision). Detection itself is no longer a global hidden-state toggle: Far Sight and passive detector abilities share the viewer-specific path, and non-invisibility RF_HIDDEN states remain hidden.
Diagnostic Workflow
build/bin/ability_audit -data 'data/Warcraft III' -raw Aeye
build/bin/ability_audit -data 'data/Warcraft III' -raw AIsw
build/bin/ability_audit -data 'data/Warcraft III' -raw Adt1
Verification
Rune of the Watcher
APwt uses AB_ITEM | AB_POWERUP. On acquisition it summons the ability's
UnitID at the collector's position, belonging to the collector's player. The
ordinary Aeye/AIsw Dur and HeroDur timed-life rule does not apply:
Blizzard's Rune of the Watcher explicitly creates a ward without a timer.
The summoned ward retains summon_ability=APwt, RF_HIDDEN, and the Adt1
detection radius in wait. This reuses the normal player-specific detection
logic; its model, invulnerability and ordinary sight come from the spawned
unit's authored UnitData. Activation effect uses the ability's EffectArt where
present; item collection reuses the common pickup sound and event lifecycle.
The existing invisible-ward owner-fog-vision gap remains independent of this
rune and needs a separate test/fix. Confirm stock APwt UnitID and ability effect
art with ability_audit against an installed TFT archive before claiming exact
retail presentation parity.