Both writing to perf.log frequently as well as GetTimestamp
aren't free and hurt performance particularly on slower systems
(which can have notably higher output to perf.log, further
amplifying the problem).
Therefore we make simulation perf logging opt-in.
Additionally, logging of the current tick and tick type
(local/net) is removed from debug.log, and some
remnant debug logging for kills and pips is removed
to keep performance-sensitive logging limited to
perf.log.
A mere int comparison is obviously cheaper than
a comparison between two multiplications,
so pulling this above the checks of other damage states
allows us to bail early for undamaged actors.
Profiling has shown that filtering them out early is cheaper
than applying those percentage modifiers anyway.
Additionally, profiling shows foreach loops to be cheaper
than LINQ here as well.
Inits that are logically singletons (e.g. actor
location or owner) should implement this interface
to avoid runtime inconsistencies.
Duplicate instances are rejected at init-time,
allowing simpler queries when they are used.
A shared ValueActorInit<T> is introduced to reduce duplication
in the most common init cases, and an ActorInitActorReference
allow actors to be referenced by map.yaml name.
During heated battles, those TraitsImplementing look-ups in Health might cause bursty CPU load on warhead impacts. Caching the notify traits of the actor + owner can reduce the trait look-ups per impact by more than half.
While avoiding divisions.
While there haven't been any desyncs to speak of recently (not in this part of the code, in any case), this still looks like an oversight from when we migrated away from using floats.
This also makes it easier to expose the thresholds to modders later.
Added a Damage class to pass damage value and damage(types) instead.
This removes a great amount of overhead and longterm opens possibilities to have damagetypes without warheads.