satoshinm / WebSandboxMC

Bukkit plugin providing a web-based interface with an interactive WebGL 3D preview or glimpse of your server 🕷⏳📦 ⛺
https://www.spigotmc.org/resources/websandboxmc.39415/
MIT License
19 stars 5 forks source link

Compact chunks #86

Closed satoshinm closed 7 years ago

satoshinm commented 7 years ago

For https://github.com/satoshinm/NetCraft/issues/136

satoshinm commented 7 years ago

ThinkMap has two methods to get chunk data, getChunkBytes() first tries to fetch a ChunkSnapshot using the Bukkit API, if null then getChunkData() reads and parses the actual chunk file on disk! Since it is a world map, this may not be too unreasonable. But for this kind of plugin, where web players would necessarily be in the chunks they visit, and to avoid interdependence on non-Bukkit API, may want to only use the first approach. The blocks need to translated, packed, compressed, then possibly encoded for sending over the wire in Craft's protocol.

satoshinm commented 7 years ago

https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/ChunkSnapshot.html only has useful deprecated methods? This is the entirety of the interface:

public interface ChunkSnapshot {
    int getX();

    int getZ();

    String getWorldName();

    /** @deprecated */
    @Deprecated
    int getBlockTypeId(int var1, int var2, int var3);

    /** @deprecated */
    @Deprecated
    int getBlockData(int var1, int var2, int var3);

    int getBlockSkyLight(int var1, int var2, int var3);

    int getBlockEmittedLight(int var1, int var2, int var3);

    int getHighestBlockYAt(int var1, int var2);

    Biome getBiome(int var1, int var2);

    double getRawBiomeTemperature(int var1, int var2);

    double getRawBiomeRainfall(int var1, int var2);

    long getCaptureFullTime();

    boolean isSectionEmpty(int var1);
}

ChunkSnapshot may not be needed or useful. Iterate over a cube of World and translate BlockStates into a ByteBuf array then gzip it?

satoshinm commented 7 years ago

Asked at https://www.spigotmc.org/threads/is-it-possible-to-use-chunksnapshot-to-get-blocks-without-deprecated-api.244795/

satoshinm commented 7 years ago

Testing block order on a test world versus compression size, to determine compression efficiency (radius=+/-16, so (216)(216)(216)2=65536 bytes, short):

axis order (outer to inner) deflated size code
y, z, x 3163 bytes Block block = world.getBlockAt(k + x_center, j + y_center, i + z_center);
z, y, x 3163 bytes Block block = world.getBlockAt(k + x_center, j + y_center, i + z_center);
x, y, z 3022 bytes Block block = world.getBlockAt(i + x_center, j + y_center, k + z_center);
x, z, y 2871 bytes Block block = world.getBlockAt(k + x_center, i + y_center, j + z_center);
y, x, z 2947 bytes Block block = world.getBlockAt(j + x_center, k + y_center, i + z_center);
z, x, y 2790 bytes Block block = world.getBlockAt(j + x_center, i + y_center, k + z_center);

z, x, y (or from inner to outer: y, x, z) is the winner - this makes sense given runs of air. Flipped on side:

screenshot-netcraft-2017-06-03t22_28_17 508z