Extending Players
BDSC supports dynamic, runtime-safe extension of player objects with custom data and methods. This lets you build modular logic without touching the core.
Add Data
Adds custom data to the player. Optionally replicated to the client.
Example
player:add_data("stats", { health = 100, stamina = 50 }, true)
Parameters
stats
– key name for the data entry.{ health = 100, stamina = 50 }
– table to store.true
– replicate to client (optional).
Add Methods
Attach custom methods that can later be executed via run_method
.
Example
player:add_method("stats", "get_health", function(self)
local stats = self:get_data("stats")
return stats and stats.health or 0
end)
Usage
player:run_method("stats", "get_health")
Update Data
Modify an existing data block and optionally sync it.
Example
local stats = player:get_data("stats")
stats.health = stats.health - 10
player:set_data("stats", stats, true)
Remove Data
Removes a data key.
Example
player:remove_data("job")
Sync Data
Force a sync of all replicated data to the client.
Example
player:sync_data()
Dump All Data
Logs all currently stored player data.
Example
local data = player:get_data()
for k, v in pairs(data) do
print(k .. ": " .. json.encode(v))
end
Here’s a concise section explaining how the on_save
and on_destroy
methods work when registered via namespaces:
Lifecycle Hooks
BDSC supports namespace-specific lifecycle methods that automatically run when certain player events occur.
These methods are defined under a specific namespace using add_method
and are called internally during key moments in the player's lifecycle.
Supported Hooks
on_save
Called when player:save()
is triggered (e.g., on disconnect or manually).
on_destroy
Called when player:destroy()
is triggered (e.g., on player drop).
How It Works
When a lifecycle event runs, BDSC will automatically check each namespace for these methods and call them in order.
Example
player:add_method("stats", "on_save", function(self)
print("Saving stats for player:", self.meta.username)
end)
player:add_method("inventory", "on_destroy", function(self)
print("Cleaning up inventory for:", self.meta.username)
end)
You do not need to manually call these - BDSC will handle them as long as they are added under a namespace using add_method(namespace, "on_save" | "on_destroy", fn)
.
Avoid long-running operations inside these hooks — keep them lightweight for stability.
Missing Method Safety
Calling a non-existent method will return nil
.
Example
local result = player:run_method("missing")
print("Result:", result or "nil")
No Internal Access
Only the meta
table is exposed. All other functionality data, methods, syncing - must be accessed via the public API.
Direct access to _extensions._data
, _extensions._methods
, or other internals is not possible and never required.
Quick Example
Below is a minimal, self-contained example that demonstrates how to create a player object and extend it externally using basic commands.
This includes:
Adding a
stats
data blockDefining custom methods (like
get_health
)Syncing data to the client
Simulating damage
Handling save logic
local core = exports.bdsc:import()
-- Create and initialize a new player
RegisterCommand("make", function(src)
local player = core.create_player(src)
if not player then print("Failed to create player") return end
-- Add initial stats
player:add_data("stats", {
health = 100,
stamina = 50
}, true)
-- Add method to retrieve health
player:add_method("stats", "get_health", function(self)
local stats = self:get_data("stats")
return stats and stats.health or 0
end)
-- Add save lifecycle method
player:add_method("stats", "on_save", function()
print("saving player stats")
end)
print("Player created and methods attached.")
end, false)
-- Check player health
RegisterCommand("hp", function(src)
local player = core.get_player(src)
if not player then print("No player found.") return end
local hp = player:run_method("stats", "get_health")
print("Health:", hp)
end, false)
-- Apply damage to the player
RegisterCommand("damage", function(src, args)
local player = core.get_player(src)
if not player then print("No player found.") return end
local amount = tonumber(args[1]) or 10
local stats = player:get_data("stats")
stats.health = stats.health - amount
player:set_data("stats", stats, true)
print("Damaged player for", amount)
end, false)
Tip: Every player object supports runtime extension. You can safely add new data or methods at any point — even after creation.
Last updated