SDK 3.1: illusions and hero order
SDK 3.1.0 makes ordinary unit and hero views ignore illusions by default, while keeping copies available for apps that need them. It also exposes Warcraft's player-relative hero ordering key.
Updating is optional
Existing SDK 3.0 apps keep working with protocol 3.0. No forced minimum
version change or binding regeneration is needed for these fields. To use the
new types and selector behavior, install @w3booster/sdk@3.1.0, update your
lockfile, rebuild, and deploy your app. Add isIllusion to any typed fixtures
you construct yourself.
Illusions are available, but opt-in for selectors
Every observed Unit, Hero, and Building has isIllusion: boolean.
The raw player.units, player.heroes, and player.buildings maps retain all
observed instances, including illusions. Their usual visibility, scopes, and
plan rules still apply.
playerUnits, playerHeroes, and playerBuildings exclude illusions by
default. Pass { includeIllusions: true } when copies matter. These selectors
return immutable, memoized arrays in ascending full instance-ID order. Do not
sort the returned array in place. ID order is deterministic, not spawn order.
Follow Warcraft's hero order
Hero.heroOrder?: number is a positive player-relative ordering key. Lower
values come first. It may be absent until observed, and gaps are normal.
Ownership and lifecycle changes can reassign the key: it is neither a birth
timestamp nor a permanent F1/F2/F3 slot. Use (match.id, hero.id) for identity.
For a hero panel, copy the selector result and sort by heroOrder, then by the
full ID. This keeps a deterministic fallback when order has not arrived yet.
import type { Player } from '@w3booster/sdk';
import { playerHeroes, playerUnits } from '@w3booster/sdk/selectors';
export function heroPanel(player: Player) {
return [...playerHeroes(player)].sort((a, b) =>
(a.heroOrder ?? Number.MAX_SAFE_INTEGER) - (b.heroOrder ?? Number.MAX_SAFE_INTEGER)
|| (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
);
}
export function unitCopies(player: Player) {
return playerUnits(player, { includeIllusions: true })
.filter(unit => unit.isIllusion);
}
Availability
| Field | Scope and plan |
|---|---|
Ordinary unit isIllusion |
units:read, all plans |
Building isIllusion |
Follows buildings:read (all plans), or a production-only projection's production:read access |
Hero isIllusion and heroOrder |
heroes:read: PRO in self-play, free in observer/replay mode |
These fields do not grant access to opponents' hidden entities in self-play. Production remains PRO in self-play and free in observer/replay mode.
See the full API reference, data model and plan labels, and SDK changelog.