The way to save any data related to a specific player, entity or even ItemStack is definitely capabilities.
First you have to create an interface that will contain all methods that you need for the functioning of your mechanics, but usually, they are just getters/setters for your variables. Then you need another class that implements this interface. Here are the variables declared and modified. Another class you need implements ICapabilitySerializable and it converts the capability to NBT and vice versa, well so does actually also another class that implements IStorage<IExtendedPlayer>. Last class you need is an event handler, where you subscribe for AttachCapabilitiesEvent<Entity> event, check for EntityPlayer and using event.addCapability(ResourceLocation, ICapabilityProvider) you attach the capability to the player.
The way to save any data related to a specific player, entity or even ItemStack is definitely capabilities.
First you have to create an interface that will contain all methods that you need for the functioning of your mechanics, but usually, they are just getters/setters for your variables. Then you need another class that implements this interface. Here are the variables declared and modified. Another class you need implements ICapabilitySerializable and it converts the capability to NBT and vice versa, well so does actually also another class that implements IStorage<IExtendedPlayer>. Last class you need is an event handler, where you subscribe for AttachCapabilitiesEvent<Entity> event, check for EntityPlayer and using event.addCapability(ResourceLocation, ICapabilityProvider) you attach the capability to the player.