UserVault should be started before any dependent modules (see UserVault.Start()).
Initializes UserVault with the provided configuration. This function is essential for setting up the module's behavior according to your game's needs and should be called once before starting Knit.
config: table- Configuration options for UserVault.VerboseLevel: number(optional) - Controls the level of debug information output by the module. Useful for debugging and monitoring module operations.0- No debug information. Use this level for production environments to keep the logs clean.1- Logs basic events like profile loading and releasing. Good for initial testing and verification of module setup.2- Includes logs for external data modifications, helping to track unexpected changes or interactions.3- Expands logging to include data access events, aiding in debugging data flow and access patterns.4- Provides detailed logs on all function calls, useful for in-depth debugging of module operations.5- The most verbose level, logging all code paths taken within the module. Best used for troubleshooting specific issues.
DebugUseMock: boolean(optional) - Enables the use of a mock profile store in Studio, allowing for safe testing without affecting live data. Defaults to true.WarnNilUpdate: boolean(optional) - Emits warnings when callbacks inUpdateValue()returnnilvalues, helping identify unintended data erasures. Defaults to true.ProfileStoreIndex: string(optional) - Custom identifier for the profile store, overriding the default. Useful for differentiating between multiple stores or testing environments.PlayerDataUpdateFunctions: table- Contains functions for updating player data between versions. Each function should convert data from its index version to the next, ensuring smooth transitions during updates.- Functions are indexed corresponding to the version they update from (e.g., function at index 1 updates from Version 1 to 2). This allows for sequential data transformations across multiple versions.
PlayerDataTemplate: table- Defines the default data structure for new player profiles. Critical for establishing initial data states and versioning.Version: number- Indicates the template version, used to trigger data updates viaPlayerDataUpdateFunctionsfor existing profiles.Shared: tableandServer: table- Dictate the data accessible on both client and server (Shared), and server-only (Server), ensuring clear data separation and security.
UserVault.Start({
VerboseLevel = 2,
DebugUseMock = true,
WarnNilUpdate = true,
ProfileStoreIndex = "PlayerData",
PlayerDataUpdateFunctions = {
[1] = function(data) ... end, -- Example update function from Version 1 to 2
},
PlayerDataTemplate = {
Version = 1,
Shared = { Coins = 0 },
Server = { Inventory = {} },
}
})Warning
It's critical to invoke Start() before initializing other modules, such as Knit, to ensure UserVault is fully configured and operational,
preventing dependency or initialization conflicts.
This order is crucial for maintaining a stable and predictable initialization sequence for your game's services.
Important
Ensure all keys in the PlayerDataTemplate are unique across the Shared and Server categories. If there is a conflict, an error will be thrown.
Note
The default profile store key is "PlayerData"
Performs an atomic operation on one or multiple players' profiles. The callback function is passed a tuple of Vault objects, one for each player, which can
be used to access the profile data. The Vault object has two functions:
GetValue(key: string) -> any: Returns the value at the given key.SetValue(key: string, value: any): Assigns the value at the given key, and triggers an update.
Any changes made to the Vault objects are not applied to the players' profiles until the entire transaction is complete. If the transaction fails or is canceled
at any point before completion, all changes made to the Vault objects are discarded.
Beginning a transaction locks player profiles until the transaction is concluded. Any subsequent attempts to access the player's profile will yield until the blocking transaction has concluded.
Warning
All access to a player's profile will be blocked until the transaction concludes. Ensure that transaction callbacks will not yield indefinitely.
callback: (...Vault) -> ()- The callback function which performs the transaction....: Player- A vararg of Players to include in the transaction. TheVaultobjects passed to the callback be in the same respective order as the Players passed here.
Returns a Promise which resolves with any values returned from the callback function, once the transaction is complete.
UserVault.PerformTransaction(function(vault)
local coins = vault:GetValue("Coins")
local inventory = vault:GetValue("Inventory")
if coins < 100 then return end
if inventory.Sword then
inventory.Sword += 1
else
inventory.Sword = 1
end
vault:SetValue("Coins", coins - 100)
vault:SetValue("Inventory", inventory) -- Ensure table values get updated
end, player)Retrieves specified data from the player's profile.
This function supports two parameter formats:
-
GetValue(player: Player, keys: {string}): Uses an array of keys to retrieve specific player data.player: Player- The target player.keys: {string}- The data keys to retrieve.
-
GetValue(player: Player, ...: string): Uses a variable number of arguments to specify the data keys.player: Player- The target player....: string- The data keys to retrieve.
Returns a Promise that:
- Resolves with the requested player data on success. When
keysis an array, the promise resolves with a dictionary mapping each key to its value. When using varargs, the promise resolves with the values directly. - Rejects if the player profile cannot be loaded.
Retrieve player data using an array of keys "Coins" and "Level".
The promise resolves with a dictionary containing the values for these keys.
UserVault.GetValue(player, {"Coins", "Level"}):andThen(function(data)
print("Player " .. player.DisplayName .. " has " .. data.Coins .. " coins and is level " .. data.Level)
end, function()
print("Player " .. player.DisplayName .. "'s data failed to load!")
end)Retrieve player data using varargs "Coins" and "Level".
The promise resolves with the values for these keys in order.
UserVault.GetValue(player, "Coins", "Level"):andThen(function(coins, level)
print("Player " .. player.DisplayName .. " has " .. coins .. " coins and is level " .. level)
end, function()
print("Player " .. player.DisplayName .. "'s data failed to load!")
end)Tip
GetValues() is a valid alias for GetValue()
Sets a specified value for a key in the player's profile.
player: Player- The player whose profile is being modified.key: string- The key within the profile to update.value: any- The new value to assign to the key.
Returns a Promise that:
- Resolves when the value is successfully updated in the player's profile.
- Rejects if updating the player profile fails.
UserVault.SetValue(player, "Coins", 500):andThen(function()
print("Successfully updated " .. player.DisplayName .. "'s coins to 500")
end, function()
print("Failed to update " .. player.DisplayName .. "'s coins to 500!")
end)Updates a specified value for a key in the player's profile by applying a callback function. This function allows for complex transformations of existing data.
player: Player- The player whose profile is being updated.key: string- The key to be updated within the profile.callback: (value: any) -> any- A function that receives the current value and returns the updated value. This callback is used to transform the value.
Caution
When working with table values, ensure to return the modified table from the callback to avoid unintended nil assignments.
Caution
The callback function cannot yield under any circumstances, as this could create a race condition. If the callback function yields, the thread will be killed and the promise will reject.
Returns a Promise that:
- Resolves with the newly computed value after successfully updating it in the player's profile. This ensures that the calling code can immediately use the updated value.
- Rejects if the update process fails.
UserVault.UpdateValue(player, "Coins", function(coins)
return coins + 500
end):andThen(function(newCoins)
print("Successfully increased " .. player.DisplayName .. "'s coins to " .. newCoins)
end, function()
print("Failed to update " .. player.DisplayName .. "'s coins!")
end)Increments a specified value for a key in the player's profile by a specific amount. Sugar for:
UserVault.UpdateValue(player, key, function(value)
return value + increment
end)player: Player- The player whose profile is being updated.key: string- The key to be updated within the profile.increment: number- The amount to increment the value by.
Returns a Promise that:
- Resolves with the newly computed value after successfully updating it in the player's profile. This ensures that the calling code can immediately use the updated value.
- Rejects if the increment process fails.
UserVault.IncrementValue(player, "Coins", 500):andThen(function(newCoins)
print("Successfully increased " .. player.DisplayName .. "'s coins by " .. newCoins)
end, function()
print("Failed to increase " .. player.DisplayName .. "'s coins!")
end)Creates and returns a signal that is fired when a specified key's value changes in the player's profile. This operation is dependent on the successful loading of the player's profile. The signal passes the new and previous values of the observed key.
player: Player- The player whose profile changes are to be monitored.key: string- The profile key to monitor for changes.
Returns a Promise that resolves with a Signal object.
The resolved signal can then be connected to functions that will be called with the new and previous values of the key whenever it changes.
The promise is rejected if the player's profile cannot be loaded.
UserVault.GetValueChangedSignal(player, "Coins")
:andThen(function(signal)
signal:Connect(function(newValue, oldValue)
print("Player " .. player.DisplayName .. "'s coins changed from " .. oldValue .. " to " .. newValue)
end)
end)
:catch(function(error)
print("Player " .. player.DisplayName .. "'s data failed to load!")
end)Note
The Signal is only available after the player's profile has been successfully loaded.
It does not fire for the initial load of the profile's data.
For initial data handling, other methods like BindToValue() should be considered.
Invokes a callback function with the current value of a specified key immediately upon binding, and then again each time that key's value updates in the player's profile.
player: Player- The player whose data is being monitored.key: string- The key within the player's profile to watch for changes.callback: (newValue: any, oldValue: any?) -> ()- A callback function that is executed with the new value of the key and, for updates after the initial call, the previous value. For the initial invocation,oldValuewill not be provided.
Returns a Promise that:
- Resolves once the callback has been successfully registered and invoked with the current value of the key.
- Rejects if the player's profile cannot be loaded or the key does not exist.
-- Bind to monitor and reflect changes in 'Coins' within the player's leaderstats.
UserVault.BindToValue(player, "Coins", function(newValue, oldValue)
if oldValue then
print("Coins updated from " .. oldValue .. " to " .. newValue)
else
print("Initial coin value: " .. newValue)
end
player.leaderstats.Coins.Value = newValue
end)Note
The immediate invocation of the callback provides an opportunity to initialize any dependent data or UI elements with the current value of the specified key. Subsequent invocations facilitate real-time updates, enabling dynamic content adjustments based on the player's data changes.
Prepares a player's profile for teleportation by ensuring it is properly released and ready to be loaded in a new game instance. OnHopClear utilizes
Profile:ListenToHopReady()
from the ProfileService module to monitor and manage the profile's readiness for a hop. This function returns a promise that
resolves once the profile is adequately prepared, optimizing the teleportation process, especially useful when navigating noticeable delays in profile
loading after universe teleports.
player: Player- The player whose profile is to be prepared for a hop.
Returns a Promise that:
- Resolves when the player's profile has been successfully released and is ready for loading in a new game instance, facilitating seamless teleportation.
- Rejects if the player leaves the game before the promise resolves. It is recommended to account for this scenario in your implementation to handle potential errors gracefully.
UserVault.OnHopClear(player)
:andThen(function()
TeleportService:Teleport(placeId, {player})
end, function()
print("Player left before the profile could be cleared for hop.")
end)Tip
OnHopClear is particularly beneficial for managing profile readiness in scenarios with noticeable delays during teleportation between universe places.
The promise returned by this function not only signifies that the player's profile is ready for a new game instance but also provides a mechanism to
handle cases where a player may leave the game before teleportation can occur. Implementing error handling for promise rejection is crucial for
maintaining a robust teleportation process.
Provides an option to release a player's profile with a parameter that can prevent the player from being automatically kicked from the game. This is useful for scenarios like teleportation, where the player needs to remain in the game until the teleportation process begins.
player: Player- The player whose profile needs to be released.dontKick: boolean?(optional) - If true, the player is not automatically kicked from the game when their profile is released. Useful for managing teleportation without interrupting the player's session.
-- Wait for the profile to be ready for a hop
UserVault.OnHopClear(player)
:andThen(function()
TeleportService:TeleportAsync(placeId, {player})
end)
:catch(function(e)
print("Something went wrong when teleporting")
end)
-- Release the player's profile without kicking them, in anticipation of teleportation
UserVault.ReleaseProfile(player, true)Using Promise:timeout()
-- Wait for the profile to be ready for a hop, with a timeout to handle edge cases
UserVault.OnHopClear(player):timeout(5) -- Timeout after 5 seconds
:andThen(function()
-- Proceed with teleportation upon successful readiness confirmation
TeleportService:TeleportAsync(placeId, {player})
end)
:catch(function(e)
-- Handle timeout or other errors
if Promise.Error.isKind(e, Promise.Error.Kind.TimedOut) then
print("Timeout occurred while waiting for " .. player.DisplayName .. "'s profile to be ready for hop")
else
print("An error occurred while preparing " .. player.DisplayName .. " for teleportation: " .. e)
end
-- Fallback logic for errors, such as kicking or retrying the teleportation process
if player.Parent then
player:Kick()
end
end)
-- Once the teleportation is set up, release the player's profile without kicking them
UserVault.ReleaseProfile(player, true)Tip
Utilizing dontKick with true is essential for teleportation scenarios, ensuring players aren't forcibly exited from the game after their profile
release. To handle edge cases, such as players not leaving after a certain period or teleportation failing, it's advisable to use Promise:timeout()
with this process. This approach allows for the implementation of a fallback mechanism, ensuring that if the player does not leave the game within a
specified timeout period, the game can take appropriate action, such as forcibly removing the player or logging an error for further investigation.
Deletes all data stored in a player's profile.
userId: number- The user ID of the target player.profileStoreIndex: string(optional) - If provided, overrides the default profile store index. Only needed if using a profile store index other than the default.
Returns a boolean indicating if the profile was wiped successfully.
UserVault.ResetProfile(123456789)Important
ResetProfile can only be called from Roblox Studio. This is to prevent accidental data deletion.
Caution
Resetting a profile is permanent and cannot be undone.
Returns a promise which resolves when the player's data is ready.
player: Player- The target player.
Returns a Promise that:
- Resolves upon successfully loading the player profile.
- Rejects if the player profile cannot be loaded.
