replay.tracker.events is an array containing events whose types are specified in the lib/protocol#####.js
files under the tracker_event_types
variable.
Convert m_unitTagIndex
and m_unitTagRecycle
into a unit tag m_tag
with protocol.unitTag(m_unitTagIndex, m_unitTagRecycle)
.
m_tag
is useful to determine what unit was targeted by a skill, for example in this NNet.Game.SCmdEvent
present in the replay.game.events
file:
{
"_eventid": 27,
"m_unitGroup": null,
"_event": "NNet.Game.SCmdEvent",
"m_abil": {
"m_abilLink": 147,
"m_abilCmdIndex": 0,
"m_abilCmdData": null
},
"_gameloop": 2365,
"_bits": 264,
"m_data": {
"TargetUnit": {
"m_snapshotControlPlayerId": 6,
"m_snapshotPoint": {
"y": 235853,
"x": 579289,
"z": 32441
},
"m_snapshotUpkeepPlayerId": 6,
"m_timer": 0,
"m_targetUnitFlags": 111,
"m_snapshotUnitLink": 281,
"m_tag": 45350913
}
},
"_userid": {
"m_userId": 5
},
"m_cmdFlags": 2097408,
"m_sequence": 451,
"m_otherUnit": null
}
We see that the unit with tag 45350913
was the target of the ability id 147
casted by player 5
.
Convert m_tag
into a unit tag index m_unitTagIndex
and unit tag recycle m_unitTagRecycle
with protocol.unitTagIndex(m_tag)
and protocol.unitTagRecycle(m_tag)
.
There is a known issue where revived units are not tracked, and placeholder units track death but not birth.
The first 10 events are NNet.Replay.Tracker.SPlayerSetupEvent
events, one for each player. Should check if there are also 10 if playing with or versus A.I.
Events contain generic properties and type specific properties.
Event type.
Not a unique identifier.
In NNet.Replay.Tracker.SPlayerStatsEvent
, m_scoreValueFoodUsed
and m_scoreValueFoodMade
are in fixed point (divide by 4096 for integer values). All other values are in integers.
Index of the player in arrays referencing players elsewhere?
All these stats field seem to be from the Starcraft 2 engine. Don't know if any is actually useful for Heroes of the Storm.
NNet.Replay.Tracker.SUnitBornEvent
events appear for units that are created fully constructed.
You may receive a NNet.Replay.Tracker.SUnitDiedEvent
after either a UnitInit or UnitBorn event for the corresponding unit tag.
Player generating the event. Index ranging from 0 to 15?
Known values:
- 0 - (when
m_unitTypeName
equalsDiabloShrine
, should check if it's because diablo was in the game's slot 0) - 11 - one of the teams
- 12 - the other team
Always identical to m_upkeepPlayerId
?
See note concerning unit tags at the top of this document.
See note concerning unit tags at the top of this document.
Name for different units. Several with the same name can be born.
Known values:
- CampOwnershipFlag
- CatapultMinion - The catapult
- DiabloShrine - Diablo's trait respawn point? Not unique.
- FootmanMinion - The normal minion
- GhostShipBeacon - Ghost ship you can 'controll' by paying coins
- ItemSoulPickup - Item you can pickup in the
Tomb of the Spider
Map, awards 1 gem. - ItemSoulPickupFive - Item you can pickup in the
Tomb of the Spider
map, awards 5 gems. - ItemSoulPickupTwenty - Item you can pickup in the
Tomb of the Spider
map, awards 20 gems. - JungleGraveGolemDefender - Boss unit summoned in
Cursed Mines
map - JunglePlantHorror
- KingsCore - The core of each team
- LuxoriaTemple - Temple you can controll in the
Sky Temple
map - MercLanerMeleeOgre - Siege mercenaries
- MercLanerSiegeGiant - Boss mercenarie that appears on most of the maps
- MercLanerRangedOgre - Another siege mercenarie
- RangedMinion - Ranged minion
- RegenGlobe - A pickable unit that grants a small health and mana amount
- RegenGlobeNeutral - A pickable unit that grants a small health and mana amount, usually drops when fighting bosses, it's color is purple.
- SoulEater - Big spider summoned when a team completes the required amount of item souls.
- SoulEaterMinion - Medium spiders summoned by the big spider in the
Tomb of the Spider
map - StormGameStartPathingBlocker - Gate blockers at the beginning of the game?
- StormGameStartPathingBlockerDiagonal - Gate blockers at the beginning of the game?
- TownCannonTowerDead
- TownCannonTowerL2
- TownCannonTowerL2Standalone
- TownCannonTowerL3
- TownCannonTowerL3Standalone
- TownGateL215BLUR
- TownGateL215BRUL
- TownGateL2BLUR
- TownGateL315BLUR
- TownGateL315BRUL
- TownGateL3BRUL
- TownMoonwellL2
- TownMoonwellL3
- TownTownHallL2
- TownTownHallL3
- TownWallRadial14L3
- TownWallRadial15L3
- TownWallRadial16L2
- TownWallRadial17L2
- TownWallRadial17L3
- TownWallRadial18L2
- TownWallRadial18L3
- TownWallRadial19L1
- TownWallRadial19L2
- TownWallRadial19L3
- TownWallRadial20L3
- TownWallRadial21L3
- TownWallRadial2L3
- TownWallRadial3L3
- TownWallRadial4L2
- TownWallRadial4L3
- TownWallRadial5L2
- TownWallRadial5L3
- TownWallRadial6L2
- TownWallRadial6L3
- TownWallRadial7L2
- TownWallRadial7L3
- TownWallRadial8L3
- TownWallRadial9L3
- TownGateL2VerticalLeftVisionBlocked
- TownGateL2VerticalRightVisionBlocked
- TownGateL3BLURBRVisionBlocked
- TownGateL3BLURTLVisionBlocked
- TownGateL3BRULBLVisionBlocked
- TownGateL3BRULTRVisionBlocked
- TownGateL3VerticalLeftVisionBlocked
- TownGateL3VerticalRightVisionBlocked
- WeaponRackSpecialHeaven
- WizardMinion - Wizard minion, usually drops a health globe when it dies
Should map values to known in-game elements. Check each value count to narrow down what they could be.
Does the L2 and L3 suffix reffer to each team? Each color? Orientation?
Create tool to extract values programmatically instead of by hand.
Always identical to m_controlPlayerId
? See for details
Unit spawn x
coordinate.
Unit spawn y
coordinate.
You may receive a NNet.Replay.Tracker.SUnitDiedEvent
after either a UnitInit or UnitBorn event for the corresponding unit tag.
References who gave the fatal blow to the unit that died.
m_unitTagIndex
for the unit that killed a particular unit, useful when the killer is not a human player but a NPC.
See note concerning unit tags at the top of this document.
m_unitTagRecycle
for the unit that killed a particular unit, useful when the killer is not a human player but a NPC.
See note concerning unit tags at the top of this document.
See note concerning unit tags at the top of this document.
See note concerning unit tags at the top of this document.
Unit death x
coordinate.
Unit death y
coordinate.
This event occurs when a unit changes ownership, for example when the Dragon Statue is controlled by a team:
{
"m_unitTagIndex": 104,
"m_unitTagRecycle": 110,
"m_controlPlayerId": 11,
"_eventid": 3,
"_event": "NNet.Replay.Tracker.SUnitOwnerChangeEvent",
"_gameloop": 16102,
"_bits": 176,
"m_upkeepPlayerId": 11
}
Here m_upkeepPlayerId
/m_controlPlayerId
is 11, meaning the control of the statue was granted to the blue team.
References a player.
Always identical to m_upkeepPlayerId
?
See note concerning unit tags at the top of this document.
See note concerning unit tags at the top of this document.
References a player.
Always identical to m_controlPlayerId
?
Known values:
- TownCannonTowerDead
Limited number at the beginning of the game.
Also used to determine when a unit is upgraded, for example when a player is transformed to a Dragon in the Dragon Shire map.
{
"m_playerId": 4,
"_eventid": 5,
"m_count": 16,
"_event": "NNet.Replay.Tracker.SUpgradeEvent",
"_bits": 296,
"_gameloop": 16165,
"m_upgradeTypeName": "VehicleDragonUpgrade"
}
Here, the player with m_playerId
of 4
, which belongs to the blue team, took the dragon and was upgraded to VehicleDragonUpgrade
unit.
References one of the 16 game slot, need to find which.
Probably not always referencing a player because a possible value is 15
?
Known values:
- CreepColor
- GatesAreOpen
- IsPlayer11
- IsPlayer12
- MinionsAreSpawning
- VehicleDragonUpgrade
Not encountered in data dump. Structure extracted from source code.
NNet.Replay.Tracker.SUnitInitEvent
events appear for units under construction. When complete you'll see a NNet.Replay.Tracker.SUnitDoneEvent
with the same unit tag.
You may receive a NNet.Replay.Tracker.SUnitDiedEvent
after either a UnitInit or UnitBorn event for the corresponding unit tag.
Not encountered in data dump. Structure extracted from source code.
-
Interpret the NNet.Replay.Tracker.SUnitPositionsEvent events like this:
var unitIndex = event.m_firstUnitIndex; for (var i = 0, ln = event.m_items.length; i < ln; i += 3) { unitIndex += event.m_items[i + 0]; var x = event.m_items[i + 1] * 4; var y = event.m_items[i + 2] * 4; // unit identified by unitIndex at the current event._gameloop time is at approximate position (x, y) }
-
Only units that have inflicted or taken damage are mentioned in unit position events, and they occur periodically with a limit of 256 units mentioned per event.
One and only one for each player at the very beginning of the event list.
Reference to the player, ranges from 1 to 10.
Index for the player, ranges from 0 to 9.
Identical to m_userId
.
Depends on if the player is a real person or a bot?
- 1 = real player?
Index for the player, ranges from 0 to 9.
Identical to m_slotId
.