1

For some reason, my local variables in the module script all seem to be nil, with no exact explanation for it, or solution. Local Script (Stamina bar Script):

local ms = require(game.ReplicatedStorage.ModuleScript)
if not ms then
    
    local ms = require(game.ReplicatedStorage:WaitForChild("ModuleScript"))
    
end

local TW = game:GetService("TweenService")--Get Tween Service

local Staminabar = script.Parent -- Get The Stamina bar

local function UpdateStaminabar() --Stamina Bar Size Change Function
    local stamina = math.clamp(ms.stamina / ms.maxstamina, 0, 1) --Maths
    local info = TweenInfo.new(ms.stamina / ms.maxstamina,Enum.EasingStyle.Linear,Enum.EasingDirection.InOut,0,false,0) --Tween Info
    TW:Create(script.Parent,info,{Size = UDim2.fromScale(ms.stamina, 1)}):Play() -- Create The Tween Then Play It
end

UpdateStaminabar()--Update The Health Bar

ms.stamina:GetPropertyChangedSignal("Value"):Connect(UpdateStaminabar) --Update The Health Bar When The Health Change
ms.maxstamina:GetPropertyChangedSignal("Value"):Connect(UpdateStaminabar) --Update The Health Bar Wheb The MaxHealth Change

LocalScript (Combat Script):

local ms = require(game.ReplicatedStorage.ModuleScript)
if not ms then
    
    local ms = require(game.ReplicatedStorage:WaitForChild("ModuleScript"))
    
end 
local uis = game:GetService("UserInputService")
local cas = game:GetService("ContextActionService")
local rs = game:GetService("ReplicatedStorage")

local events = rs:WaitForChild("Events")
local hitbox = events:WaitForChild("Hitbox")

local plr = game.Players.LocalPlayer
local character = plr.Character
if not character then
    
    plr:WaitForChild("Character")
    
end
local humanoid = character.Humanoid
local animator = humanoid:WaitForChild("Animator")

local idle = animator:LoadAnimation(script:WaitForChild("idle"))
local jab = animator:LoadAnimation(script:WaitForChild("jab"))
local rightcross = animator:LoadAnimation(script:WaitForChild("rightstraight"))
local lefthook = animator:LoadAnimation(script:WaitForChild("lefthook"))
local righthook = animator:LoadAnimation(script:WaitForChild("righthook"))
local swingsfx = script:WaitForChild("Air swing")

local currentPunch = 0
local currentPunch2 = 0
local debounce1 = false
local debounce2 = false

local function onInputBegan(input)
    
    if debounce2 == true then return end
    if ms.stamina <= 0 then return end
    
    
    if input.KeyCode == Enum.KeyCode.Q then
        
        ms.stamina -= 20
        debounce2 = true
        humanoid.WalkSpeed = 0.5
        lefthook:Play()
        swingsfx:Play()
        hitbox:FireServer(Vector3.new(4, 5, 3), Vector3.new(4.5, 1), 7.5, 0.15)
        task.wait(0.5)
        humanoid.WalkSpeed = 10
        lefthook:Stop()
        task.wait(6)
        debounce2 = false
        
    end 
    
    if input.KeyCode == Enum.KeyCode.E then

        ms.stamina -= 20
        debounce2 = true
        humanoid.WalkSpeed = 0.5
        righthook:Play()
        swingsfx:Play()
        hitbox:FireServer(Vector3.new(4, 5, 3), Vector3.new(4.5, 1), 7.5, 0.15)
        task.wait(0.5)
        humanoid.WalkSpeed = 10
        righthook:Stop()
        task.wait(6)
        debounce2 = false

    end 
end

local function punch()
    
    if debounce1 then return end
    
    debounce1 = true
    if currentPunch == 0 then
        
        ms.stamina -= 10
        humanoid.WalkSpeed = 0.6
        jab:Play()
        swingsfx:Play()
        hitbox:FireServer(Vector3.new(4, 5, 3), Vector3.new(5.7, 1), 2.5, 0.15)
        task.wait(0.5)
        humanoid.WalkSpeed = 10
        jab:Stop()
        debounce1 = false
        
    elseif currentPunch == 1 then
        
        ms.stamina -= 10
        humanoid.WalkSpeed = 0.6
        rightcross:Play()
        swingsfx:Play()
        hitbox:FireServer(Vector3.new(4, 5, 3), Vector3.new(5.7, 1), 2.5, 0.15)
        task.wait(0.5)
        humanoid.WalkSpeed = 10
        rightcross:Stop()
        debounce1 = false
        
    elseif currentPunch == 2 then
        
        ms.stamina -= 10
        humanoid.WalkSpeed = 0.6
        jab:Play()
        swingsfx:Play()
        hitbox:FireServer(Vector3.new(4, 5, 3), Vector3.new(5.7, 1), 2.5, 0.15)
        task.wait(0.5)
        humanoid.WalkSpeed = 10
        jab:Stop()
        debounce1 = false
        
    elseif currentPunch == 3 then
        
        ms.stamina -= 10
        debounce2 = true
        humanoid.WalkSpeed = 0.6
        rightcross:Play()
        swingsfx:Play()
        hitbox:FireServer(Vector3.new(4, 5, 3), Vector3.new(5.7, 1), 5, 0.15)
        task.wait(0.5)
        humanoid.WalkSpeed = 10
        rightcross:Stop()
        debounce1 = false
        debounce2 = false
        
    end

    if currentPunch == 3  then
        
        currentPunch = 0
        debounce1 = true
        wait(2)
        debounce1 = false
        
    else
        
        currentPunch += 1
        
    end
    
end

cas:BindAction("Punch", punch, true, Enum.UserInputType.MouseButton1)
uis.InputBegan:Connect(onInputBegan)

ModuleScript:

local info = {}

    local stamina = 100
    local maxstamina = 100
    
return info

I was trying to make a stamina system, together with a stamina bar, but they just refuse to use the locals, and instead print out errors like:

15:00:30.915 Players.Morelval1.PlayerGui.ScreenGui.StaminaBar.Frame.StaminaBar Script:12: attempt to perform arithmetic (div) on nil - Client - StaminaBar Script:12 15:00:32.505 Players.Morelval1.PlayerGui.Main.PunchScript:39: attempt to compare nil <= number - Client - PunchScript:39

I was expecting for the variables to be interacted with, and be used.

2 Answers 2

3
local ms = require(game.ReplicatedStorage.ModuleScript)
if not ms then
    
    local ms = require(game.ReplicatedStorage:WaitForChild("ModuleScript"))    
end

The second ms is local to the if statement. It shadows the first ms. So in case the first require failed you'll store the return value of the second require into the wrong variable.

Remove the local keyword.

local ms = require(game.ReplicatedStorage.ModuleScript)
if not ms then
    
    ms = require(game.ReplicatedStorage:WaitForChild("ModuleScript"))    
end

Or simply

local ms = require(game.ReplicatedStorage.ModuleScript)
         or require(game.ReplicatedStorage:WaitForChild("ModuleScript"))    

Of course you should still check if the second require attempt succeeded befor you proceed.

No to your actual problem.

local info = {}

    local stamina = 100
    local maxstamina = 100
    
return info

You return an empty table here. So any index operation on ms will result in nil.

You want to do this:

local info = {

    stamina = 100,
    maxstamina = 100,
}
    
return info

or

local info = {}

info.stamina = 100
info.maxstamina = 100
    
return info

As stamina and maxstamina need to be fields of the table info, not local variables to your script.

Then the result of your require statement will be the table { maxstamina = 100, stamina = 100 } instead of { }

4
  • Thank you for the answer! Do you know a way I can detect that the value of stamina changed? it tells me I can't refer to numbers with getpropertychangedsignal. Commented Jul 5 at 12:26
  • 1
    you can implement this using the __newindex metamethod in a proxy table. Read this: lua.org/pil/13.4.4.html you'll basically replace info by a proxy table that acts as an interface to your data. when you assign to proxy.stamina proxy's __newindex method will store the value in your data table and call a notification function.
    – Piglet
    Commented Jul 5 at 12:49
  • I can't seem to understand a single thing. So it basically means that I can't simply access the variable change it, and detect when it changes. Commented Jul 5 at 13:40
  • @RelaxGaming, if you can't figure out metamethods, you can always use IntValues and their Changed signal.
    – Kylaaa
    Commented Jul 5 at 17:05
1

The first answer is correct, but if the module is not found, then require will not return nil!

Use this check when loading a module:

local _, ms = pcall(require, game.ReplicatedStorage.ModuleScript) 

if type(ms)~="table" then 
 ms = require( game.ReplicatedStorage:WaitForChild("ModuleScript") )
end

Not the answer you're looking for? Browse other questions tagged or ask your own question.