Dynmap-Forge/Fabric

Dynmap-Forge/Fabric

888k Downloads

Unwanted chunks rendered outside defined limits with limit visibility enabled

gmfamily opened this issue · 13 comments

commented

template is bold
sample data is italicized

Issue Description: *Some unwanted chunks are rendered outside defined limits with limit visibility enabled. The unwanted chunk are located only around two visible limits defined near to x=20000 z=-20000. We have *

  • Dynmap Version: 3.4
  • Server Version: paper 1.19 build 81
  • Pastebin of Configuration.txt: https://pastebin.com/8drbHTJa
  • Server Host (if applicable): MineStrator
  • Pastebin of crashlogs or other relevant logs: https://pastebin.com/crashcausedbydynmap
  • Other Relevant Data/Screenshots: No specific texture pack / Plugins (29): ArmorStandTools, AsyncWorldEdit, AsyncWorldEditBossBar, Chunky, CoreProtect, dynmap, Essentials, EssentialsAntiBuild, EssentialsDiscord, EssentialsProtect, EssentialsSpawn, HeadDatabase, HolographicDisplays, LuckPerms, MessageAnnouncer, Multiverse-Core, NoMobGriefing, PlaceholderAPI, ProtocolLib, Skript, spark, SurvivalInvisiframes, TerredesHorizons, Vault, VaultChatFormatter, WorldEdit, WorldEditSelectionVisualizer, WorldGuard, WorldGuardExtraFlags / Current worlds.txt file : https://pastebin.com/4UAU0UiT / Current dmap worldgetlimits world results : https://pastebin.com/AJE0dwA4 / Online dynmap scoped on problematic limits rendered with unwanted chunks : http://137.74.100.108:25575/?worldname=world&mapname=flat&zoom=1&x=19976&y=64&z=-19994
  • Steps to Replicate: dynmap cancelrender world ; dynmap purgeworld world ; dynmap fullrender world -> this sequence repeated 2 times produced exactly the same result with unwanted chunks rendered outside defined limits.

[X ] I have looked at all other issues and this is not a duplicate
[X ] I have been able to replicate this

commented

you have a lot of areas defined, maybe some are overlapping, you can check by visualising the areas with circlemarkers: dmarker addcircle "label" radius:150 world:world x:-801 y:64 z:975 for example. dynmap sets the areas defined last as the most important ones, so whatever is on top is how it is getting rendered.

commented

Thank you for your feedback, I'll try to reproduce keeping only suspicious limits.

commented

I think I got the trick!
In the method doIntersectChunk of the class RoundVisibilityLimit there is a formula computing the distance between a block and the center of a limit to be compared with the radius. The part of the formula computing the distance is executed in ‘int’ context.
Indeed, taking our own defined limites, the « unwanted rendered blocks » are all at more than 46341 blocks (in our case it is on the z axis) of the center of the limit defined at the opposite of the map.
Then the distance computing formula exceed the capacity of ‘int’ representation (square root of 2^31 = 46 340,95).

commented

Ok, so I followed a strict methodolody adding / removing limits and checking when the rendering problem occurs.
The conclusion is indeed very simple : as soon as I add the following visibility limits I reproduce the problem, with or without all the others and/or with or without hiddenlimits :

visibilitylimits:
-   x: 19939
    z: -20043
    r: 150
-   x: 19783
    z: -19932
    r: 150
-   x: 13167
    z: 29432
    r: 150

Another curiousity is that the "unwanted rendering" seems to stop near a circular frontier centered on x=0/z=0 and ~30000 block radius (I need further analysis to confirm that fact). This can be observed a these coordinates: http://137.74.100.108:25575/?worldname=world&mapname=flat&zoom=0&x=12280&y=64&z=27484

In conclusion:

  • The problem is reproductible, not related to number of visibility limits behing defined and hidden limits have also no impact.
  • The problem occurs only when some visibility limits are defined outside a certain "frontier".
commented

I have recompiled locally the spigot (1.19-R0.1-SNAPSHOT) artefact with the following code (casting to long all return formula operands) and the problem seems to be solved. I will test further to ensure there is no significative impact on performance before suggesting a merge request.

@Override
public boolean doIntersectChunk(int chunk_x, int chunk_z) {
    int chunk_center_x = chunk_x * 16 + 8;
    int chunk_center_z = chunk_z * 16 + 8;
    int chunk_corner_x, chunk_corner_z;
    if (chunk_center_x >= x_center)
        chunk_corner_x = chunk_x * 16;
    else
        chunk_corner_x = chunk_x * 16 + 15;

    if (chunk_center_z >= z_center)
        chunk_corner_z = chunk_z * 16;
    else
        chunk_corner_z = chunk_z * 16 + 15;

    return (long)(chunk_corner_x - x_center) * (long)(chunk_corner_x - x_center) + (long)(chunk_corner_z - z_center) * (long)(chunk_corner_z - z_center) < (long)(radius * radius);
}
commented

The fixed version has been deployed on our server with no regression on runtime with several players connected (fullrender still running). I'll propose pull request asap.

commented

Thanks for investigating! code looks good from what I can see, you can create a pr on the github to address this issue.

commented

how is the PR going? I don't see a repo on your github account, do you need help with creating the PR?

commented

It is ok. I was focused on another subjects at work. Please review the PR below 😊

commented

Is there any problem with the PR ? I'm not very familiar with github delivery process...

commented

Mike is very busy, PRs take weeks to merge. This one looks good, so all that's needed now is patience :)

commented

No problem... I was only wondering if I made something wrong...

commented

just tested, works wonders, thanks for catching this issue! if you have any other issues about dynmap that are not already stated please feel free to open a new issue.