Example: Saving Locations

This page will show you how to save the player's last location using FastBitBuffer and DataStore2. This assumes you already have it installed and it is located in ServerStorage. If you want to see it in action, the place is right here.

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local DataStore2 = require(ServerStorage.DataStore2)
local FastBitBuffer = require(ServerStorage.FastBitBuffer)

local DATA_STORE_NAME = "LastPlayerLocation"
local RAISED_VECTOR3 = Vector3.new(0, 3, 0)
local DEFAULT_PLAYER_SPAWN_CFRAME = CFrame.new(0, 6, 0)

local DEFAULT_PLAYER_SPAWN_BASE64 do
    local bitBuffer = FastBitBuffer.new()
    bitBuffer:WriteCFrame(DEFAULT_PLAYER_SPAWN_CFRAME)
    DEFAULT_PLAYER_SPAWN_BASE64 = bitBuffer:ToBase64()

    bitBuffer:Destroy()
    bitBuffer = nil
end

local playerLocations = {}

local function beforeInitialGet(serialized)
    local bitBuffer = FastBitBuffer.new()
    bitBuffer:FromBase64(serialized)

    local deserialized = bitBuffer:ReadCFrame()
    bitBuffer:Destroy()
    bitBuffer = nil

    return deserialized
end

local function beforeSave(deserialized)
    local bitBuffer = FastBitBuffer.new()
    bitBuffer:WriteCFrame(deserialized)

    local serialized = bitBuffer:ToBase64()
    bitBuffer:Destroy()
    bitBuffer = nil

    return serialized
end

local function onUpdate(player)
    return function(playerLocation)
        playerLocations[player] = playerLocation
    end
end

local function characterRemoving(player)
    return function(character)
        local humanoid = character:FindFirstChildOfClass("Humanoid")
        if humanoid and humanoid.Health > 0 then
            local playerLocation = DataStore2(DATA_STORE_NAME, player)
            playerLocation:Set(character:GetPrimaryPartCFrame())
        end
    end
end

local function playerAdded(player)
    if not playerLocations[player] then
        player.CharacterRemoving:Connect(characterRemoving(player))

        local playerLocation = DataStore2(DATA_STORE_NAME, player)
        playerLocation:BeforeInitialGet(beforeInitialGet)
        playerLocation:BeforeSave(beforeSave)
        playerLocation:OnUpdate(onUpdate(player))

        local defaultLocation = playerLocation:Get(DEFAULT_PLAYER_SPAWN_BASE64)
        if type(defaultLocation) == "string" then
            defaultLocation = beforeInitialGet(defaultLocation)
        end

        local character = player.Character or player.CharacterAdded:Wait()
        character:WaitForChild("HumanoidRootPart")
        character:SetPrimaryPartCFrame(defaultLocation + RAISED_VECTOR3)
    end
end

local function playerRemoving(player)
    if playerLocations[player] then
        playerLocations[player] = nil
    end
end

Players.PlayerAdded:Connect(playerAdded)
Players.PlayerRemoving:Connect(playerRemoving)
for _, player in ipairs(Players:GetPlayers()) do playerAdded(player) end