VirtualStore - A Modern Data Framework

Hey everyone,

I’ve been working on a Roblox data framework called VirtualStore for a while now, and the first public release is now available.

I originally started making it because I wanted a player data system that was simple to use for normal cases, but wouldn’t completely fall apart once the game started needing more serious data handling.

Some of the problems I wanted it to handle were things like:

  • DataStore being temporarily unavailable when a player joins
  • Two servers trying to open the same profile
  • A player leaving before receiving an important reward
  • Replicating things like Coins or Inventory without exposing the entire profile
  • Finding operations that keep failing and being able to inspect or repair them later

Discord Server
Documentation
GitHub
Release v0.1.0


Basic Player Data

For a simple game, you can create one shared data module like this:

local ServerScriptService = game:GetService("ServerScriptService")
local VirtualStore = require(ServerScriptService.VirtualStore)

local Data = VirtualStore.players({
	Name = "PlayerData",

	Template = {
		Coins = 0,
		Inventory = {},
	},

	Public = {
		"Coins",
		"Inventory",
	},
})

return Data

Then other server scripts can use it pretty directly:

local Data = require(ServerScriptService.DataService)

local _, loadError = Data:Wait(player, 5)

if loadError then
	warn(loadError.Code, loadError.Message)
	return
end

Data:Add(player, "Coins", 100)
Data:Insert(player, "Inventory", "Sword")

The player-data module handles loading, autosaving, retrying temporary failures, releasing data when the player leaves, and client replication.

Transactions

Transactions

For actions that need to change multiple values at once, you can use a transaction.

For example, buying an item:

Data:Edit(player, function(profile)
	if profile.Coins < 500 then
		return VirtualStore.Cancel
	end

	profile.Coins -= 500
	table.insert(profile.Inventory, "Sword")
end)

If the transaction is cancelled or fails, the partial changes are not kept.

Durable Operations

Durable Operations

One of the main things I wanted to support was safer reward delivery.

For example, a match reward can be queued with a unique operation ID:

Data:DeliverAsync(
	player.UserId,
	`match:{matchId}:reward`,
	"GrantMatchReward",
	{
		Coins = 250,
	}
)

If the player disconnects before the reward is fully applied, the operation can stay pending in their profile and be continued later.

This is mainly meant for things like:

  • Match rewards
  • Developer products
  • Crate rewards
  • Offline rewards
  • Teleport-related rewards

Operations also track attempts, receipts, duplicate IDs, failures, and dead letters, so failed operations can be inspected instead of silently disappearing.

Client Replication

Client Replication

VirtualStore lets you choose exactly which profile paths the client is allowed to see:

Public = {
	{"Wallet", "Coins"},
	{"Progress", "Level"},
}

So publishing Wallet.Coins does not automatically expose the rest of Wallet.

The client gets a read-only replica and can listen to specific paths for UI updates.

Other Features

Other Features

VirtualStore currently includes:

  • Session leases
  • Autosaving that skips unchanged data
  • Safe path mutations
  • Transactions and local locks
  • Schema migrations
  • DataStore validation
  • OrderedDataStore leaderboards
  • Memory adapters for testing
  • Diagnostics and critical-state events
  • Server-only inspection and repair methods
  • Optional helpers for cooldowns, daily rewards, purchase receipts, and timed effects

Most of the optional helpers are separate from the core system, so they can be removed if they are not needed.

Limitations and Important Notes

Limitations

VirtualStore does not make changes across multiple DataStore keys atomic.

For example, a secure player trade still needs a persistent journal and a recovery or compensation system. Local locks by themselves are not enough for a fully safe multi-profile trade.

MessagingService is also only treated as a way to speed things up. The system should still work correctly even if messages are delayed or missed.


Current State

VirtualStore is currently at v0.1.0.

The main systems and documentation are available. Since this is the first public release, test it against your game’s requirements before moving an established production economy.

VirtualStore is open source and future releases will continue improving the framework as it is used in more projects.

Documentation
Source Code

2 Likes