Skip to content

Additional chunk data with SRF 13#161

Merged
davidmayr merged 11 commits intodevelopfrom
dev/additional-chunk-data-srf-13
Jun 7, 2025
Merged

Additional chunk data with SRF 13#161
davidmayr merged 11 commits intodevelopfrom
dev/additional-chunk-data-srf-13

Conversation

@davidmayr
Copy link
Member

@davidmayr davidmayr commented Apr 21, 2025

This PR implements SRF 13 which adds a bitmask to specify flags for additional world data. The current additional world data consists of block and fluid ticks (closes #5) and poi chunk data. The format was also designed with future proofing in mind, in case we want to add new additional world data in the future.

To implement the POI chunk data, a moonrise data loader was implemented. And to make POI loading consistent with entity loading, the entity loader has been converted to a moonrise data loader as well. This also has the advantage of less disk io (it is async, but it would have still consumed resources) and less patching required. Chunk loading and world saving is still implemented via the traditional slime world conversion and serialization APIs.

This also fixes another bug (by modifying forceNoSave in the PaperHooks) where moonrise saving was accidentally triggered sometimes and saved to the temporary directory.

TODO

  • Test for performance regressions
  • Testing in general
  • Document new API

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
…rovements

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
…low for future additions to the format

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
@davidmayr davidmayr requested a review from Copilot April 21, 2025 17:54
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements SRF 13 to support additional chunk data by introducing a new bitmask for POI chunks and tick data (block and fluid ticks) while preparing the format for future extensions. Key changes include:

  • Updating serialization and deserialization logic (in SlimeSerializer, SlimeChunkConverter, etc.) to write and read additional world data.
  • Introducing new moonrise data loaders for POI and entity data to reduce disk IO and improve consistency.
  • Upgrading API definitions and properties (including updating SLIME_VERSION and adding new SlimeProperties) to support the additional data.

Reviewed Changes

Copilot reviewed 27 out of 32 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/SlimeWorldReaderRegistry.java Registers the new v13 world format for SRF 13 support.
core/src/main/java/com/infernalsuite/asp/serialization/slime/SlimeSerializer.java Implements serialization of additional world data based on new properties.
core/src/main/java/com/infernalsuite/asp/serialization/anvil/AnvilWorldReader.java Updates chunk reading to include new data fields (POI, block ticks, fluid ticks) with a TODO for further conversion.
core/src/main/java/com/infernalsuite/asp/SlimeLogger.java Adds a warn method to the logger.
aspaper-server/src/main/java/com/infernalsuite/asp/level/moonrise/SlimePoiDataLoader.java Introduces a new POI data loader for moonrise with custom save behavior.
aspaper-server/src/main/java/com/infernalsuite/asp/level/moonrise/SlimeEntityDataLoader.java Introduces a new entity data loader for moonrise to align with the POI loader and reduce disk IO.
aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeLevelInstance.java Updates unloading and initializes new data controllers for POI and entity data.
aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeInMemoryWorld.java Adjusts in-memory chunk unloading and serialization to capture additional world data.
aspaper-server/src/main/java/com/infernalsuite/asp/level/SlimeChunkConverter.java Adds conversion utilities for block and fluid ticks and methods to work with POI chunk data.
aspaper-server/src/main/java/com/infernalsuite/asp/level/SafeNmsChunkWrapper.java Provides new accessor methods for additional data (ticks and POI sections).
aspaper-server/src/main/java/com/infernalsuite/asp/level/NMSSlimeChunk.java Updates getters to supply additional tick and POI data.
aspaper-server/src/main/java/com/infernalsuite/asp/SimpleDataFixerConverter.java Modifies data fixer conversion to include additional chunk data.
api/src/main/java/com/infernalsuite/asp/api/world/properties/SlimeProperties.java Adds new properties (SAVE_POI, SAVE_BLOCK_TICKS, SAVE_FLUID_TICKS) for controlling additional data saving.
api/src/main/java/com/infernalsuite/asp/api/world/SlimeChunk.java Extends the interface to expose new methods for tick and POI data retrieval.
api/src/main/java/com/infernalsuite/asp/api/utils/SlimeFormat.java Upgrades the SLIME version to 13 to signal the new format changes.
Files not reviewed (5)
  • SLIME_FORMAT: Language not supported
  • aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch: Language not supported
  • aspaper-server/minecraft-patches/sources/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java.patch: Language not supported
  • aspaper-server/minecraft-patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch: Language not supported
  • build-data/aspaper.at: Language not supported

Comment on lines +335 to 336
.map(x -> new SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMaps, tileEntities, entities, extraTag, null, null, null, null)) //TODO: Convert poi, block and fluid
.orElse(null);
Copy link

Copilot AI Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TODO comment indicates that the conversion logic for POI, block ticks, and fluid ticks has not been implemented yet. It is recommended to add the appropriate conversion logic and corresponding tests to ensure proper functionality.

Suggested change
.map(x -> new SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMaps, tileEntities, entities, extraTag, null, null, null, null)) //TODO: Convert poi, block and fluid
.orElse(null);
.map(x -> {
List<CompoundBinaryTag> poi = compound.getList("poi", BinaryTagTypes.COMPOUND).stream().map(t -> (CompoundBinaryTag) t).toList();
List<CompoundBinaryTag> blockTicks = compound.getList("block_ticks", BinaryTagTypes.COMPOUND).stream().map(t -> (CompoundBinaryTag) t).toList();
List<CompoundBinaryTag> fluidTicks = compound.getList("fluid_ticks", BinaryTagTypes.COMPOUND).stream().map(t -> (CompoundBinaryTag) t).toList();
return new SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMaps, tileEntities, entities, extraTag, poi, blockTicks, fluidTicks, null);
})

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidmayr what about this?

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
@GliczDev
Copy link
Contributor

GliczDev commented Apr 21, 2025

since PoiChunk, block ticks and fluid ticks are all optional compound tags, wouldn't it be better to simply store them in extra tag (like upgrade data)?

tbh SRF 13 feels like style over substance - storing optional data in extra tag (just like upgrade data) wouldn't require format change and would be much, much easier (and, I suppose, storing it in extra tag would take even less bytes?)

@davidmayr
Copy link
Member Author

davidmayr commented Apr 21, 2025

since PoiChunk, block ticks and fluid ticks are all optional compound tags, wouldn't it be better to simply store them in extra tag (like upgrade data)?

tbh SRF 13 feels like style over substance - storing optional data in extra tag (just like upgrade data) wouldn't require format change and would be much, much easier (and, I suppose, storing it in extra tag would take even less bytes?)

Thanks for your input on this. I was actually thinking the same things you did when I began working on this, but then decided for the current approach. Here is why:

I'm fully against storing it in extra data, strictly because of the reason that the extra data is user modifiable (Who knows what undefined behavior might happen if someone accidentally saves a tag with that name in extra data. And I guess block_ticks or POI is not that rare to save in the extra data? I named things similarly on my projects.). I'm already not a huge fan of the PDC being in the extra data, but I guess that makes sort of sense.

However, I was indeed thinking about storing the data in one large compound, and I was talking this through with @kyngs (one of the people (or the person, not sure) that designed the v12 format) and we both decided for storing this data on a separate tag for each property and make it disableable with a flag(like it is now). This is just how the format and API has always been designed. Block Data, Biome Data, Heightmaps, Entities, TileEntities. They each have their own serialized part in the format. So doing this differently for additional data just feels hacked and patched together.

Theoretically, we could save the whole chunk data in one NBT tag. Minecraft does this too, it's no problem. But this is just not how slime was designed by the people that primarily maintained this before I did. I didn't want to make too many changes to the preexisting format, and saving everything inside of one large nbt tag is sometimes actually slightly larger than saving it in separate tags.

I wanted to make sure this feels like a properly integrated feature and not like a patched together mess to quickly get block ticks running.

However, what I am definitely open about is merging block and fluid ticks into a single compound tag. Simply because they are lists and therefor need to be wrapped inside a compound tag anyway. Also, Minecraft serializes them as one thing anyway and I just split it out again

Since this is still a draft PR, I'm open to hear your voice on this and make major changes if necessary @GliczDev. However, I'm pretty happy with the way this turned out right now. I'll still need to do javadoc and importing of POI & ticks on anvil world import.

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
# Conflicts:
#	core/src/main/java/com/infernalsuite/asp/serialization/slime/reader/impl/v10/v10SlimeWorldDeSerializer.java
#	gradle.properties
Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
@davidmayr davidmayr marked this pull request as ready for review June 4, 2025 23:24
@davidmayr davidmayr requested a review from AverageGithub June 4, 2025 23:25
@davidmayr
Copy link
Member Author

Tests concluded:

  • No noticeable regression in world size with default configs
  • No noticeable regression in server memory usage
  • No change in serialization/deserialization/load speed

Copy link
Member

@kyngs kyngs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this looks solid—nice work!
Please take a look at the comment from copilot; I think it could still be relevant.

One potential concern here is around backward compatibility when using SlimeProperties to specify which additional data should be saved. If new types of world data are added, a plugin might not be aware of what additional data the server actually supports. If it tries to save a world using a SlimeProperty that exists in a newer version of the API but not on the server itself, this could result in an error due to the missing field.

Comment on lines +335 to 336
.map(x -> new SlimeChunkSkeleton(chunkX, chunkZ, sectionArray, heightMaps, tileEntities, entities, extraTag, null, null, null, null)) //TODO: Convert poi, block and fluid
.orElse(null);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidmayr what about this?

@davidmayr
Copy link
Member Author

davidmayr commented Jun 5, 2025

Overall, this looks solid—nice work! Please take a look at the comment from copilot; I think it could still be relevant.

That's just for importing vanilla worlds. Would be a nice to have (that's why there is the TODO), but I'm not sure if I want to invest time in that right now (Although it shouldn't be too hard). I just don't want to do the testing, but I can implement it if you want

One potential concern here is around backward compatibility when using SlimeProperties to specify which additional data should be saved. If new types of world data are added, a plugin might not be aware of what additional data the server actually supports. If it tries to save a world using a SlimeProperty that exists in a newer version of the API but not on the server itself, this could result in an error due to the missing field.

But how should we solve that? Every type of constant or enum would have the same effect. Only maybe a string constant could fix that (since the compiler writes string constants directly) but I feel like that's not a nice solution either.

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
@davidmayr davidmayr merged commit 490c9ad into develop Jun 7, 2025
1 check passed
@davidmayr davidmayr mentioned this pull request Jun 30, 2025
davidmayr added a commit that referenced this pull request Jun 30, 2025
* fix: empty compound tags causing null pointers when e.g. heightmaps are missing

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* chore: update paper

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* Additional chunk data with SRF 13 (#161)

* feat: begin working on srf 13

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: moonrise implementation for entity and poi loading, further improvements

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: dont put the wrong DataVersion in the tag when data fixing

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: document format, swap poi chunks around to match read order, allow for future additions to the format

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* chore: javadoc

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* chore: remove some useless things

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: section flags for sky and block light

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: the thing I just fixed for the other formats for SRF 13

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: potential entity save errors

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: entities not saving in vanilla worlds on autosave

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

---------

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* 1.21.6 (#165)

* fix: make asp compile with file patches only on 1.21.5

Signed-off-by: David <davidliebtkekse@gmail.com>

* fix: npe on null cache

Signed-off-by: David <davidliebtkekse@gmail.com>

* fix: paper server feature patches

Signed-off-by: David <davidliebtkekse@gmail.com>

* feat: port all patches

Signed-off-by: David <davidliebtkekse@gmail.com>

* chore: add big fat temporary warning and fail if someone loads an old world

Signed-off-by: David <davidliebtkekse@gmail.com>

* chore: clarify on why saveIncrementally is commented out

Signed-off-by: David <davidliebtkekse@gmail.com>

* feat: incremental saving is back in paper

Signed-off-by: David <davidliebtkekse@gmail.com>

* feat: update to newest 1.21.5 commit

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: initial 1.21.6-pre3 work

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: compilation issues on ASP side

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: update to newest paper

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: compilation problems --nobuild

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: lists with multiple types in conversion

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: full 1.21.6 release

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: update paper

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: temporarily downgrade adventure

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: update to newest paper

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

---------

Signed-off-by: David <davidliebtkekse@gmail.com>
Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: allow changing sea level using a slime property and change default to vanilla world sea level (Closes #166)

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: change the default back to what it was before to avoid breaking changes, allow sea level modification in plugin config

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: properties being accessed before they are ready

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: use bstats server metrics

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* fix: allow animals was not applied

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: allow to specify biome and environment on world creation as these variables are difficult to change later

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* Constructor with custom HikariDataSource for mysql-loader (#167)

* feat(mysql-loader): add constructor that accepts HikariDataSource

* feat(mysql-loader): add ApiStatus.Experimental to constructor

* feat: update to upstream paper 57c202e01516b653aea9c7e050eaded1448863e5

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

feat: update to upstream paper 57c202e01516b653aea9c7e050eaded1448863e5

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* chore: update adventure

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* feat: 1.21.7 update

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

* chore: change api version to release --nobuild

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>

---------

Signed-off-by: David Mayr <davidliebtkekse@gmail.com>
Signed-off-by: David <davidliebtkekse@gmail.com>
Co-authored-by: Edoardo Mannino <64657892+HighVirus@users.noreply.github.com>
@davidmayr davidmayr deleted the dev/additional-chunk-data-srf-13 branch September 18, 2025 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants