Skip to content

Commands

Commands are how players talk to your plugin, so almost every plugin has some. You've already made a few, but none of them cared about what the player typed after the command. In this lesson you'll learn to read that, and you'll finish with a /heal that can heal you, heal another player, and even work from the console.

Part 1: Read what the player typed

Everything typed after the command name is called the arguments. Try this command to see them:

main.lua
plugin.addCommand({
    name = "echo",
    description = "Show what you typed",
    usage = "/echo <words>"
}, function(event)
    local sender = event.getSender()
    local args = event.getArgs()
    sender:sendMessage("You typed " .. #args .. " word(s).")
    sender:sendMessage("The first word was: " .. tostring(args[1]))
end)

event.getArgs() gives you the arguments as a list with one word in each spot. If someone types /echo hello there, the list holds hello and there. Putting # in front of the list counts how many words it holds, and args[1] is the first word, because Lua starts counting at 1 instead of 0.

If the player types nothing, args[1] is nil, which is Lua's way of saying "there's nothing here". The tostring part turns nil into text, so the message can still be sent.

Try /echo hello there and then just /echo to see both cases.

Part 2: Player or console?

Commands can be run by players, by the console, and by command blocks, so it's worth knowing who you're dealing with:

main.lua
plugin.addCommand({
    name = "whoami",
    description = "Tell me who ran this command",
    usage = "/whoami"
}, function(event)
    local sender = event.getSender()
    if event.isPlayerSender() then
        sender:sendMessage("You are a player.")
    else
        sender:sendMessage("You are not a player, so you're probably the console.")
    end
end)

event.isPlayerSender() is true when a player ran the command and false otherwise. This is why the /heal from earlier didn't work in the console: the console isn't a player, so it has no health to fill. Try /whoami in game and then from the server console.

Part 3: Find another player

To act on a different player, you need to look them up by name:

main.lua
plugin.addCommand({
    name = "isonline",
    description = "Check if a player is online",
    usage = "/isonline <player>",
    minArgs = 1,
    maxArgs = 1
}, function(event)
    local sender = event.getSender()
    local args = event.getArgs()
    local target = plugin.getServer():getPlayer(args[1])
    if target then
        sender:sendMessage(target:getName() .. " is online!")
    else
        sender:sendMessage("That player isn't online.")
    end
end)

plugin.getServer() gives you the server, and :getPlayer(name) looks for an online player with that name. If it finds one you get the player, and if not you get nil. That's why if target then works: a player counts as "yes" and nil counts as "no".

minArgs = 1 and maxArgs = 1 tell LuaCord to check the number of arguments for you. If someone types /isonline with no name, or with two names, LuaCord replies with an error message and your function never runs.

Dot or colon, again

plugin.getServer() uses a dot because plugin belongs to LuaCord. Then :getPlayer(...) uses a colon, because the server comes from Spigot.

Putting it together

Now let's use all three to make a better /heal. Replace your old one with this:

main.lua
plugin.addCommand({
    name = "heal",
    description = "Heal yourself or another player",
    usage = "/heal [player]",
    maxArgs = 1
}, function(event)
    local sender = event.getSender()
    local args = event.getArgs()
    local target = nil

    if args[1] then
        target = plugin.getServer():getPlayer(args[1])
    elseif event.isPlayerSender() then
        target = sender
    end

    if target then
        target:setHealth(20)
        target:sendMessage("You were healed!")
    else
        sender:sendMessage("Couldn't find anyone to heal. Use /heal <player>.")
    end
end)

target is the player we're going to heal, and it starts as nil, which means we haven't picked anyone yet. The first if fills it in. If a name was typed, we look that player up, and if nobody by that name is online it stays nil. If no name was typed and a player ran the command, the target is the sender, so they heal themselves. If no name was typed and it's the console, nobody is picked, so it stays nil there too.

The second if then checks whether we found anyone. If we did, we heal them and tell them. If not, we explain how to use the command.

Try these, and watch what comes back each time:

  • /heal in game heals you.
  • /heal Steve, with a real player's name, heals them.
  • /heal Nobody says it couldn't find anyone.
  • /heal in the console says it couldn't find anyone, since the console isn't a player.
  • /heal Steve in the console works.
  • /heal a b gets LuaCord's too many arguments error.

Quick reference

Command options

This is everything you can put in the table you give to plugin.addCommand. You always need name and description, and the rest are optional.

Option What it does Example
name What players type after the slash name = "heal"
description A short summary of the command. Without one, the command won't register. description = "Heal a player"
usage How to use the command usage = "/heal [player]"
permission Only people with this permission can use the command permission = "myplugin.heal"
minArgs The fewest arguments allowed. LuaCord shows an error if there are fewer. minArgs = 1
maxArgs The most arguments allowed. LuaCord shows an error if there are more. maxArgs = 1
runAsync Runs the command in the background. Most Spigot actions aren't safe there, so leave this off for now. runAsync = false

What the event gives you

Your command function looks like function(event), and this is what you can call on that event.

Call What you get Example
event.getSender() Whoever ran the command. See everything you can do with it. local sender = event.getSender()
event.getArgs() A list of the words typed after the command local args = event.getArgs()
event.getCommand() The name of the command that was used event.getCommand()
event.isPlayerSender() true if a player ran it if event.isPlayerSender() then
event.isConsoleSender() true if the console ran it if event.isConsoleSender() then
event.isBlockSender() true if a command block ran it if event.isBlockSender() then
event.isEntitySender() true if an entity ran it, and players count as entities if event.isEntitySender() then

Next up is events.