Best way to organize commands?

Basically, I have a command console, with the command code currently being organized like this:

if CommandData[1] == "set" then
    if CommandData[2] == "admin" then
        --code for command
    end
elseif CommandData[1] == "load" then
    --code for command
end

I want to add more commands soon. Is there a better way of doing this?

You can make a table of function, although it’s not the most efficient way:

local Commands = {
    set = function() --[[ Command code here ]] end, 
    admin = function() --[[ Command code here ]] end, 
    load = function() --[[ Command code here ]] end
    --- etc.
}

--// When the player chats

Player.Chatted:Connect(function(Message)
    if Commands[string.lower(Message)] then -- Checks if the command is in the table
        Commands[string.lower(Message)]() -- Calls the command from the table
    end
end)

This method is much more organized, but as I said, performance might be a bit worse, or better. Even if it worse it won’t make much of a difference.

1 Like

Sadly, this wouldn’t really help because if I wanted to create a “subcommand” (such as set admin and set data) then I would have to either do what I did above (will get messy), or create an entirely new table of subcommands specifically for set (will also get messy). I could do

Commands = {
    "set admin" = --function
    "set data" = --function
}

but this would conflict with the way I handle command arguments (I use string.split)

You could use a handler pattern like this:

local handlers = {}

local function addHandler(name, func)
    handlers[name] = func
end

local function handle(commandData)
    local name = table.remove(commandData, 1)
    local handler = assert(handlers[name], "No handler for command: " .. name)
    handler(commandData)
end

addHandler("set", function (commandData)
    if commandData[1] == "admin" then
        -- ...
    end
end)
addHandler("load", function (commandData)
    -- ...
end)

1 Like

You can use a dictionary instead of no dictionary:

local Commands = {
    ["set"] = function() --[[ Command code here ]] end, 
    ["admin"]  = function() --[[ Command code here ]] end, 
    ["load"]  = function() --[[ Command code here ]] end,
    ["set admin"]  = function() --[[ Command code here ]] end
    --- etc.
}

--// When the player chats

Player.Chatted:Connect(function(Message)
    if Commands[string.lower(Message)] then -- Checks if the command is in the table
        Commands[string.lower(Message)]() -- Calls the command from the table
    end
end)

This will make your set admin command to work.

Consider also using a proper library for creating commands. I personally love Cmdr, and it’s got built-in type checking, among other fantastic goodies.