Custom Health system does not work

Hello! I am currently attempting to create an alternative to the default Roblox health value and am having trouble creating it.

I would like it to have these features, which I have programmed already: mostly

  • Accesible settings from within the ModuleScript
  • Kicks if player is over a set health value (Defaults to 100)
  • Have lighting and screen effects if a player is at a certain health
  • When the value hits zero, to ragdoll, heal and send them back to spawn

My current issues with this are the following:

  • My LocalScript that I have for testing it does call the functions.
  • I am confused by my functions and how I can get them to run like this: Pulse:AddHealth(30)
  • My while true do statement for if they have Kick if over Max Health is turned on
  • I’m not sure whether or not it has an individual PulseValue for each player

I have tried multiple things including changing functions from local to global to no avail. Additionally, I have read multiple posts on the DevForum and articles on the DevHub.

Here are my current scripts:

MainModule
local Pulse = {}

--SETTINGS
MaxHealth = 100 -- Change to your own maximum health
StartHealth = 100 -- Change to your own default start health
KickIfOverMax = true -- Change to either true or false if they will be kicked if they are over the maximum value

--CODE
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Lighting = game:GetService("Lighting")
local player = game.Players.LocalPlayer
local PulseValue = script.Health
PulseValue.Value = StartHealth


while KickIfOverMax = true do
	wait(1)
	if PulseValue.Value > MaxHealth then 
		player:Kick("You have been kicked from this game for having a health value of more than 100. If this was unintentional, you can appeal your ban and submit a bug report in our communications server so our developers can fix it.")
	end
end




function AddHealth(NumVal)
	local result = math.clamp(PulseValue.Value + NumVal, 0, 100)
	return result
end

function ReduceHealth(NumVal)
	local result = math.clamp(PulseValue.Value - NumVal, 0, 100)
	return result
end

function Kill(NumVal)
	local result = PulseValue.Value - 100
	return result
end

function SetHealth(NumVal)
	local result = PulseValue.Value = NumVal
	return result
end

if PulseValue.Value > 90 then
	print("full health works")
	Lighting.Brightness	= 2
elseif PulseValue.Value > 40 then
	print("medium health works")
	Lighting.Brightness = 1.5
elseif PulseValue.Value > 10 then
	print("very low health works")
	Lighting.Brightness = 0.8
elseif PulseValue.Value < 1 then
	print("death works")
end
return Pulse
LocalScript
local pulse = require(game.ReplicatedStorage.Pulse.MainModule)

wait(5)
pulse:ReduceHealth(30)
wait(4)
pulse:AddHealth(30)
wait(4)
pulse:Kill()

If you can also suggest ways to secure and optimize it, or just tips on my code in general, I’d really appreciate it.

this is my first ever module. please take it with a grain of salt.

You should use this for the Module Script functions:

local Pulse = {}

function Pulse.FunctionName()
   -- Code
end

return Pulse
1 Like

Thanks for the suggestion. Would this allow me to use the functions like:
Pulse:AddHealth(30)
?

Yes, but I suggest using this method:

ModuleScript:

local Pulse = {}

function Pulse.FunctionName()
   -- Code
end

return Pulse

For the LocalScript:

Pulse.FunctionName(30)
1 Like

Any other suggestions for my code or any fixes?

1 Like

You should use == here and not =

1 Like

Thanks for helping I really appreciate it :slight_smile:

1 Like

You don’t even need == true you can just have

while KickIfOverMax do

This will run if the value is true.

1 Like

Thanks for the suggestion.

Any other suggestions like ways to make a value for each player or secure it?

I really need some help with creating a value for each player. If someone could help, It’d be great :slight_smile:

I wonder what your project’s layout is. It seems to me that the NumberValue is inaccessible to server scripts.

Player stats should only be handled on the server as the client can do whatever they want with their values.

Also, the methods as they are right now don’t exist in the pulse table.

function pulse:ReduceHealth(NumVal)
    --stuff
end

I used : here as it is the standard way to call methods in Lua.

pulse:ReduceValue(20)

I don’t know how to make a value for each of player and manage it on the server. As you can see in this topic and others, I’ve been trying.

Whenever I tried to use a colon it gives me an error?

Also, it’s just code atm, no real layout. This is my first ever module and I really want to open-source it but I don’t think I have the skills to make it good enough to open-source.

Here’s a link to the GitHub repository where I keep the updated code:
https://github.com/versoftltd/pulse

The values for each player should be created server side in a server script.

As for the Colon error its because when calling a function like that, it passes the calling Object/Instance into the function.

local pulse = {}

function pulse.ReduceHealth(NumVal)

end

return pulse

now calling these functions below

local Pulse = require("Location To Pulse Module")

Pulse.ReduceHealth(20)    --Passes 20 into NumVal to be reduced from player health
Pulse:ReduceHealth()      --Passes Pulse Object/Instance into NumVal
Pulse:ReduceHealth(20)    --Passes Pulse Object/Instance into NumVal

Be careful when choosing which notation to use

There are 2 ways you could do this on a server. You can handle it as a library or a class.

If you want it as a library, then you can call all the functions above with the Player who’s health you want to set as the first argument.

If you want it as a class, then you’ll create a new Pulse object for each player and then call all those functions as methods.

Here’s an example of the first way:

local modulePulse = {}

local servicePlayers = game:GetService("Players")

--Initialize
local listForPlyr = {}
local loadplayer = function (plyr)
    if listForPlyr[plyr] then
        return
    end

    local pulse = Instance.new("NumberValue")
    pulse.Name = "Pulse"
    pulse.Value = 100

    listForPlyr[plyr] = pulse
end
servicePlayers.PlayerAdded:Connect(loadplayer)
for _,plyr in ipairs(servicePlayers:GetPlayers()) do
    loadplayer(plyr)
end
servicePlayers.PlayerRemoving:Connect(function(plyr)
    listForPlyr[plyr] = nil
end)

--methods
function modulePulse:ReduceHealth(plyr,NumVal)
    local pulse = listForPlyr[plyr]
    if not pulse then
        error("Pulse is not loaded for player "..plyr.Name)
    end
    pulse.Value = pulse.Value-NumVal
    if pulse.Value<=0 then
        --kill
    end
end


--return
return modulePulse

Then you call it from other scripts as:

local modulePulse = require("Path to the module")

modulePulse:ReduceHealth(player,20)

I’m very confused by this code. Could you break it down?

Also, how would i make my KickIfOverMax function work?

while KickIfOverMax do
	wait(1)
	if PulseValue.Value > MaxHealth then 
		LocalPlayer:Kick("You have been kicked from this game for having a health value of more than 100. If this was unintentional, you can appeal your ban and submit a bug report in our communications server so our developers can fix it.")
	end
end

EDIT: Also, do I just add my default code into the function?

The part before --initialize is self-explanatory.

listForPlyr holds NumberValue (Pulse) instances for each player.

The loadplayer function creates a new NumberValue named Pulse for a given player (plyr). The first if statement checks if the player was already loaded to avoid creating duplicates.
The NumberValue instance is created, named Pulse, given a default value (100) and parented to the player.

The loadplayer function is connected to PlayerAdded to fire each time a player joins.

loadplayer is called for every already existing player since the module only starts the first time it was required, so anyone who joined before that will have to be loaded.

A function that removes the Pulse object is connected to PlayerRemoving to avoid memory leaks.

The modulePulse:ReduceHealth method takes plyr and NumVal as its arguments (also a hidden self argument, but it’s not used here). plyr is the player you want to change the health for and NumVal is the amount of health you wanr to reduce.

pulse is a NumberValue instance that’s parented to the player. All of them are stored in the listForPlyr table as said before.

If pulse value does not exist, throw an error to avoid bugs.

Decrease its value by the given NumVal amount.

If health is below 0 then kill the player.

Finally, return the module.

KickIfOverMax will no longer be required as the client cannot change anything on the server’s side.

1 Like

I am having trouble implementing it. Mind submitting a Pull Request on the GitHub repository?
https://github.com/versoftltd/pulse