My number value isn't updating, how do I fix it? - lua

So I was trying to make it so that every second the loop changed the value of the number value but it keeps returning either nil or 0. I tried adding it as a local value that affected the actual value and a few other things like making it a string instead and replacing the string with a new one but that still didn't return anything. This is my code now and it's the code that returns 0 and not nil or an error.
local SecondsAfterGameStart = game.ServerStorage.SecondsAfterGameStart.Value
while true do
wait(0.1)
SecondsAfterGameStart = SecondsAfterGameStart + 1
end

When you save SecondsAfterGameStart.Value into a local variable, you are not keeping a reference to the original NumberValue object, you are copying its value into the local variable. Later in your while loop, you are accessing and modifying a variable and not the original object, so changes are never saved back to the object in the ServerStorage.
So, instead of saving the Value, hold onto the entire NumberValue itself. Then you can update the Value directly.
local SecondsAfterGameStart = game.ServerStorage.SecondsAfterGameStart
while true do
wait(0.1)
SecondsAfterGameStart.Value = SecondsAfterGameStart.Value + 1
end

Related

Unable to assign property CFrame. CoordinateFrame expected, got Vector3

So, I was trying to make that it scans everything in user's body and if it's called humanoidRootPart, it will save the the position. Instead of it i got the error 'Unable to assign property CFrame. CoordinateFrame expected, got Vector3'
for i,v in pairs(plrChar:GetChildren()) do
if v.Name == "HumanoidRootPart" then
game:GetService('ReplicatedStorage').savedPos.Value = Vector3.new(v.Position)
end
end
If savedpos is a CFrame Value, instead of just assigning it's Value to "Vector3.new(v.Position)" (which is already redundant as "Position" is already a Vector3) you should use "CFrame.new(v.Position)"

Roblox Lua - attempt to index nil with 'stats' (leaderstats)

i want to make this, when the baseFinal is touched by a block (Bloque) it gives you money and the block is destroyed. it gives me an error: attempt to index nil with 'stats'
local base = script.Parent.Base
local baseFinal = script.Parent.Final
local plr = game.Players.LocalPlayer
baseFinal.Touched:Connect(function(hit)
if hit.Name == "Bloque" then
wait(0.6)
plr.stats.Value = plr.stats.Value + 5 // here is the error
hit:Destroy()
end
end)
The error is telling you that the plr variable is undefined or nil.
Since this code is running in a Script, the issue is how you are accessing the Player object. See the documentation for Players.LocalPlayer :
This property is only defined for LocalScripts (and ModuleScripts required by them), as they run on the client. For the server (on which Script objects run their code), this property is nil.
The way to fix this is to access the Player object another way. One way is to connect to the Players.PlayerAdded signal.
local base = script.Parent.Base
local baseFinal = script.Parent.Final
local connections = {}
game.Players.PlayerAdded:Connect( function(plr)
-- listen for Players to touch the block
local connection = baseFinal.Touched:Connect( function(hit)
if hit.Name == "Bloque" then
wait(0.6)
plr.stats.Money.Value = plr.stats.Money.Value + 5
hit:Destroy()
end
end)
-- hold onto the connection to clean it up later
connections[plr] = connection
end)
-- clean up when the Player leaves
game.Players.PlayerRemoving:Connect( function(plr)
connections[plr]:Disconnect()
end)
This is most likely because when you are trying to reference a value, you must put .Value after it in order to change the value itself. Assuming you have a stats folder, you should use plr.stats.Value.Value instead.
Next time, please show us your object structure so we have a better understanding of what the error is. Thanks.

Lua: Can I use a for loop to process all 'sometimes-nil' values in an array?

I have the following code:
local overrideNode = xml.first(rootFromOverrideXML,"nodes/node[#identifier='"..nodeIdentifier.."']")
local overrideRefNode
if (elementRef) then overrideRefNode = xml.first(rootFromOverrideXML,"nodes/node[#identifier='"..elementRef.."']") end
This results in overrideNode and overrideRefNode being nil in most cases. But either can be non-nil when something is found in the xml.
I have to handle overrideRefNode before overrideNode, so I wrote:
for _,nodeVar in ipairs {overrideRefNode, overrideNode} do
if (nodeVar) then
But it turns out that when both are non-nil, both are processed (two runs of the for loop, correct), but when overrideRefNode (the first) is nil, overrideNode (the second) is never processed (incorrect), so zero runs of the for loop, while it should be one run.
How do I loop over a set of two strings, either of which can be nil, but every non-nil must be processed?
A workaround is
local overrides = {}
overrides[1] = overrideRefNode
overrides[2] = overrideNode
for i = 1,2 do
local nodeVar = overrides[i]
-- Do some stuff here with nodeVar
end

Lua userdata pass by reference - local functions in different files

I have 2 Lua files, namely mydialog.lua and rangecontrol.lua. The code in mydialog.lua is as follows:
local function mydialog()
--omitted
local wb_responses=activeobj() --wb_responses points to the current activeobj(), say Obj1
UI.m_txt=sys.rangetextcontrol(UI.sbSizerInput:GetStaticBox() ,wb_responses) --wb_responses is passed by reference
--Selection event happened
--Omitted
--If clicked on a checkbox execute the following line
print(wb_responses) --Still prints Obj1 instead of Obj2
end
sys.tools.mydialog=mydialog
Code in rangecontrol.lua:
local function rangetextcontrol(parent, wb_txtBox)
local m_txtBox=nil
m_txtBox=wx.wxTextCtrl( parent, wx.wxID_ANY, "", wx.wxDefaultPosition, wx.wxDefaultSize, 0 )
local function GetRange()
wb_txtBox=activeobj()
local ws=activeobj():cur()
local rng=ws:selection()
if (rng==nil) then return end
m_txtBox:SetValue(rng:tostring()) -- Here wb_txtBox correctly refers to Obj2
end
m_txtBox:Connect( wx.wxEVT_LEFT_DOWN, function(event)
wb_txtBox=activeobj() --Current activeobj() changed, say Obj2
local ws=wb_txtBox:cur()
ws:connect(GetRange) --There is a selection event, call GetRange
event:Skip()
end)
return m_txtBox
end
sys.rangetextcontrol=rangetextcontrol
Briefly what happens:
1) A dialog starts and it has a textcontrol (there might be several textcontrols)
2) When user makes a selection from an object, the text box is populated.
3) My goal is to track from which object the selection is made.
My confusion: Although I pass wb_responses a userdata type, which should be passing by reference to the rangetextcontrol which keeps track of the selections, it seems that wb_responses never changes since it always prints info on Obj1. Therefore, I assume it always points to the first object that it has been initialized with in mydialog.lua. What could I be doing/thinking wrong?
local function mydialog()
--omitted
local wb_responses=activeobj() --wb_responses points to the current activeobj(), say Obj1
UI.m_txt=sys.rangetextcontrol(UI.sbSizerInput:GetStaticBox() ,wb_responses) --wb_responses is passed by reference
--Selection event happened
print(wb_responses) --Still prints Obj1 instead of Obj2
end
You print wbresponses right after you initialize it. How should it change its value? There won't be any event handling between those two lines of code.

attempt to call a nil value

for i = 1, groupA:getNumChildren() do
local sprite = groupA:getChildAt(i)
if cute.anim[1]:collidesWith(sprite) then
youLoose()
end
end
local function youLoose()
local font3 = TTFont.new("billo.ttf", 20, " 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,?")
local text7 = TextField.new(font2, "gameover")
text7:setPosition(200, 100)
stage:addChild(text7)
GameLost = Bitmap.new(Texture.new("gameover.jpg"))
Background : removeFromParent()
groupA : removeFromParent()
stage: addChild(GameLost)
alert()
end
It gives an error that says 'attempt to call global youLoose (a nil value), where am I doing it wrong?
Note that collideswith is not the same as collidesWith; if that error you posted is correct, then you posted code that is different from what you are using. It could be that the method really is called collidesWith (it appears to be if it is the one from sprite1), but you used collideswith. Alternatively, if the code posted is what you used, then the error is likely attempt to call collideswith(a nil value), so cute.anim[1] is not a sprite1 object, but it is not nil either otherwise the error would be different.
Once you have fixed this, you'll notice that youLoose is defined after that for loop, when you call youLoose() it is not yet defined. You're going to have to move the local function youLoose() function to before the loop. Because the loop is not itself in a function, but is at module level, it gets executed before any following code, so any functions (local or global) that are used in the loop must be defined before the loop.
Note that "loose" does not mean the same as "lose". Check Grammar-monster to see difference. Probably everywhere you have the word "loose" you should change to "lose".

Resources