A lightweight wrapper around ffrostfall/keyForm for Mark-Marks/sapphire
- Install it with wally
[dependencies]
sapphire_data = "mark-marks/sapphire-data@LATEST" # replace LATEST with the latest version
wally install
2. Set it up
local sapphire_data = require("@pkg/sapphire_data")
local template = {
...
}
export type data = typeof(template)
return sapphire_data.server({
store_name = "data",
template = template,
})
-- or on the client:
return sapphire_data.client({
template = template,
})
- Extend sapphire with it
local data = require(".../data")
sapphire
:use(data)
type server<data> = {
--- @private
identifier: string,
--- @private
extension: () -> (),
--- @private
methods: {},
get_data: (player: Player) -> data,
on_data_changed: (fn: (Player, data) -> ()) -> () -> (),
create_transform: <T...>(fn: (data, T...) -> data) -> (Player, T...) -> (),
transform: (player: Player, fn: (data) -> data) -> (),
calculate_difference: (player: Player, exposable_data: any) -> buffer?,
}
type server_settings<data> = {
--- Store name.
store_name: string,
--- Player data template.
--- ⚠️ Expected to be a table!
template: data,
}
type client<data> = {
--- @private
identifier: string,
--- @private
extension: () -> (),
--- @private
methods: {},
get_data: () -> data?,
apply_difference: (difference: buffer) -> (),
on_data_changed: (fn: (data) -> ()) -> () -> (),
}
type client_settings<data> = {
--- Player data template.
--- ⚠️ Expected to be a table!
template: data,
}
<data>(
settings: server_settings<data>
) -> server<data>
<data>(
settings: client_settings<data>
) -> client<data>
Gets the players data.
(
player: Player
) -> data
Listens to data changes. Returns a disconnect function.
(
fn: (Player, data) -> ()
) -> () -> ()
Creates a transform for player data.
Use sapphire_data.transform()
for one time data changes.
<T...>(
fn: (data, T...) -> data
) -> (
player: Player,
T...
) -> ()
local increment_coins = sapphire_data.create_transform(function(data, n: number)
data.coins += n
return data
end)
increment_coins(player, 10)
Transforms player data with the given function.
Use .create_transform()
for multiple data changes.
(
player: Player
) -> (
data: data
) -> data
sapphire_data.transform(player, function(data)
data.coins += 10
return data
end)
Calculates the difference between the player's last calculated difference and their current data. Returns a buffer representing the difference.
(
player: Player,
exposable_data: any
) -> buffer?
local difference = sapphire_data.calculate_difference(player)
if not difference then
return
end
data_replication_event.send_to(player, difference)
You may also provide the new data yourself to expose only what you need to to the client.
local exposed_data = make_exposable(sapphire_data.get_data(player))
local difference = sapphire_data.calculate_difference(player, exposed_data)
if not difference then
return
end
data_replication_event.send_to(player, difference)
Gets the local players data.
() -> data?
Applies the difference received from the server's sapphire_data.calculate_difference()
.
(
difference: buffer
) -> ()
data_replication_event.listen(function(difference)
sapphire_data.apply_difference(difference)
end)
Listens to data changes. The received data is guaranteed to not be nil. Returns a disconnect function.
(
fn: (data) -> ()
) -> () -> ()