Storing variables to a player

I can’t seem to get a clear answer for this one after wandering the forums. How do I store a variable or string to a player/entity?

Java is not a dynamic language, so objects once defined do not usually change their shape and have extra fields/methods attached.

However, SpongeAPI offers a solution, which is the custom DataAPI , the downside is that it’s currently pretty complex to implement and can discourage people from using it.

The brightside though is once you have implemented Data correctly it is persisted across server restarts and saved with the NBT data that makes up the player/entity.

There is an open docs Pull Request that is working on explaining Data in API 5 https://github.com/SpongePowered/SpongeDocs/pull/532
However it’s not for the faint of heart.

2 Likes

It’s worth mentioning that, eventually, this will fix all our problems and make everything perfectly easy (at least, where custom data is concerned) (and yes, I may be exaggerating a bit, but it will be much easier than implementing data as it is now).

3 Likes

I was thinking more like attaching a variable to a UUID. So it’s not attached to the player/entity but to the ID. I thought it would involve the use of a table of some sort. for example:

pData[UUID]["Kills"] = 5;
pData[UUID]["Deaths"] = 10;
and so on...

That sounds more like storing it to database instead of storing that information onto the Player itself. The difference is that of course, a database can ben globally affecting for multiple server instances, whereas a Player object can only keep the same data on the same server instance.

1 Like

Honestly, I don’t see why we have to store information directly on a player/entity if we can store them to their ID script side (if they have one). It’s just as good as attaching it to them directly (unless it’s not possible in java). I’m a little new to the OOP concept so please forgive me if I’m wrong about something. :confounded:

What do you mean by multiple server instances? Like multiple servers using the same plugin?

You can’t store it on the ID either, however interpreting your syntax used, what you are describing is a Map(Associative array - Wikipedia) or a Table .

The problem is more how to save the information, and whether you need to be able to index offline players.

What Gabizou was referring to a literal database of some kind. Database - Wikipedia / Relational database - Wikipedia

You may have heard of some such as MySQL sqlLite H2

The problem isn’t object orientated programming, it’s static vs dynamic languages.

As for server instances, what I believe gab was referring to was the ability of databases to act atomically, concurrently, persist between server restarts, and be shared.

The DataAPI generally ends up storing data on the player and serializing(saving) it out onto the player.dats that also contain the players inventory.

A Database would store this data externally to both the player.dat and the entire server, allowing for it to be shared to say, a web interface, a phone app, or a whole network of minecraft servers.

Now, as for options inside the base game of Minecraft, if you only need it to work over 1 server, (noticing that you are saving kills / deaths) you could save this data inside a scoreboard objective, this would also give the server admins the ability to modify or increase / decrease the numbers.

If you don’t need it to persist/save you could also store this as a field / variable on your class, but it would reset everytime the server shutdowns unless you saved it manually (in a database/config/file etc)

1 Like

My plan was to save the player data on a mysql database and set it to the player later when the player joins the server. Then I save the data when the player disconnects. I don’t think I need it to save it on the player.DAT unless there’s a reason to. I rather keep the plugins data separate from minecraft’s data. (Unless it involves any other entities besides players, but that’s not a concern for me for the moment)

If I need to use the data later on a different server or through a website, I can get it through mysql. But I understand what you’re saying now. Is there any downside what I’m trying to do?

1 Like

Not really, there are possible performance concerns as well as the requirement to run an external database of some kind, but most servers are already running one anyway, or at the least using h2 or sql lite.

If you run your database IO on an async task, then you are golden.

Edit: There are a few edge cases about when to save / commit your data changes, also what the behavior of your plugin should be if the database is unavailable for some reason, which you won’t run into using the DataAPI as it will save when the entities do.

1 Like

You should be fine, and you’re taking a good approach. Orthogonality (not to say it is this per-se) is a great concept, and in this case the encapsulation of data vs runtime objects is a good idea. Mixing your data in with Minecraft’s data makes things complicated in cases where you need to port your software, and thus port your data- and in cases where Minecraft changes their data handling.

1 Like