Save data in WorldStorage or ChunkStorage

Hi :slightly_smiling_face:

I meet some difficulties implementing persistant data.

I need to store a sorted list of blockSnapshot with other custom values.
Theses values are only “active” when the chunk is loaded.

Previously on Forge, I saved my data using ChunkDataEvent.Load#getData() and I attached a custom compound nbt tag. It worked well.

With WorlStorage.getChunkData(), the DataContainer I receive seem to be read only.
I’ve made a sample with just an Integer and It does not save it.
Maybe I’m doing something wrong …

@Listener
    public void onSaveWorldEvent(SaveWorldEvent.Pre e) {
        logger.info("Save world event : "+e.getTargetWorld().getName());
        e.getTargetWorld().getLoadedChunks().forEach(chunk -> {
            logger.info("[SAVE] Ask for chunk data "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString());
            try {
                final Optional<DataContainer> data = chunk.getWorld().getWorldStorage().getChunkData(chunk.getPosition()).get();
                if(data.isPresent()) {
                    logger.info("[SAVE] Got chunk data "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString());
                    final Optional<Integer> opt = data.get().getInt(DataQuery.of("intSampleKey"));
                    if(opt.isPresent()) {
                        logger.info("[SAVE] Got value "+opt.get()+" for chunk data "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString());
                    }else {
                        logger.info("[SAVE] Value for chunk data "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString()+" not found");
                    }
                    logger.info("[SAVE] Setting value "+(chunk.getPosition().getX()+chunk.getPosition().getZ())+" for key \"intSampleKey\" for chunk "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString());
                    data.get().set(DataQuery.of("intSampleKey"), chunk.getPosition().getX()+chunk.getPosition().getZ());
                }else {
                    logger.info("[SAVE] Chunk data for chunk "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString()+" not found");
                }
            } catch (InterruptedException | ExecutionException err) {
                logger.error("[SAVE] Unable to get chunk data "+chunk.getWorld().getName()+" - "+chunk.getPosition().toString());
                err.printStackTrace();
            }
        });
    }

First save :

[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Ask for chunk data New World- - (-60, 0, -49)
[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Got chunk data New World- - (-60, 0, -49)
[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Value for chunk data New World- - (-60, 0, -49) not found
[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Setting value -109 for key "intSampleKey" for chunk New World- - (-60, 0, -49)

After saved twice :

[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Ask for chunk data New World- - (-60, 0, -49)
[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Got chunk data New World- - (-60, 0, -49)
[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Value for chunk data New World- - (-60, 0, -49) not found
[22:08:48] [Server thread/INFO] [myspongesample]: [SAVE] Setting value -109 for key "intSampleKey" for chunk New World- - (-60, 0, -49)

Is it possible to write in WorldStorage using Sponge ? Or should I use Forge for this part ?
If I use external database, what about performance issues ?
My modification is visible server side only, so client don’t do any stuff with theses added values.
Using Forge is a constraints for users. I want to keep vanilla user acceptance.

If I use an external DB, I will probably use MongoDB, I there a recommanded support from Sponge ? I see in documentation that’s not currently supported. Do you accept PR about it or can I have visibily about a release date of it support ?

PS : I have an additionnal question, I’ve registered a listener for UnloadChunkEvent and when a “save & quit” my game, the world is unloaded but the UnloadChunkEvent is never called. Is it expected behavior ?

Tanks a lot for your help

I finally use a LevelDB database using JNI implementation instead of MongoDB. It works pretty good :slight_smile:

However, I’m still in trouble concerning my PS question :
“save & quit” my game, the world is unloaded but the UnloadChunkEvent is never called. Is it expected behavior ?