Data Storage Script

Kill Leaderboard Script Works For Some Weapons, But not others. I don’t know how to fix this.

1 Like

Perhaps you should make it so the weapons that you’re using handle the kill value change? I don’t know much about your situation here so maybe if you provide me with more details I could help you out.

2 Likes

What do you mean details? More scripts?

1 Like

How exactly do you check for who killed a player? As far as I can see in the script you’ve provided it checks for a Value (Assuming that’s the killer) inside of the Humanoid instance. Is there another script that sets the Value?

1 Like

@thebulldogs22ALT
In the tool damage script, (It’s very messy but line 427 should be what you mean) if the person dies after dmg is done, then it sets killer to the player. [Ctrl + F] local function _defaultDamageCallback

local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local IsServer = RunService:IsServer()

-- Dependencies
local WeaponData = script.Parent:WaitForChild("WeaponData")
local WeaponsSystemFolder = script.Parent
local WeaponTypes = WeaponsSystemFolder:WaitForChild("WeaponTypes")
local Libraries = WeaponsSystemFolder:WaitForChild("Libraries")
local ShoulderCamera = require(Libraries:WaitForChild("ShoulderCamera"))
local WeaponsGui = require(Libraries:WaitForChild("WeaponsGui"))
local SpringService = require(Libraries:WaitForChild("SpringService"))
local ancestorHasTag = require(Libraries:WaitForChild("ancestorHasTag"))
ShoulderCamera.SpringService = SpringService

local Configuration = WeaponsSystemFolder:WaitForChild("Configuration")
local ConfigurationValues = {
	SprintEnabled = Configuration:WaitForChild("SprintEnabled"),
	SlowZoomWalkEnabled = Configuration:WaitForChild("SlowZoomWalkEnabled"),
}

local WEAPON_TAG = "WeaponsSystemWeapon"
local WEAPON_TYPES_LOOKUP = {}

local REMOTE_EVENT_NAMES = {
	"WeaponFired",
	"WeaponHit",
	"WeaponReloadRequest",
	"WeaponReloaded",
	"WeaponReloadCanceled",
	"WeaponActivated"
}
local REMOTE_FUNCTION_NAMES = {}

--Set up WeaponTypes lookup table
do
	local function onNewWeaponType(weaponTypeModule)
		if not weaponTypeModule:IsA("ModuleScript") then
			return
		end
		local weaponTypeName = weaponTypeModule.Name
		xpcall(function()
			coroutine.wrap(function()
				local weaponType = require(weaponTypeModule)
				assert(typeof(weaponType) == "table", string.format("WeaponType \"%s\" did not return a valid table", weaponTypeModule:GetFullName()))
				WEAPON_TYPES_LOOKUP[weaponTypeName] = weaponType
			end)()
		end, function(errMsg)
			warn(string.format("Error while loading %s: %s", weaponTypeModule:GetFullName(), errMsg))
			warn(debug.traceback())
		end)
	end
	for _, child in pairs(WeaponTypes:GetChildren()) do
		onNewWeaponType(child)
	end
	WeaponTypes.ChildAdded:Connect(onNewWeaponType)
end

local WeaponsSystem = {}
WeaponsSystem.didSetup = false
WeaponsSystem.knownWeapons = {}
WeaponsSystem.connections = {}
WeaponsSystem.networkFolder = nil
WeaponsSystem.remoteEvents = {}
WeaponsSystem.remoteFunctions = {}
WeaponsSystem.currentWeapon = nil
WeaponsSystem.aimRayCallback = nil

WeaponsSystem.CurrentWeaponChanged = Instance.new("BindableEvent")

local NetworkingCallbacks = require(WeaponsSystemFolder:WaitForChild("NetworkingCallbacks"))
NetworkingCallbacks.WeaponsSystem = WeaponsSystem

local _damageCallback = nil
local _getTeamCallback = nil

function WeaponsSystem.setDamageCallback(cb)
	_damageCallback = cb
end

function WeaponsSystem.setGetTeamCallback(cb)
	_getTeamCallback = cb
end

function WeaponsSystem.setup()
	if WeaponsSystem.didSetup then
		warn("Warning: trying to run WeaponsSystem setup twice on the same module.")
		return
	end
	print(script.Parent:GetFullName(), "is now active.")

	WeaponsSystem.doingSetup = true

	--Setup network routing
	if IsServer then
		local networkFolder = Instance.new("Folder")
		networkFolder.Name = "Network"

		for _, remoteEventName in pairs(REMOTE_EVENT_NAMES) do
			local remoteEvent = Instance.new("RemoteEvent")
			remoteEvent.Name = remoteEventName
			remoteEvent.Parent = networkFolder

			local callback = NetworkingCallbacks[remoteEventName]
			if not callback then
				--Connect a no-op function to ensure the queue doesn't pile up.
				warn("There is no server callback implemented for the WeaponsSystem RemoteEvent \"%s\"!")
				warn("A default no-op function will be implemented so that the queue cannot be abused.")
				callback = function() end
			end
			WeaponsSystem.connections[remoteEventName .. "Remote"] = remoteEvent.OnServerEvent:Connect(function(...)
				callback(...)
			end)
			WeaponsSystem.remoteEvents[remoteEventName] = remoteEvent
		end
		for _, remoteFuncName in pairs(REMOTE_FUNCTION_NAMES) do
			local remoteFunc = Instance.new("RemoteEvent")
			remoteFunc.Name = remoteFuncName
			remoteFunc.Parent = networkFolder

			local callback = NetworkingCallbacks[remoteFuncName]
			if not callback then
				--Connect a no-op function to ensure the queue doesn't pile up.
				warn("There is no server callback implemented for the WeaponsSystem RemoteFunction \"%s\"!")
				warn("A default no-op function will be implemented so that the queue cannot be abused.")
				callback = function() end
			end
			remoteFunc.OnServerInvoke = function(...)
				return callback(...)
			end
			WeaponsSystem.remoteFunctions[remoteFuncName] = remoteFunc
		end

		networkFolder.Parent = WeaponsSystemFolder
		WeaponsSystem.networkFolder = networkFolder
	else
		WeaponsSystem.StarterGui = game:GetService("StarterGui")

		WeaponsSystem.camera = ShoulderCamera.new(WeaponsSystem)
		WeaponsSystem.gui = WeaponsGui.new(WeaponsSystem)

		if ConfigurationValues.SprintEnabled.Value then
			WeaponsSystem.camera:setSprintEnabled(ConfigurationValues.SprintEnabled.Value)
		end
		
		if ConfigurationValues.SlowZoomWalkEnabled.Value then
			WeaponsSystem.camera:setSlowZoomWalkEnabled(ConfigurationValues.SlowZoomWalkEnabled.Value)
		end

		local networkFolder = WeaponsSystemFolder:WaitForChild("Network", math.huge)

		for _, remoteEventName in pairs(REMOTE_EVENT_NAMES) do
			coroutine.wrap(function()
				local remoteEvent = networkFolder:WaitForChild(remoteEventName, math.huge)
				local callback = NetworkingCallbacks[remoteEventName]
				if callback then
					WeaponsSystem.connections[remoteEventName .. "Remote"] = remoteEvent.OnClientEvent:Connect(function(...)
						callback(...)
					end)
				end
				WeaponsSystem.remoteEvents[remoteEventName] = remoteEvent
			end)()
		end
		for _, remoteFuncName in pairs(REMOTE_FUNCTION_NAMES) do
			coroutine.wrap(function()
				local remoteFunc = networkFolder:WaitForChild(remoteFuncName, math.huge)
				local callback = NetworkingCallbacks[remoteFuncName]
				if callback then
					remoteFunc.OnClientInvoke = function(...)
						return callback(...)
					end
				end
				WeaponsSystem.remoteFunctions[remoteFuncName] = remoteFunc
			end)()
		end

		Players.LocalPlayer.CharacterAdded:Connect(WeaponsSystem.onCharacterAdded)
		if Players.LocalPlayer.Character then
			WeaponsSystem.onCharacterAdded(Players.LocalPlayer.Character)
		end

		WeaponsSystem.networkFolder = networkFolder
		WeaponsSystem.camera:setEnabled(true)
	end

	--Setup weapon tools and listening
	WeaponsSystem.connections.weaponAdded = CollectionService:GetInstanceAddedSignal(WEAPON_TAG):Connect(WeaponsSystem.onWeaponAdded)
	WeaponsSystem.connections.weaponRemoved = CollectionService:GetInstanceRemovedSignal(WEAPON_TAG):Connect(WeaponsSystem.onWeaponRemoved)

	for _, instance in pairs(CollectionService:GetTagged(WEAPON_TAG)) do
		WeaponsSystem.onWeaponAdded(instance)
	end

	WeaponsSystem.doingSetup = false
	WeaponsSystem.didSetup = true
end

function WeaponsSystem.onCharacterAdded(character)
	-- Make it so players unequip weapons while seated, then reequip weapons when they become unseated
	local humanoid = character:WaitForChild("Humanoid")
	WeaponsSystem.connections.seated = humanoid.Seated:Connect(function(isSeated)
		if isSeated then
			WeaponsSystem.seatedWeapon = character:FindFirstChildOfClass("Tool")
			humanoid:UnequipTools()
			WeaponsSystem.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
		else
			WeaponsSystem.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, true)
			humanoid:EquipTool(WeaponsSystem.seatedWeapon)
		end
	end)
end

function WeaponsSystem.shutdown()
	if not WeaponsSystem.didSetup then
		return
	end

	for _, weapon in pairs(WeaponsSystem.knownWeapons) do
		weapon:onDestroyed()
	end
	WeaponsSystem.knownWeapons = {}

	if IsServer and WeaponsSystem.networkFolder then
		WeaponsSystem.networkFolder:Destroy()
	end
	WeaponsSystem.networkFolder = nil
	WeaponsSystem.remoteEvents = {}
	WeaponsSystem.remoteFunctions = {}

	for _, connection in pairs(WeaponsSystem.connections) do
		if typeof(connection) == "RBXScriptConnection" then
			connection:Disconnect()
		end
	end
	WeaponsSystem.connections = {}
end

function WeaponsSystem.getWeaponTypeFromTags(instance)
	for _, tag in pairs(CollectionService:GetTags(instance)) do
		local weaponTypeFound = WEAPON_TYPES_LOOKUP[tag]
		if weaponTypeFound then
			return weaponTypeFound
		end
	end

	return nil
end

function WeaponsSystem.createWeaponForInstance(weaponInstance)
	coroutine.wrap(function()
		local weaponType = WeaponsSystem.getWeaponTypeFromTags(weaponInstance)
		if not weaponType then
			local weaponTypeObj = weaponInstance:WaitForChild("WeaponType")

			if weaponTypeObj and weaponTypeObj:IsA("StringValue") then
				local weaponTypeName = weaponTypeObj.Value
				local weaponTypeFound = WEAPON_TYPES_LOOKUP[weaponTypeName]
				if not weaponTypeFound then
					warn(string.format("Cannot find the weapon type \"%s\" for the instance %s!", weaponTypeName, weaponInstance:GetFullName()))
					return
				end

				weaponType = weaponTypeFound
			else
				warn("Could not find a WeaponType tag or StringValue for the instance ", weaponInstance:GetFullName())
				return
			end
		end

		-- Since we might have yielded while trying to get the WeaponType, we need to make sure not to continue
		-- making a new weapon if something else beat this iteration.
		if WeaponsSystem.getWeaponForInstance(weaponInstance) then
			warn("Already got ", weaponInstance:GetFullName())
			warn(debug.traceback())
			return
		end

		-- We should be pretty sure we got a valid weaponType by now
		assert(weaponType, "Got invalid weaponType")

		local weapon = weaponType.new(WeaponsSystem, weaponInstance)
		WeaponsSystem.knownWeapons[weaponInstance] = weapon
	end)()
end

function WeaponsSystem.getWeaponForInstance(weaponInstance)
	if not typeof(weaponInstance) == "Instance" then
		warn("WeaponsSystem.getWeaponForInstance(weaponInstance): 'weaponInstance' was not an instance.")
		return nil
	end

	return WeaponsSystem.knownWeapons[weaponInstance]
end

-- and (IsServer or weaponInstance:IsDescendantOf(Players.LocalPlayer))

function WeaponsSystem.onWeaponAdded(weaponInstance)
	local weapon = WeaponsSystem.getWeaponForInstance(weaponInstance)
	if not weapon then
		WeaponsSystem.createWeaponForInstance(weaponInstance)
	end
end

function WeaponsSystem.onWeaponRemoved(weaponInstance)
	local weapon = WeaponsSystem.getWeaponForInstance(weaponInstance)
	if weapon then
		weapon:onDestroyed()
	end
	WeaponsSystem.knownWeapons[weaponInstance] = nil
end

function WeaponsSystem.getRemoteEvent(name)
	if not WeaponsSystem.networkFolder then
		return
	end

	local remoteEvent = WeaponsSystem.remoteEvents[name]
	if IsServer then
		if not remoteEvent then
			warn("No RemoteEvent named ", name)
			return nil
		end

		return remoteEvent
	else
		if not remoteEvent then
			remoteEvent = WeaponsSystem.networkFolder:WaitForChild(name, math.huge)
		end

		return remoteEvent
	end
end

function WeaponsSystem.getRemoteFunction(name)
	if not WeaponsSystem.networkFolder then
		return
	end

	local remoteFunc = WeaponsSystem.remoteFunctions[name]
	if IsServer then
		if not remoteFunc then
			warn("No RemoteFunction named ", name)
			return nil
		end

		return remoteFunc
	else
		if not remoteFunc then
			remoteFunc = WeaponsSystem.networkFolder:WaitForChild(name, math.huge)
		end

		return remoteFunc
	end
end

function WeaponsSystem.setWeaponEquipped(weapon, equipped)
	assert(not IsServer, "WeaponsSystem.setWeaponEquipped should only be called on the client.")
	if not weapon then
		return
	end

	local lastWeapon = WeaponsSystem.currentWeapon
	local hasWeapon = false
	local weaponChanged = false

	if lastWeapon == weapon then
		if not equipped then
			WeaponsSystem.currentWeapon = nil
			hasWeapon = false
			weaponChanged = true
		else
			weaponChanged = false
		end
	else
		if equipped then
			WeaponsSystem.currentWeapon = weapon
			hasWeapon = true
			weaponChanged = true
		end
	end

	if WeaponsSystem.camera then
		WeaponsSystem.camera:resetZoomFactor()
		WeaponsSystem.camera:setHasScope(false)

		if WeaponsSystem.currentWeapon then
			WeaponsSystem.camera:setZoomFactor(WeaponsSystem.currentWeapon:getConfigValue("ZoomFactor", 1.1))
			WeaponsSystem.camera:setHasScope(WeaponsSystem.currentWeapon:getConfigValue("HasScope", false))
		end
	end

	if WeaponsSystem.gui then
		WeaponsSystem.gui:setEnabled(hasWeapon)

		if WeaponsSystem.currentWeapon then
			WeaponsSystem.gui:setCrosshairWeaponScale(WeaponsSystem.currentWeapon:getConfigValue("CrosshairScale", 1))
		else
			WeaponsSystem.gui:setCrosshairWeaponScale(1)
		end
	end

	if weaponChanged then
		WeaponsSystem.CurrentWeaponChanged:Fire(weapon.instance, lastWeapon and lastWeapon.instance)
	end
end

function WeaponsSystem.getHumanoid(part)
	while part and part ~= workspace do
		if part:IsA("Model") and part.PrimaryPart and part.PrimaryPart.Name == "HumanoidRootPart" then
			return part:FindFirstChildOfClass("Humanoid")
		end

		part = part.Parent
	end
end

function WeaponsSystem.getPlayerFromHumanoid(humanoid)
	for _, player in ipairs(Players:GetPlayers()) do
		if player.Character and humanoid:IsDescendantOf(player.Character) then
			return player
		end
	end
end

local function _defaultDamageCallback(system, target, amount, damageType, --here dealer, hitInfo, damageData)
	if target:IsA("Humanoid") then
		target:TakeDamage(amount)
		game:GetService('Players').PlayerAdded:Connect(function(player)
			player.CharacterAdded:Connect(function(character)
				character:WaitForChild("Humanoid").Died:Connect(function()
		local killer = script.Parent.Parent.Parent
	end
end

function WeaponsSystem.doDamage(target, amount, damageType, dealer, hitInfo, damageData)
	if not target or ancestorHasTag(target, "WeaponsSystemIgnore") then
		return
	end
	if IsServer then
		if target:IsA("Humanoid") and dealer:IsA("Player") and dealer.Character then
			local dealerHumanoid = dealer.Character:FindFirstChildOfClass("Humanoid")
			local targetPlayer = Players:GetPlayerFromCharacter(target.Parent)
			if dealerHumanoid and target ~= dealerHumanoid and targetPlayer then
				-- Trigger the damage indicator
				WeaponData:FireClient(targetPlayer, "HitByOtherPlayer", dealer.Character.HumanoidRootPart.CFrame.Position)
			end
		end

		-- NOTE:  damageData is a more or less free-form parameter that can be used for passing information from the code that is dealing damage about the cause.
		-- .The most obvious usage is extracting icons from the various weapon types (in which case a weapon instance would likely be passed in)
		-- ..The default weapons pass in that data
		local handler = _damageCallback or _defaultDamageCallback
		handler(WeaponsSystem, target, amount, damageType, dealer, hitInfo, damageData)
	end
end

local function _defaultGetTeamCallback(player)
	return 0
end

function WeaponsSystem.getTeam(player)
	local handler = _getTeamCallback or _defaultGetTeamCallback
	return handler(player)
end

function WeaponsSystem.playersOnDifferentTeams(player1, player2)
	if player1 == player2 or player1 == nil or player2 == nil then
		-- This allows players to damage themselves and NPC's
		return true
	end

	local player1Team = WeaponsSystem.getTeam(player1)
	local player2Team = WeaponsSystem.getTeam(player2)
	return player1Team == 0 or player1Team ~= player2Team
end
return WeaponsSystem
2 Likes

Oops-
I attached the wrong script…
My real problem is certain guns don’t give XP or kills.

print("Keaderboard script loaded!")

maxlevel = 50

function onXPChanged(player, score, level)
		if score.Value>= 25 * (level.Value) + 100 and level.Value < maxlevel then 
			score.Value = score.Value - (25*(level.Value) + 100) 
			level.Value = level.Value + 1 
		end 
	end

function onLevelUp(player, score, level) 
if player.Character~=nil then 
for i = 1,5 do 
local fireworks = Instance.new("Part") 
fireworks.Shape = 0 
fireworks.formFactor = "Symmetric" 
fireworks.Size = Vector3.new(1,1,1) 
fireworks.BrickColor = BrickColor.Random() 
fireworks.CFrame = player.Character.Head.CFrame + Vector3.new(0,2,0) 
fireworks.Parent = game.Workspace 
game:GetService("Debris"):AddItem(fireworks, 2) 
fireworks.Velocity = Vector3.new(math.random(-30,30),math.random(-30,30),math.random(-30,30)) 
end 
end 
local m = Instance.new("Hint") 
m.Parent = game.Workspace 
m.Text = player.Name .. " has ranked up!" --Sweet!
wait(5) 
m.Parent = nil 
end



function onHumanoidDied(humanoid, player)
	local stats = player:findFirstChild("leaderstats")
	if stats ~= nil then
		local deaths = stats:findFirstChild("Dies")
		deaths.Value = deaths.Value + 1
		

		-- do short dance to try and find the killer

		local killer = getKillerOfHumanoidIfStillInGame(humanoid)

		handleKillCount(humanoid, player)
	end
end

function onPlayerRespawn(property, player)
	-- need to connect to new humanoid
	
	if property == "Character" and player.Character ~= nil then
		local humanoid = player.Character.Humanoid
			local p = player
			local h = humanoid
			humanoid.Died:connect(function() onHumanoidDied(h, p) end )
	end
end

function getKillerOfHumanoidIfStillInGame(humanoid)
	-- returns the player object that killed this humanoid
	-- returns nil if the killer is no longer in the game

	-- check for kill tag on humanoid - may be more than one - todo: deal with this
	local tag = humanoid:findFirstChild("creator")

	-- find player with name on tag
	if tag ~= nil then
		
		local killer = tag.Value
		if killer.Parent ~= nil then -- killer still in game
			return killer
		end
	end

	return nil
end

function handleKillCount(humanoid, player)
	local killer = getKillerOfHumanoidIfStillInGame(humanoid)
	if killer ~= nil then
		local stats = killer:findFirstChild("leaderstats")
		if stats ~= nil then
			local kills = stats:findFirstChild("Kills")
			local score = stats:findFirstChild("XP")
			local level = stats:findFirstChild("Rank")
			if killer ~= player then
				score.Value = score.Value + 250 * 
				kills.Value = kills.Value + 1
				
			else
				kills.Value = kills.Value - 1
			end
		end
	end
end


-----------------------------------------------
function plr(newPlayer)
		local stats = Instance.new("IntValue")
		stats.Name = "leaderstats"

		local kills = Instance.new("IntValue")
		kills.Name = "Kills"
		kills.Value = 0

		local deaths = Instance.new("IntValue")
		deaths.Name = "Dies"
		deaths.Value = 0

		local score = Instance.new("IntValue")
		score.Name = "XP"
		score.Value = 0

		local rank = Instance.new("IntValue")
		rank.Name = "Rank"
		rank.Value = 1

		local fill = Instance.new("IntValue")
		fill.Name= "filler1"
		fill.Value = 0
		
		rank.Parent = stats
		score.Parent = stats
		kills.Parent = stats
		deaths.Parent = stats
		fill.Parent = stats
		stats.Parent = newPlayer

	--[[	if newPlayer.usedId == 65006475 then
		newPlayer.leaderstats.Rank.Value = maxlevel
		end]]

	score.Changed:connect(function() onXPChanged(newPlayer, score, rank) end) 
	rank.Changed:connect(function() onLevelUp(newPlayer, score, rank) end)

		while true do
			if newPlayer.Character ~= nil then break end
			wait(5)
		end

		local humanoid = newPlayer.Character.Humanoid

		humanoid.Died:connect(function() onHumanoidDied(humanoid, newPlayer) end )

		-- start to listen for new humanoid
		newPlayer.Changed:connect(function(property) onPlayerRespawn(property, newPlayer) end )
		end


		for _,v in pairs(game.Players:GetPlayers()) do
	plr(v)
end

game.Players.ChildAdded:connect(plr)
1 Like

Sorry! I was offline so I couldn’t respond back on time.

local function _defaultDamageCallback(system, target, amount, damageType, dealer, hitInfo, damageData)
	if target:IsA("Humanoid") and game:GetService("Players"):GetPlayerFromCharacter(target.Parent) ~= nil then --Check if the target is a Humanoid and that the Parent of the humanoid is actually a Character of a Player
		if target.Health > 0 then --Checking whether the target is alive
			target:TakeDamage(amount) --Damaging the Humanoid
			if target.Health <= 0 then --Checking whether the target is alive
				if dealer.leaderstats:FindFirstChild("Kills") then --Checking whether the dealer has a Kills Value
					dealer.leaderstats.Kills.Value += 1 --Increment the Kills value by 1.
				end
			end
		end
	end
end

Here’s my example of a kill value changer. Basically what the function does is it checks whether the target is a Humanoid and whether the Character that the Humanoid is a child of is actually a Players chatacter. If it is then it checks if the target is alive. If that is the case then it’ll apply damage to the target. After that it checks whether the Humanoids health is Equal or under 0. If so then it’ll get the damage dealers Kills value and increment it by 1.

2 Likes

My save script isn’t working. Any ideas?

game.Players.ChildAdded:connect(plr)
local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("XPValueSaver")


local kills = Instance.new("IntValue")
kills.Name = "Kills"
players.PlayerAdded:connect(function(player)
	kills.Changed:connect(function()
		ds3:SetAsync(player.UserId, kills.Value)
	end)
game.Players.ChildAdded:connect(plr) --Remove this as it is completely unnecessary. 
local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("XPValueSaver")


local kills = Instance.new("IntValue")
kills.Name = "Kills" -- Move these two lines inside of the PlayerAdded event. What you're doing here is making only one IntValue that has no parent whatsoever.
players.PlayerAdded:connect(function(player) --Alright so inside of here, what you're doing is just saving the Value inside of the DataStore upon it's change. This isn't a very good practice as it makes a lot more DataStore requests than it should. Also, you should make it so the script actually gets the amount of kills with ds3:GetAsync(). This'll return the saved value for the player.
	kills.Changed:connect(function()
		ds3:SetAsync(player.UserId, kills.Value)
	end) 

Here’s what I would do if I was you:

local PlayerService = game:GetService("Players")
local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("XPValueSaver")
--------DEFINITIONS

--PLAYERADDED EVENT
PlayerService.PlayerAdded:Connect(function(player)
	local plrDat = nil
	local fld = Instance.new("Folder")
	fld.Name = "leaderstats"
	fld.Parent = player --Here I create a folder named 'leaderstats' that is located inside of the player.
	local kills = Instance.new("IntValue")
	kills.Name = "Kills"
	kills.Parent = fld --Here I create a new IntValue (Kills value) that is located inside of the newly created leaderstats folder.
	local success,err = pcall(function()
		plrDat = DS:GetAsync(player.UserId)
	end) --This function right here loads the data for the player from the DataStore. I'm using pcalls here for error handling during the loading.
	if success then --If there weren't any issues accessing the DataStore and the players data was obtained successfully, it'll proceed with the script.
		if plrDat ~= nil then --In case the player isn't new and already has existing data, we'll just load it!
			kills.Value = plrDat --Here we set the kills value to the loaded data.
			print("Loaded player data for user "..player.Name)
		else --else if the player has no data (Is a new player):
			kills.Value = 0 -- We set their kills value to 0 (Considering they're new.)
			DS:SetAsync(player.UserId, kills.Value) -- We create a new save for the player in the DataStore
			print("User "..player.Name.." appears to be new (Has no kills data). New save file will be created.")
		end
	else --else if there was an error while accessing the DataStore, it'll print out a message informing you that data loading has failed and will let you know what the error is. 
		print("Failed to load data for user "..player.Name.." ("..tostring(err)..").")
	end
end)
--PLAYERREMOVING EVENT (Player leaving)
PlayerService.PlayerRemoving:Connect(function(player)
	if player.leaderstats:FindFirstChild("Kills") then --When a player is leaving, we check whether the player still has the Kills IntValue (Though I like to keep stuff clean without errors hence I did this. The if check is optional if you're sure that the Kills IntValue instance will not be removed or changed.)
		local success,err = pcall(function()
			DS:SetAsync(player.UserId, player.leaderstats.Kills.Value)
		end) --pcall function that saves the player kills inside the DataStore.
		if success then --If it was successful, it'll print out this message.
			print("Player data saved for user "..player.Name)
		else -- if there was an error and saving has failed, the error will be printed out here.
			warn("Failed to save kills data for user "..player.Name..". ("..tostring(err)..").")
		end
	end
end)

Hope I was able to help you out.

EDIT: Fixed a few errors in my code.

Sorry, I was at a funeral yesterday. I am going to test this out!

@avwzz This goes in ServerScriptService right?

@CodeOverloader Yeah, place it there and it should work. Let me know if there are any errors as I’ve written that without testing.

@thebulldogs22ALT
This might be on me, but the kills aren’t accounted for. Any ideas?

I have a kill effects script that might be the problem but I don’t know.

This is in starter Character:

        local Children = game.workspace.OffHeads:GetChildren()
local num = math.random(1,5)
if num == 1 then
	wait(3)
	script.Parent.Humanoid.Died:Connect(function()
		local Children = script.Parent:GetChildren()
		for i = 1, #Children do
			Children[i].Transparency = 1
		end
	end)
	local Humanoid = script.parent.Humanoid
	local Character = script.Parent
	local Part = game.workspace.Model
	for i = 1, #Children do
		script.Parent.Humanoid.Died:Connect(function()
			Children[i].Anchored = false
			Children[i].Position = script.Parent.UpperTorso.Position
		end)
	end
elseif num == 2 then
	wait(3)
	script.Parent.Humanoid.Died:Connect(function()
		local Children = script.Parent:GetChildren()
		for i = 1, #Children do
			Children[i].Transparency = 1
		end
	end)
	local Humanoid = script.parent.Humanoid
	local Character = script.Parent
	local Part1 = game.workspace.Cake
	local Children = game.workspace.Cake:GetChildren()
	for i = 1, #Children do
		script.Parent.Humanoid.Died:Connect(function()
			Children[i].Anchored = false
			Children[i].Position = script.Parent.UpperTorso.Position
		end)
	end
elseif num == 3 then
	--------------------------------------------------------
	---------- Version 2.0 ---------------------------------
	---------- Released 8/17/2017 --------------------------
	---------- Written by orange451 ------------------------
	--------------------------------------------------------
	wait();

	local DEBUG = false;

	function waitFor( directory, name ) 
		while ( directory == nil or (name ~= nil and directory:FindFirstChild(name) == nil) ) do
			wait(0.1);
		end
		if ( name == nil ) then
			return directory;
		else
			return directory:FindFirstChild(name);
		end
	end

	function getCharacter()
		return script.Parent;
	end

	function getPlayer()
		return game.Players:GetPlayerFromCharacter(getCharacter());
	end

	function getHumanoid()
		return waitFor( getCharacter(), "Humanoid" );
	end

	function getNearestPlayer( position )
		local Players = game.Players:GetChildren();
		local dist = math.huge;
		local ret = nil;
		for i=1,#Players do
			local Player = Players[i];
			local Character = Player.Character;
			if ( Character ~= nil ) then
				local Root = Character:FindFirstChild("HumanoidRootPart");
				if ( Root ~= nil ) then
					local t = (position - Root.Position).magnitude;
					if ( t < dist ) then
						dist = t;
						ret = Player;
					end
				end
			end
		end

		return ret;
	end

	local RootLimbData = {
		{
			["WeldTo"]			= "LowerTorso",
			["WeldRoot"]		= "HumanoidRootPart",
			["AttachmentName"]	= "Root",
			["NeedsCollider"]	= false,
			["UpperAngle"]		= 10
		},
		{
			["WeldTo"]			= "UpperTorso",
			["WeldRoot"]		= "LowerTorso",
			["AttachmentName"]	= "Waist",
			["ColliderOffset"]	= CFrame.new(0, 0.5, 0),
			["UpperAngle"]		= 0
		},
		{
			["WeldTo"]			= "Head",
			["WeldRoot"]		= "UpperTorso",
			["AttachmentName"]	= "Neck",
			["ColliderOffset"]	= CFrame.new(),
			["UpperAngle"]		= 20
		},
		{
			["WeldTo"]			= "LeftUpperLeg",
			["WeldRoot"]		= "LowerTorso",
			["AttachmentName"]	= "LeftHip",
			["ColliderOffset"]	= CFrame.new(0, -0.5, 0)
		},
		{
			["WeldTo"]			= "RightUpperLeg",
			["WeldRoot"]		= "LowerTorso",
			["AttachmentName"]	= "RightHip",
			["ColliderOffset"]	= CFrame.new(0, -0.5, 0)
		},
		{
			["WeldTo"]			= "RightLowerLeg",
			["WeldRoot"]		= "RightUpperLeg",
			["AttachmentName"]	= "RightKnee",
			["ColliderOffset"]	= CFrame.new(0, -0.5, 0)
		},
		{
			["WeldTo"]			= "LeftLowerLeg",
			["WeldRoot"]		= "LeftUpperLeg",
			["AttachmentName"]	= "LeftKnee",
			["ColliderOffset"]	= CFrame.new(-0.05, -0.5, 0)
		},
		{
			["WeldTo"]			= "RightUpperArm",
			["WeldRoot"]		= "UpperTorso",
			["AttachmentName"]	= "RightShoulder",
			["ColliderOffset"]	= CFrame.new(0.05, 0.45, 0.15),
		},
		{
			["WeldTo"]			= "LeftUpperArm",
			["WeldRoot"]		= "UpperTorso",
			["AttachmentName"]	= "LeftShoulder",
			["ColliderOffset"]	= CFrame.new(0, 0.45, 0.15),
		},
		{
			["WeldTo"]			= "LeftLowerArm",
			["WeldRoot"]		= "LeftUpperArm",
			["AttachmentName"]	= "LeftElbow",
			["ColliderOffset"]	= CFrame.new(0, 0.125, 0),
			["UpperAngle"]		= 10
		},
		{
			["WeldTo"]			= "RightLowerArm",
			["WeldRoot"]		= "RightUpperArm",
			["AttachmentName"]	= "RightElbow",
			["ColliderOffset"]	= CFrame.new(0, 0.125, 0),
			["UpperAngle"]		= 10
		},
		{
			["WeldTo"]			= "RightHand",
			["WeldRoot"]		= "RightLowerArm",
			["AttachmentName"]	= "RightWrist",
			["ColliderOffset"]	= CFrame.new(0, 0.125, 0),
			["UpperAngle"]		= 0
		},
		{
			["WeldTo"]			= "LeftHand",
			["WeldRoot"]		= "LeftLowerArm",
			["AttachmentName"]	= "LeftWrist",
			["ColliderOffset"]	= CFrame.new(0, 0.125, 0),
			["UpperAngle"]		= 0
		},
		{
			["WeldTo"]			= "LeftFoot",
			["WeldRoot"]		= "LeftLowerLeg",
			["AttachmentName"]	= "LeftAnkle",
			["NeedsCollider"]	= false,
			["UpperAngle"]		= 0
		},
		{
			["WeldTo"]			= "RightFoot",
			["WeldRoot"]		= "RightLowerLeg",
			["AttachmentName"]	= "RightAnkle",
			["NeedsCollider"]	= false,
			["UpperAngle"]		= 0
		},
	}

	local RootPart = nil;
	local MotorList = {};
	local GlueList = {};
	local ColliderList = {};

	function deactivate()
		print("Unragdolling");
		if ( RootPart == nil ) then
			return;
		end

		-- Move to Players Location
		local UpperTorso = getCharacter():FindFirstChild("UpperTorso");
		if ( UpperTorso ~= nil ) then
			UpperTorso:SetNetworkOwner(nil);
			RootPart.CFrame = UpperTorso.CFrame;
		end

		-- Replace Motors
		for i=1,#MotorList do
			local MotorData = MotorList[i];
			local PartTo = MotorData[1];
			local Motor = MotorData[2];
			Motor.Parent = PartTo;
		end

		-- Remove Glues
		for i=1,#GlueList do
			GlueList[i]:Destroy();
		end

		-- Remove Colliders
		for i=1,#ColliderList do
			ColliderList[i]:Destroy();
		end

		-- Replace Humanoid Stuff
		getHumanoid().PlatformStand = false;
		RootPart.Parent = getCharacter();

		-- Restart
		MotorList = {};
		GlueList = {};
		RootPart = nil;
	end

	function activate()
		print("Ragdolling");
		local Character = getCharacter();
		local Humanoid = getHumanoid();
		local HumanoidRoot = script.Parent:FindFirstChild("HumanoidRootPart");
		if ( HumanoidRoot == nil ) then
			print("Cannot create ragdoll");
			return;
		end
		local Position = script.Parent.HumanoidRootPart.Position;
		Humanoid.PlatformStand = true;

		-- Handle death specific ragdoll. Will Clone you, then destroy you.
		local RagDollModel = Character;
		if ( (Humanoid.Health <= 0) and script.ActivateOnDeath.CloneAndDestroy.Value ) then
			Character:FindFirstChild("HumanoidRootPart"):Destroy();
			Character.Archivable = true;
			RagDollModel = Character:Clone();
			RagDollModel.Name = "RagDoll";

			local t = RagDollModel:GetChildren();
			for i=1,#t do
				local t2 = t[i];
				if ( t2:IsA("Script") or t2:IsA("LocalScript") ) then
					t2:Destroy();
				end
			end

			spawn(function()
				wait();
				RagDollModel.Humanoid.PlatformStand = true;
				game.Debris:AddItem(RagDollModel, script.ActivateOnDeath.CloneAndDestroy.Delay.Value);
			end)

			RagDollModel.Humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None;
			RagDollModel.Humanoid.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOff;
			RagDollModel.Humanoid.Health = 0;
			RagDollModel.Parent = game.Workspace;

			local RagDollPointer = Instance.new("ObjectValue");
			RagDollPointer.Value = RagDollModel;
			RagDollPointer.Name = "RagDoll";
			RagDollPointer.Parent = Character;
		end

		-- Reglue The Character
		for i=1,#RootLimbData do
			local limbData = RootLimbData[i];
			local partName = limbData["WeldTo"];
			local weldName = limbData["WeldRoot"];
			local PartTo = RagDollModel:FindFirstChild(partName);
			local WeldTo = RagDollModel:FindFirstChild(weldName);

			if ( PartTo ~= nil and WeldTo ~= nil ) then
				if ( RagDollModel ~= nil ) then
					if ( script.ApplyRandomVelocity.Value ) then
						local scale = script.ApplyRandomVelocity.Force.Value;
						local vecX = (math.random()-math.random())*scale;
						local vecY = (math.random()-math.random())*scale;
						local vecZ = (math.random()-math.random())*scale;
						PartTo.Velocity = PartTo.Velocity + Vector3.new(vecX, vecY, vecZ);
					end
					PartTo.Parent = RagDollModel;
				end
				-- Create New Constraint
				local UpperAngle = limbData["UpperAngle"];
				local Joint = Instance.new("BallSocketConstraint");
				if ( (UpperAngle ~= nil and UpperAngle == 0) or (script.WeldHead.Value and partName == "Head") ) then
					Joint = Instance.new("HingeConstraint");
					Joint.UpperAngle = 0;
					Joint.LowerAngle = 0;
				end
				Joint.Name = limbData["AttachmentName"];
				Joint.LimitsEnabled = true;
				Joint.Attachment0 = PartTo:FindFirstChild(Joint.Name .. "RigAttachment");
				Joint.Attachment1 = WeldTo:FindFirstChild(Joint.Name .. "RigAttachment");
				Joint.Parent = PartTo;
				GlueList[#GlueList+1] = Joint;
				if ( UpperAngle ~= nil ) then
					Joint.UpperAngle = UpperAngle;
				end

				-- Destroy the motor attaching it
				local Motor = PartTo:FindFirstChildOfClass("Motor6D");
				if ( Motor ~= nil ) then
					if ( Humanoid.Health <= 0 ) then
						Motor:Destroy();
					else
						MotorList[#MotorList+1] = { PartTo, Motor };
						Motor.Parent = nil;
					end
				end

				-- Create Collider
				local needsCollider = limbData["NeedsCollider"];
				if ( needsCollider == nil ) then
					needsCollider = true;
				end
				if ( needsCollider ) then
					local B = Instance.new("Part");
					B.CanCollide = true;
					B.TopSurface = 0;
					B.BottomSurface = 0;
					B.formFactor = "Symmetric";
					B.Size = Vector3.new(0.7, 0.7, 0.7);
					B.Transparency = 1;
					B.BrickColor = BrickColor.Red();
					B.Parent = RagDollModel;
					local W = Instance.new("Weld");
					W.Part0 = PartTo;
					W.Part1 = B;
					W.C0 = limbData["ColliderOffset"];
					W.Parent = PartTo;
					ColliderList[#ColliderList+1] = B;
				end
			end
		end

		-- Destroy Root Part
		local root = Character:FindFirstChild("HumanoidRootPart");
		if ( root ~= nil ) then
			RootPart = root;
			if ( Humanoid.Health <= 0 ) then
				RootPart:Destroy();
			else
				RootPart.Parent = nil;
			end
		end	

		-- Delete all my parts if we made a new ragdoll
		if ( RagDollModel ~= Character ) then
			print("Deleting character");
			local children = Character:GetChildren();
			for i=1,#children do
				local child = children[i];
				if ( child:IsA("BasePart") or child:IsA("Accessory") ) then
					child:Destroy();
				end
			end
		end

		-- Give player physics
		if ( script.GivePlayerPhysics.Value ) then
			local PlayerPhysics = getPlayer();
			if ( script.GivePlayerPhysics.ForceNearestPlayer.Value ) then
				PlayerPhysics = getNearestPlayer( Position );
			end

			local Children = RagDollModel:GetChildren();
			for i=1,#Children do
				local Child = Children[i];
				if ( Child:IsA("BasePart") ) then
					Child:SetNetworkOwner(PlayerPhysics);
				end
			end
		end

		-- Copy plugins into ragdoll
		local Plugins = script.Plugins:GetChildren();
		for i=1,#Plugins do
			local Plugin = Plugins[i];
			local Copy = Plugin:Clone();
			if ( Copy:IsA("Script") ) then
				Copy.Disabled = false;
			end
			Copy.Parent = RagDollModel;
		end
	end

	-- Wait for torso (assume everything else will load at the same time)
	waitFor( getCharacter(), "UpperTorso" );

	-- Activate when we die.
	getHumanoid().Died:Connect(function()
		if ( script.ActivateOnDeath.Value ) then
			script.Activate.Value = true;
		end
	end);

	-- Activate when setting is checked.
	script.Activate.Changed:Connect(function(value)
		if ( value ) then
			activate();
		else
			deactivate();
		end
	end);

	-- Activate it on start.
	if ( script.Activate.Value ) then
		activate();
	end
elseif num == 4 then
	wait(3)
	script.Parent.Humanoid.Died:Connect(function()
		local Children = script.Parent:GetChildren()
		for i = 1, #Children do
			Children[i].Transparency = 1
		end
	end)
	gold = workspace["R15 Dummy"]
	local Children = game.workspace["R15 Dummy"]:GetChildren()
	for i = 1, #Children do
		script.Parent.Humanoid.Died:Connect(function()
			Children[i].Position = script.Parent.UpperTorso.Position
			wait (1)
			Children[i].Anchored = false
		end)
	end
elseif num == 5 then
	wait(3)
	script.Parent.Humanoid.Died:Connect(function()
		local Children = script.Parent:GetChildren()
		for i = 1, #Children do
			Children[i].Transparency = 1
		end
	end)
	gold = workspace.Anvil
	script.Parent.Humanoid.Died:Connect(function()
		workspace.Anvil.Position = script.Parent.UpperTorso.Position
		wait (1)
		workspace.Anvil.Anchored = false
	end)
elseif num == 6 then
	local hum = script.Parent:WaitForChild("Humanoid")
	local anim = hum:LoadAnimation(script:FindFirstChildOfClass("Animation"))
	anim:Play()
end

And im an idiot. I didn’t turn on API services. My fault.

@avwzz
Okay the data store works now, but the kills don’t register.

Do I put your first script in every weapon?

Yeah, put it inside of every weapon script.