stackotter / delta-client

An open source Minecraft Java Edition client built for speed.
https://deltaclient.app
GNU General Public License v3.0
328 stars 32 forks source link

Improve block model loading speed #7

Closed stackotter closed 2 years ago

stackotter commented 3 years ago

The slowest step in resource pack loading is block model loading. The block model loading process is quite complicated and has many intermediate steps. This is because lots of data is pre-calculated at block model loading time so that it only needs to be calculated once. Once block models are cached on the first launch, subsequent launches are much faster. However, this issue is only about the initial block model loading speed.

Block model loading speed is important because it is quite a significant step in the first launch and also, optimising it may even result in nicer code in the end! (the current implementation is pretty messy).

How block model loading currently works

  1. Block model json files are loaded as JSONBlockModels using Swift's Codable feature.
  2. They are then flattened into an intermediate representation (IntermediateBlockModelPalette). The JSON models can reference parents and are mostly incomplete because they rely on data from parent models. Flattening them vastly simplifies processing of them.
  3. The intermediate representations are finally converted into a BlockModelPalette.

Here's some more information about the json format of block models in resource packs. The protobuf message definitions for block model caching are in the Cache directory.

Edit

I have optimised the code for loading the JSON (not processing it) and I found a library called ZippyJSON. It is about 3x faster than the built in JSONDecoder and it implements the same API so it could just be swapped in easily. I also found that reading the files in and combining them into one large json object to decode all at once was the best approach. The biggest bottleneck for JSONBlockModel.loadModels is now reading the files in (which takes about 500ms total on my laptop).

Side note: I implemented JSONBlockModel.loadModels in Rust (while learning Rust) and it is 10x faster (0.06 seconds vs 0.6 seconds).

stackotter commented 3 years ago

18 will make caching much much nicer, so maybe hold off on this one until that's completed.

stackotter commented 2 years ago

I'm closing this, it is at a completely acceptable speed for now.