[Solved] Best way to save data stored for each player?

Hello, I am currently deciding on how often my data should be saved, and how to save it. The data is stored per player. I have 3 options I am considering:

  1. Saving the data to the file on action(Every time a player breaks a specific block, this will happen a lot)

  2. Storing the data in an object and saving it when the server stops(A problem may be when the server is forced to stop, such as in a power loss)

  3. Saving the data to the players using the new Data API(I think this would be the best, but I am unsure how to do this one. If anyone knows how and wouldn’t mind explaining, that would be greatly appreciated)

I am assuming you are saving to a file? If so:

  1. Probably not the best idea - you might want to store the data in an object (like 2) and have a scheduled asynchronous task run every 5 or so seconds to save it to the file, and clear the object
  2. Probably not good as you said
  3. Can’t help you there, sorry… I am also interested in how you might do this. You might want to ask here
1 Like

Does the data need to scale? Does the data potentially need to accessed by multiple servers? If so I would go with a database.

If you do not need those, I would just save to flat file such as YAML/HOCON/JSON. If the server is up for long periods of time, I would recommend a mix of periodic and event based saves.

So save periodically, and on special events you deem worthy of saving the player’s data such as a player quitting the server.

The data will only be on one server. I think I will do that, periodic saves and event saves, how often would you think that I should save?

When I figure out the new Data API I will probably switch over to storing the data to the player itself.

dim 0 world save only

The period depends on how intensive the save is, how many players you have to save, and how often you do it.

Also, avoid saving on events that are fired all the time such as any movement events, or block breaking, or chatting. Obviously you wouldn’t save on player chat logically, but my point is that if I break 5 blocks and trigger 5 saves on myself, if the saves aren’t asynchronous I’m going to lock up the server if the saves are event slightly intensive which will make the server lag to everyone.

Do you think every 5 minutes is too long? All that will happen is 2 files get saved.

I think you should stick to the world save. Why? because if the server crashes it is on the state of the last world save, therefor it doesn’t cause for confusion with the player and users. Else you have data loss without the user noticing it. When the world did a rollback I assume that other things “like your plugin” did, too.
If the configurable world save isn’t often enough, stick it to the player file. I assume that sponge will forward it directly so you don’t need to worry about hard saving it. That is also how most mods save player progression. E.g. thaumcraft.

@Slind
I don’t quite understand how I could accomplish this.

I’m sure there is a world save event.

@wingz @Zirconium
If I run a repeating task in a separate thread that saves the files, and repeat this task every 2 seconds or so, this shouldn’t cause any lag to the server, correct?

It should not lag the server, correct.

Ok thanks, that is the route that I will take.

Store the data in memory and perform IO upon init and teardown

Saving every 2s is a little over-kill. I would recommend increasing the interval.

1 Like

That said: This is exactly where Minecraft’s lagspike of death comes from. Mojang stores every 2sec by default too. I suggest raising this too.

@Tzk
I will increase it, but do you know if Minecraft saves the data in a separate thread?

Dont think so as the main thread lags when mc saves. Not absolutely sure on this however.