Skip to content

Commit

Permalink
fix: improved APM calculation accuracy
Browse files Browse the repository at this point in the history
* Improved APM calculation accuracy

The existing APM calculation is basically (actions / minutesPlayed) and minutesPlayed does not round at all, so if a game is 5m01s long, APM is calculated based on a game length of exactly 6 minutes. That causes minor inaccuracies which depend on the exact length of the game.
There's a larger inaccuracy, too - in a team game, if a player leaves but the game continues, the parser will continue adding 0s to the 'timed' list for each minute, so the leaver's APM is calculated not based on their ingame time but the total length of the replay.
It looks like currentTimePlayed is susceptible to inaccuracy via an AFKing player, but it seems like an acceptable compromise that the starting when a player begins AFKing through the end of the replay are not counted toward their calculated APM.

* Using the correct equality

* Test case for APM calc on an early leaver

* Refined team leave test cases

* Lint fix
  • Loading branch information
tylerkerr authored and PBug90 committed Jan 8, 2020
1 parent 0a02194 commit 107b7ab
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 1 deletion.
Binary file added replays/standard_129_3on3_leaver.w3g
Binary file not shown.
6 changes: 5 additions & 1 deletion src/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,11 @@ class Player {

cleanup (): void {
const apmSum = this.actions.timed.reduce((a: number, b: number): number => a + b)
this.apm = Math.round(apmSum / this.actions.timed.length)
if (this.currentTimePlayed === 0) {
this.apm = 0
} else {
this.apm = Math.round(apmSum / (this.currentTimePlayed / 1000 / 60))
}
this.heroes = reduceHeroes(this.heroCollector)
delete this._currentlyTrackedAPM
}
Expand Down
12 changes: 12 additions & 0 deletions test/replays.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,16 @@ describe('Replay parsing tests', () => {
expect(test.version).toBe('1.31')
expect(test.players.length).toBe(1)
})

it('evaluates APM correctly in a team game with an early leaver', () => {
const test = Parser.parse('./replays/standard_129_3on3_leaver.w3g')
const firstLeftMinute = Math.ceil(test.players[0].currentTimePlayed / 1000 / 60)
const postLeaveBlocks = test.players[0].actions.timed.slice(firstLeftMinute)
const postLeaveApmSum = postLeaveBlocks.reduce((a, b) => a + b)
expect(test.players[0].name).toBe('abmitdirpic')
expect(postLeaveApmSum).toEqual(0)
expect(test.players[0].apm).toEqual(98)
expect(test.players[0].currentTimePlayed).toEqual(4371069)
expect(Parser.msElapsed).toEqual(6433136)
})
})

0 comments on commit 107b7ab

Please sign in to comment.