There is an easy fix you can do - which applies to many other things. You can create an interface to your RPG stats, which you can then define to use RemoteFunctions or Events.
For example, you can create a Module which incorporates the following functions. Notice, that this small “documentation” allows you to incorporate a LOT of versions on how this actually should PERFORM this function! The cool part of this is that the “user” (the developers who use your API) can rely on this documentation, while you provide the actual code that performs the operations. I include function names, arguments and possible implementations.
Also, notice that, due to you (should) tunnel all operations through several functions, you can easily add features as logging, GUI notifications, etc. This is a very powerful way to code things, and also a very scaleable way, due to the fact you can change ONE function to change the complete operation of your script.
Skills:GetSkillLevel(string Name)
This function returns the level of a Skill with identifier Name. Returns the value if exists, else returns nil.
Skills:GetSkillXP(string Name)
This funtion returns the XP of a Skill with identifier Name. Returns the value if exists, else returns nil.
Notice that, in general, above functions should use the same “way” to get a value of either XP or level. I can imagine two implementations of this. You can either use the current .Value system, but this allows non-filtered games to easily change these values. The .Value version would lookup the value of the Name skill into some container.
The other implementation would be to use RemoteFunctions, where you store the ACTUAL skill values inside a table on the server. Notice that now, it is not (directly) possible on non-filtered games to change the value of the skills, as it does not physically exist on both server and client. To change the value, you need to ask the server to change this. This adds one layer to complexity. However, still if players really want to, they can easily crack this system. To fix this, you can add a layer of security where updates can only be called like - maximal - 60 times per minute, where the maximal XP upgrade is a certain value. This can still be cracked, but “hackers” cannot IMMEDIATELY get extremely high amounts of XP.
So,
Skill:GetSkill(string Name, string Type)
Gets the value of the skill with identifier Name, of type Type. Currently, the only valid Type values are “Level” and “XP”. Implementations are as described above; either using a Value system (not secure on non-filtered games) or using Remotes, where the values are stored ONLY on the server.
Skill:IncreaseSkill(string Name, double Value)
Increase the skill XP with a value Value, identified by Name.
On the server side, you need to define above functions too, returning the actual values. IncreaseSkill could use a RemoteEvent, as it is not necessary to return a value. However, you can also use a RemoteFunction, where you could return a boolean which indicates a succes or not, and the new value of the skill. If this value is false, it could mean that your security does not allow the change of such (huge?) increases.
That should create a baseline with a very handy interface to skills. Later versions could also add - for example - events, which you can connect to if a Level is updated, or a Skill is updated.
Hope this helped you. Feel free to ask any questions.