Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-272414

Redundant calculation causes 2x lag during explosions

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • 24w33a
    • 1.20.3, 1.20.6
    • None
    • Community Consensus
    • Performance
    • Important
    • 1242517
    • Expansion B

      Snapshot 23w45a introduces a redundant set of calculations during the explode method, which leads to a significant (approximately 2x) increase in lag from explosions. This is less likely to be felt on the scale of a single explosion at a time, however it has a notably outsized affect on players who use contraptions that use many TNT or have many entities in close proximity to explosions.

      Data from in-game testing in versions 23w44a and 23w45a (shows test setup):
      https://www.desmos.com/calculator/c4ccpegwpp

       

      Background (for analysis):
      The value returned by the getSeenPercent method represents what proportion of an entity is "exposed" to an explosion, and it is a value that ranges from 0 to 1. The value is sometimes colloquially called the "exposure". The lower an entity's exposure, the less of an effect the explosion has on the entity. Exposure is used when calculating how much the explosion damages an entity, as well as how much the explosion propels the entity. The method uses an array of "raycasts" that probe the area between the entity and the explosion for blocks that may protect the entity from the explosion. These raycasts can number in the dozens per entity, and each requires a non-trivial amount of math to compute.

      Code Analysis [brackets refer to attached screenshots]:

      • Prior to 23w45a, getSeenPercent was computed only once and stored in a variable that was then used by both the entity damage and propulsion computations [1a].
      • Snapshot 23w45a introduced wind charges, which create non-damaging explosions. In order to allow some explosions to cause no health damage, a condition was added during the explode method that skips computing damage if the damageSource for the explosion is null [1b]. Therefore, explosions with damageSource == null (like those of wind charges) do not hurt entities.
      • The default Explosion constructor previously overwrote null damageSource values with a non-null value [2a], so in 23w45a the constructor was also modified to accept null damageSource [2b].
        Altogether, this means that the logic for skipping damage would work simply by wrapping the existing damage code (1 line of code; see [1a]) in the conditional statement previously mentioned.

      Despite this, as of 23w45a, the explosion's damage calculation was relocated to a different class, in a new method that takes only an Explosion object and an entity as parameters [3]. This means that to have the necessary values to compute the damage, the costly exposure computation and a handful of helper values need to be recomputed from scratch using the positions of the explosion and entity, even though all of them are already computed in the explode method  for the applied velocity calculation [see 1b again]. As a result, each explosion now has about twice the amount of work when processing how it affects entities.

            billy.sjoberg [Mojang] Billy Sjöberg
            enbyd enbyd
            Votes:
            54 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: