Attempt to index local 'ply' (a nil value)


local AdminTell = function() end

usermessage.Hook("AdminTell", function(msg, ply)
    timer.Remove("DarkRP_AdminTell")
    local Message = msg:ReadString()
    local Name = ply():Name()

    AdminTell = function()
        draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
        draw.DrawNonParsedText("Announced By: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
        draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
    end

    timer.Create("DarkRP_AdminTell", 10, 1, function()
        AdminTell = function() end
    end)
end)

I’ve googled multiple times searching for the answer and it seems this forum has more recognition with this problem. I decided to make an account and post in hoping to find a direct answer.

What I’m trying to do is get the name to be announced globally and not locally. I’m fairly new to Lua, so judge me all you like! :slight_smile:

Thank you. <3

Also: It would be great if you could post how you got the solution for future references. :cat:

ply is not a function, and you’re treating it as such. You need to define ply and use ply:Name()

Example:



local ply = LocalPlayer()
local Name = ply:Name()


Or you can use:



local Name = LocalPlayer():Name()


Also don’t use user messages as it is deprecated. http://wiki.garrysmod.com/page/Net_Library_Usage

Edit: Nevermind - I guess DarkRP uses usermessages. Thought that was your code. I don’t look much at DarkRP code.

[lua]local Name = ply:Name()[/lua]

Okay, I didn’t explain it correctly. What I am trying to do is display the name of the person that is running the command. If I use LocalPlayer, it will display the name of the person receiving the tellall.

Like he said, though, ply isn’t a function, so you don’t need to have the () after it. Try changing


    local Name = ply():Name()

to


    local Name = ply:Name()

and see if it still happens.

It still doesn’t work.


[ERROR] gamemodes/darkrp/gamemode/modules/hud/cl_hud.lua:217: attempt to index global 'ply' (a nil value)


local AdminTell = function() end

usermessage.Hook("AdminTell", function(msg)
    timer.Remove("DarkRP_AdminTell")
    local Message = msg:ReadString()
    local Name = ply:Name()

    AdminTell = function()
        draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
        draw.DrawNonParsedText("Announced by: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
        draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
    end

    timer.Create("DarkRP_AdminTell", 10, 1, function()
        AdminTell = function() end
    end)
end)

That’s the old code.

This is the new code.


local AdminTell = function() end

usermessage.Hook("AdminTell", function(msg)
    timer.Remove("DarkRP_AdminTell")
    local Message = msg:ReadString()
    local Name = ply():Name()

    AdminTell = function()
        draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
        draw.DrawNonParsedText("Announced by: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
        draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
    end

    timer.Create("DarkRP_AdminTell", 10, 1, function()
        AdminTell = function() end
    end)
end)


[ERROR] gamemodes/darkrp/gamemode/modules/hud/cl_hud.lua:218: attempt to call upvalue 'ply' (a nil value)

You keep trying to use ply but ply is never defined as anything.

How do you define ply? I’m sure I have everything down correctly. Could you give me an example? I’m seriously clueless with this.

You don’t have ply defined. So it’s nil (nothing). Where is the server-side code. Because I assume that by using usermessages, it’s executing a server-side action, and sending the message. So why not attach a WriteEntity and assign it to LocalPlayer() and then in the code you have above, just add



local ply = msg:ReadEntity()


Then you can call the name or you want.

Again, you have to have something like:


local ply = LocalPlayer()

And if that’s calling the incorrect name, you have to do what I said above. Grab the name server-side that toggled to send a message using WriteEntity (server) / ReadEntity (client).

Wait, wait, hold on. In the first post, your code looks like this:


local AdminTell = function() end

usermessage.Hook("AdminTell", function(msg, ply)
    timer.Remove("DarkRP_AdminTell")
    local Message = msg:ReadString()
    local Name = ply():Name()

    AdminTell = function()
        draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
        draw.DrawNonParsedText("Announced By: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
        draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
    end

    timer.Create("DarkRP_AdminTell", 10, 1, function()
        AdminTell = function() end
    end)
end)

but in your newer post it looks like this:


local AdminTell = function() end

usermessage.Hook("AdminTell", function(msg)
    timer.Remove("DarkRP_AdminTell")
    local Message = msg:ReadString()
    local Name = ply():Name()

    AdminTell = function()
        draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
        draw.DrawNonParsedText("Announced by: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
        draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
    end

    timer.Create("DarkRP_AdminTell", 10, 1, function()
        AdminTell = function() end
    end)
end)

What happened to the “ply” argument in your function? Try replacing your code with this:


local AdminTell = function() end

usermessage.Hook("AdminTell", function(msg, ply)
    timer.Remove("DarkRP_AdminTell")
    local Message = msg:ReadString()
    local Name = ply:Name()

    AdminTell = function()
        draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
        draw.DrawNonParsedText("Announced by: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
        draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
    end

    timer.Create("DarkRP_AdminTell", 10, 1, function()
        AdminTell = function() end
    end)
end)

Using your original code,
[lua] local AdminTell = function() end

usermessage.Hook(“AdminTell”, function(msg, ply)
timer.Remove(“DarkRP_AdminTell”)
local Message = msg:ReadString()
local ply = LocalPlayer() //This is where you define ply as the player.
local Name = ply:Name()
//or you could just use: local Name = LocalPlayer():Name() instead of the last 2 locals.

AdminTell = function()
    draw.RoundedBox(4, 10, 10, Scrw - 20, 110, colors.darkblack)
    draw.DrawNonParsedText("Announced By: " .. Name, "Default", Scrw / 2 + 10, 10, colors.white, 1)
    draw.DrawNonParsedText(Message, "ChatFont", Scrw / 2 + 10, 90, colors.brightred, 1)
end

timer.Create("DarkRP_AdminTell", 10, 1, function()
    AdminTell = function() end
end)

end)
[/lua]

Didn’t I try explaining this to him from the beginning?

You did, but sometimes people need to see it done to learn. He may not have understood what you you meant without seeing it.

Glad someone got it across to him lol thanks.

Idk why you are suggesting he should use LocalPlayer()…

Using LocalPlayer() will make it so that the player receiving the tellall is also displayed as the person announcing it.

>Player1 receives tellall, says announced by: Player1
>Player2 receives tellall, says announced by: Player2

Here’s the serversided file where your usermessage is started: https://github.com/FPtje/DarkRP/blob/11faa5f854f5bc28e079616c6517887d3190ecdc/gamemode/modules/hud/sv_admintell.lua#L29-L40

You could write the entity like I.AM.Richard said, like this:



umsg.Start("AdminTell")
            umsg.String(args) --the message
            umsg.Entity(ply)   --the player
umsg.End()


and in your clientside file, you would add it like this



local Message = msg:ReadString()
local plyName = msg:ReadEntity():Name()


Now plyName is the name of the player who called the tellall. You probably wanna do some error checking and see if it’s a player who sent the tellall and not console.

Idk what Subject_Alpha was going for but it made no sense

Thanks a lot! I’m still trying to learn the variables slowly at a time. It’s not anything like Java, that’s for sure. >.<

Why has nobody acknowledged the fact that he is using user messages?

Do not use what he suggested to you. That is depreciated. Use net messages.

Use this instead



--[Server Side]
net.Start("AdminTell")
	net.WriteString(args) -- Teh Message
	net.WriteEntity(ply) -- And The Player
net.Broadcast()

--[ClientSide Side]

net.Receive("AdminTell", function()
	local Message = net.ReadString()
	local ply = net.ReadEntity():Name()
end)


I did post in my original about the use of net messages here. However, I said nevermind to the original post with it because it was stock darkrp code. I doubt he’s going to re-write the code just to convert.

But why Jeff turned around and used it again, no idea. Also Jeff, I did post in my original answers a method of using netlib for pulling it if the script did end up reporting back the calling LocalPlayer(). But people need to pay attention to the wiki about what is deprecated and umsgs have been discussed on here over and over.