Timer attempt to index local 'ply' (a nil value)

I have a code i am trying to work on a timer, it is supposed to add one point to the number of proficiency points.


function HumanTimer(ply)
	local up = 1
	Total_Proficiency_Points = Total_Proficiency_Points + up

	for k,v in pairs(player.GetAll()) do
		if ValidEntity(v) && v:IsHuman() then
			v.Prof_Points = v.Prof_Points + up
			--v:SendProfPoints()
		end
	end

	ply.Prof_Points = Total_Proficiency_Points
	--ply:SendProfPoints()
end

But when i tried to add the timer to the sv_round_begin


timer.Create( "Points", 45, 0, HumanTimer, ply )

I get the error in the title, am i doing something terribly wrong (not very familiar with Lua and have never used a timer before) I googled the use of timer.Create and it seemed to be used in that fashion.

I am trying to add 1 point to the value Prof_Points/Total_Proficiency_Points every 45 seconds.

EDIT: I am putting the timer in the sv_round_begin instead of the location of the actual function because i want it to run on roundstart.

ply is nil, it doesn’t exist.
I can think of two reasons
You didn’t define ply, in this case add ply = LocalPlayer() or replace ply with LocalPlayer()
Or you have it defined to LocalPlayer() and call it Serverside.

Both of the codes i linked are serverside. I read in another post i cannot use LocalPlayer on a serverside file, only clientside.

timer doesn’t work like that anymore. [lua]timer.Create( “Points”, 45, 0, function() HumanTimer(ply) end )[/lua]

why are you using ValidEntity instead of IsValid which was removed ages ago?

I am adding to a gamemode, in the shared.lua it says _G.ValidEntity = _G.IsValid, so i went off of that =p

Just tested it for the first time and i am still getting the error that ‘ply’ doesn’t exist.

Found out i didn’t add a variable somewhere, screwed the whole thing up =p Seems to be fine now.

Have you declared ply anywhere?

I was basing it off a function the creator already made, but he declared his elsewhere so i declared mine as well =p Trying to somewhat replicate one of his systems.

Alright…this isn’t working for me keeps giving errors, how would you guys go about making a function that gives +1 to a value every 45 seconds? Using these values.


function HumanPoints(ply)
	Total_Proficiency_Points = Total_Proficiency_Points + 1

	for k,v in pairs(player.GetAll()) do
		if IsValid(v) && v:IsHuman() then
			v.Prof_Points = v.Prof_Points + 1
			--v:SendProfPoints()
		end
	end

	ply.Prof_Points = Total_Proficiency_Points
	--ply:SendProfPoints()
end

This is in a file called sv_humans, i tried calling the timer in the file sv_round_begin, couldn’t get it to work.

[editline]5th October 2013[/editline]

Would it have something to do with the function not being created yet, since it is called before the round officially starts?

Can you show the full code?

The only way ply would not be nil, is if the timer is created inside a function where ply is set.

You can add 1 every 45 seconds by using timer.Create, giving it a name, setting the delay, setting 0 to make it run forever, and setting the function. The function should just update a global variable.

Now, you can use timer.Destroy to kill a named timer, you should do that at the start of a round if your game-mode is round based so that each round is the same.


timer.Create( "Points", 45, 0, function() HumanPoints(ply) -- or function(HumanPoints) ?
	Total_Proficiency_Points = Total_Proficiency_Points + 1

	for k,v in pairs(player.GetAll()) do
		if IsValid(v) && v:IsHuman() then
			v.Prof_Points = v.Prof_Points + 1
			--v:SendProfPoints()
		end
	end

	ply.Prof_Points = Total_Proficiency_Points
	--ply:SendProfPoints()
end )

Something like that? - I am trying to add to the Morbus gamemode made by Remscar. I am trying to make it add 1 to the total number of Proficiency Points to the Humans only, I am also unsure how to SET ply, or else i would have done it =p

I am new to anything Lua based but I can’t learn by reading tutorials, never could. So i decided to make a project out of this and try to create my own functions but I am failing so far =p

[editline]6th October 2013[/editline]

also

ply.Evo_Points = 0
ply.Prof_Points = 0

are set in a sv_player.lua file. (evo points are the points for the aliens system.)

If you want to do it that way, remove HumanPoints(ply) and put ply inside the columns in function()

ply is generally shorthand for Player. are they defined inside a function or how are they defined? Sorry, I’m not too familiar with the game-mode so without full code it’s guesswork.

To answer the ? in the code. you’re correct.

[lua]timer.Create( _name, _delay, _repetitions, _func )

timer.Create( “TheName”, 45, 0, function( )
// Logic
end )[/lua]

Where you’re doing the player.GetAll( ) that’s usually where ply is used, or in a concommand, etc. Do you have a link to download the game-mode, maybe I can help more with it. Increasing a counter every 45 seconds isn’t difficult, but are you trying to add it per individual player, or is there something globally that controls it? Is it pre-defined in the code, or is this 100% your creation?

I am trying to get it to only give the 1 point per 45 seconds to HUMANS, in morbus there is SWARM and BROOD alongside them (like TTT kinda) but I only want to target the humans and give them points, but this is proving to be more difficult than i anticipated with my low skill in Lua =)

[editline]6th October 2013[/editline]

I mostly copied his code and altered values for the majority of the code, with a few things added here and there. I did create my own files to categorize the luas for humans and brood though, but if you were to download it - and set up a timer to increase the Evolution points, instead of Proficiency - it would work the same for the system i am trying to make.

Ok, well you can get rid of this stuff at the top: HumanPoints(ply) – or function(HumanPoints) ?

You have the right idea of needing to network it in the loop. Don’t use ply outside of the loop as it’s not defined. You could change v to ply and it would be “correct”. But, I’m not familiar with how Morbus networks points; so the // Network it somehow line you’ll need to add.

You almost had the timer perfect!

Also, shouldn’t they reset points on death, or is this part of a point shop?

[lua]timer.Create( “Points”, 45, 0, function()
for k,v in pairs(player.GetAll()) do
if IsValid(v) && v:IsHuman() then
v.Prof_Points = v.Prof_Points + 1
–v:SendProfPoints() // Network it somehow
end
end
end )[/lua]

Well on death (usually) they turn into a swarm or brood alien, and the points i use for this system do not link to the other system at all. All i need to do is destroy the timer at the end of the round, after that it resets all values back to 0 automatically once the new round starts.

[editline]6th October 2013[/editline]

K, works now =) Thanks everyone for all the help, learning a lot from trying to make this.