FortCharacter.Damage() seems to be unperformant

Good observation, but I think it might actually not be related to increased damage values.

I setup an extended Test Project for this. This project inflicts different Damage values on the Player and each Damage Value gets applied 20 times for a robust data set.

These are the runtimes I profiled:

DamageFunction Runtime(ms)
Damage(1) average 0.529395
Damage(2) average 0.47123
Damage(4) average 0.49374
Damage(8) average 0.48028
Damage(16) average 0.48336
Average 0.491601
Damage(10) average 0.49534
Damage(20) average 0.528975
Damage(40) average 0.49866
Damage(80) average 0.52665
Damage(160) average 0.495495
Average 0.509024
Damage(100) average 0.51842
Damage(200) average 0.483995
Damage(400) average 0.53698
Damage(800) average 0.52955
Damage(1600) average 0.52165
Average 0.518119

So it does not seem like higher damage values influence the runtime of Damage().

But I observed something different while testing. Each time I performed a Verse change and pushed that to the session, the runtimes of the Damage() function increased.

Take a look:

Verse Push 1

DamageFunction Runtime(ms)
Damage(1) average 0.584855
Damage(2) average 0.5929
Damage(4) average 0.76719
Damage(8) average 0.757815
Damage(16) average 0.627705
Average 0.666093
Damage(10) average 0.6867
Damage(20) average 0.787575
Damage(40) average 0.60073
Damage(80) average 0.626065
Damage(160) average 0.633705
Average 0.666955
Damage(100) average 0.644415
Damage(200) average 0.60908
Damage(400) average 0.578215
Damage(800) average 0.58201
Damage(1600) average 0.602735
Average 0.603291

Verse Push 2

DamageFunction Runtime(ms)
Damage(1) average 0.669625
Damage(2) average 0.734505
Damage(4) average 0.63252
Damage(8) average 0.61244
Damage(16) average 0.603105
Average 0.650439
Damage(10) average 0.586915
Damage(20) average 0.60473
Damage(40) average 0.62434
Damage(80) average 0.66466
Damage(160) average 0.617105
Average 0.61955
Damage(100) average 0.636835
Damage(200) average 0.626705
Damage(400) average 0.61065
Damage(800) average 0.62133
Damage(1600) average 0.625995
Average 0.624303

Verse Push 3

DamageFunction Runtime(ms)
Damage(1) average 0.71006
Damage(2) average 0.93862
Damage(4) average 0.94068
Damage(8) average 0.94012
Damage(16) average 0.965275
Average 0.898951
Damage(10) average 0.694335
Damage(20) average 0.683825
Damage(40) average 0.72325
Damage(80) average 0.74583
Damage(160) average 0.67905
Average 0.705258
Damage(100) average 0.65615
Damage(200) average 0.68986
Damage(400) average 0.68032
Damage(800) average 0.65459
Damage(1600) average 0.65222
Average 0.666628

Verse Push 4

DamageFunction Runtime(ms)
Damage(1) average 0.75161
Damage(2) average 0.84514
Damage(4) average 0.81282
Damage(8) average 0.767105
Damage(16) average 0.73969
Average 0.783273
Damage(10) average 0.754245
Damage(20) average 0.758615
Damage(40) average 0.715425
Damage(80) average 0.696735
Damage(160) average 0.73606
Average 0.732216
Damage(100) average 0.731175
Damage(200) average 0.695135
Damage(400) average 0.688925
Damage(800) average 0.74599
Damage(1600) average 0.719975
Average 0.71624

So that might explain why your runtimes increased with higher damage values, because you probably pushed Verse changes in between.

And also dying from Damage() seems to be very costly with around 3.0ms-5.0ms, which might explain your runtime of 4.6 ms when inflicting 200 damage.

Regarding your question if the runtime is really too long:

My opinion, that the runtime is too long is based on the operations that such a function should be performing:

  • Decrease the player health by the amount of damage
  • Check if the player died after applying the damage
  • Trigger an event that the player health changed
  • Trigger an event if the player died

Each of the listed operations costs under normal circumstances something like 0.00X ms to 0.0X ms.

So in sum it should never even exceed 0.1 ms and it also must not be a costly operation, because in a game like fortnite it is a really frequently called function.

2 Likes