Skip to content

Config files

A config file lets the person running the server change how your plugin behaves without touching any code. In this lesson you'll learn how to create settings with defaults, read them, change them from code, and update an old config when your plugin changes. You'll finish with a welcome plugin whose message can be changed without opening main.lua.

Part 1: Create settings with defaults

A setting is a name and a value. The name is something like welcome-message, and the value can be text, a number, or true or false. Add this to your main.lua:

main.lua
plugin.onEnable(function()
    config.setDefault("welcome-message", "&aWelcome to the server, {player}!")
    config.setDefault("welcome-enabled", true)
    config.save()
end)

config is always there in your code, like plugin, and it's the place for everything to do with your config file. config.setDefault creates a setting, but only if it doesn't exist yet. That matters, because the next time the server starts, it won't overwrite a value that someone has changed. Then config.save() writes everything to the file. LuaCord doesn't save on its own, so without that line, no file appears.

Restart the server, then look in plugins/ for a folder named after your plugin, which is the name in your plugin.yml. Inside is a file called config.yml, and it looks something like this:

config.yml
welcome-message: '&aWelcome to the server, {player}!'
welcome-enabled: true

This is the file the server owner edits. The {player} part is a placeholder, and in the next part your code will swap it for the player's name.

Another way: ship a config file

Instead of setDefault, you can include a ready-made config.yml in your plugin. Create a file called config.yml in the same folder as main.lua and plugin.yml, and write your settings in it:

config.yml
welcome-message: "&aWelcome to the server, {player}!"
welcome-enabled: true

Your plugin then looks like this:

MyPlugin.lkt/
├── config.yml
├── main.lua
└── plugin.yml

If you pack your plugin as a .lkt file, put config.yml at the top, next to main.lua.

The first time the plugin loads, LuaCord checks whether there's a config file in plugins/YourPluginName/ yet. If there isn't, it copies yours there, and from then on your code can read settings straight away with config.getValue("welcome-message"), with no setDefault needed.

The catch is that it's only copied once. If you add a new setting to your config.yml later, servers that already have a config won't get it, because their file is never replaced. That's why setDefault is usually the better choice, since it adds any missing setting every time the plugin starts. You can also use both: ship a config.yml, and add a setDefault line for anything you add later.

Part 2: Read a setting

Now let's use the settings. Replace your join event with this one, along with the color helper from the Messages lesson:

main.lua
local function color(text)
    return (text:gsub("&", "\194\167"))
end

plugin.registerEvent("PlayerJoinEvent", function(event)
    if config.getValue("welcome-enabled") then
        local player = event:getPlayer()
        local message = config.getValue("welcome-message")
        message = message:gsub("{player}", player:getName())
        player:sendMessage(color(message))
    end
end)

config.getValue("welcome-enabled") gives back the value of that setting. It's true or false, so it works directly in an if, and the welcome only happens when it's true. Then config.getValue("welcome-message") gives back the text. After that comes message = message:gsub("{player}", player:getName()), which is the same gsub tool the color helper used in the Messages lesson. It means "replace every this with that", so here it replaces {player} with the player's real name. If the message is Welcome, {player}! and the player is Steve, it becomes Welcome, Steve!. We save the result back into message, so the next line uses the updated text. (gsub also reports how many swaps it made, but saving it into one variable keeps just the text.)

Finally, color turns the & codes into colors.

Because setDefault ran when the plugin started, these settings always exist by the time a player joins.

Try it by joining, then open config.yml and change the message. Settings are only read when the plugin loads, so restart the server (or reload the plugin) and join again.

A missing setting isn't nil

If you ask config.getValue for a setting that doesn't exist, you don't get nil. You get something that looks like a value, so if config.getValue("typo") then is always true. Make sure every setting has a setDefault, and double-check the spelling of the names.

Part 3: Change a setting from code

Sometimes you want the plugin itself to change a setting, like an admin command. Here's one that changes the welcome message from inside the game:

main.lua
plugin.addCommand({
    name = "setwelcome",
    description = "Change the welcome message",
    usage = "/setwelcome <message>",
    permission = "welcome.set",
    minArgs = 1
}, function(event)
    local sender = event.getSender()
    local message = table.concat(event.getArgs(), " ")

    config.set("welcome-message", message)
    config.save()
    sender:sendMessage("Welcome message updated!")
end)

config.set changes a setting to a new value, whether or not it existed before. That's the difference from setDefault, which only fills in a setting that's missing. As before, config.save() writes the change to the file, so it survives a restart.

Try /setwelcome &bHello, {player}!, then join the server again.

Part 4: Update an old config

Your plugin will change over time, and the server owners who already have a config.yml shouldn't lose their settings when you update it.

Adding a new setting is easy. Add another config.setDefault line to your plugin. Existing owners keep every value they've already changed, and they get the new setting filled in with its default the next time the server starts. Their file is never replaced.

Renaming a setting takes a bit more care. Say an old version of your plugin called it welcome, and you want to rename it to welcome-message without losing what people wrote. To do that, keep a version number in the config and move the value once:

main.lua
plugin.onEnable(function()
    config.setDefault("config-version", 1)

    -- Version 2 renamed "welcome" to "welcome-message"
    if config.getValue("config-version") < 2 then
        local oldMessage = config.getValue("welcome")
        if type(oldMessage) == "string" then
            config.set("welcome-message", oldMessage)
            config.clear("welcome")
        end
        config.set("config-version", 2)
    end

    config.setDefault("welcome-message", "&aWelcome to the server, {player}!")
    config.setDefault("welcome-enabled", true)
    config.save()
end)

An old config has no config-version, so it starts at 1 and goes into the if. There, we check whether the old welcome setting holds text. We check for text with type(oldMessage) == "string" instead of a plain if, because of the warning in Part 2. If it does, we copy it into welcome-message, remove the old one with config.clear, and mark the config as version 2. A brand new config has no welcome setting, so it skips the copy and just gets the defaults.

Next time you rename something, bump the number and add another if for it.

Putting it together

Combined, your main.lua is a welcome plugin whose message can be changed in the config file, or with a command:

main.lua
local function color(text)
    return (text:gsub("&", "\194\167"))
end

plugin.onEnable(function()
    config.setDefault("welcome-message", "&aWelcome to the server, {player}!")
    config.setDefault("welcome-enabled", true)
    config.save()
end)

plugin.registerEvent("PlayerJoinEvent", function(event)
    if config.getValue("welcome-enabled") then
        local player = event:getPlayer()
        local message = config.getValue("welcome-message")
        message = message:gsub("{player}", player:getName())
        player:sendMessage(color(message))
    end
end)

plugin.addCommand({
    name = "setwelcome",
    description = "Change the welcome message",
    usage = "/setwelcome <message>",
    permission = "welcome.set",
    minArgs = 1
}, function(event)
    local sender = event.getSender()
    local message = table.concat(event.getArgs(), " ")

    config.set("welcome-message", message)
    config.save()
    sender:sendMessage("Welcome message updated!")
end)

Try these:

  • Join the server and see the welcome message.
  • Change welcome-message in config.yml, restart, and join again.
  • Set welcome-enabled to false, restart, and join to see that the welcome stops.
  • Run /setwelcome in game, then join again.

Quick reference

These are the things you can do with config. Settings can hold text, numbers, or true and false.

Call What it does
config.getValue(name) Gives back the value of a setting
config.setDefault(name, value) Creates a setting, but only if it doesn't exist yet
config.set(name, value) Changes a setting to a new value
config.clear(name) Removes a setting and saves the file
config.save() Writes your changes to config.yml
config.setAutosave(true) Saves automatically every time you use set or setDefault, so you can skip config.save()

Next up is saving data.