The quick answer to your question for using multiple parameters with ipairs is no, you cannot get it to return multiple parameters.
However, there are a couple of ways of solving this I would take depending on how much you’re willing to change the way you’re doing things.
The first way is a bit convoluted and rather error-prone but will allow you to continue using your TalkScript.talk(player, char, ...)
syntax.
The first approach would be to iterate over the table by values of 3
Code
local stuff = {"text1", 1, "Happy", "text2", 0.5, "Neutral"}
for i = 1, #stuff, 3 do
local text, speed, mood = stuff[i], stuff[i + 1], stuff[i + 2]
print(text)
print(speed)
print(mood)
end
The second approach would be to use tables as your multiple parameters instead.
Code
module.talk(player, "character", {"text1", 0.02, "Happy"}, {"text2", 0.02, "Mad"})
-- Your code in TalkScript.talk
local stuff = {...}
for i, triplet in ipairs(stuff) do
local text, speed, mood = triplet[1], triplet[2], triplet[3]
end
However, I would advise doing it these ways as it’s easy to mess up your inputs. Instead, I believe it would be worthwhile for you in the long-term to put in the extra effort of creating a small function that turns your talk inputs into tables that you could perhaps reuse elsewhere, similar to what @DasKairo suggested.
This is how I would go about doing it
Code
type Mood = "Happy" | "Angry" | "Neutral" -- and whatever else is a possible mood
type TalkInfo = {text: string, speed: number, mood: Mood}
local function TalkInfo(text: string, speed: number, mood: Mood) : TalkInfo
return {text = text, speed = speed, mood = mood}
end
function TalkScript.talk(player, char, ...: TalkInfo)
-- all of your other code
local stuff: {TalkInfo} = {...}
for i, talkInfo in pairs(stuff) do
local text, speed, mood = talkInfo.text, talkInfo.speed, talkInfo.mood
print(text)
print(speed)
print(mood)
end
-- all of your other code
end
-- Somewhere else
-- You can still use multiple parameters, all of the parameters are instead just tables
module.talk(player, "character", TalkInfo("text1", 1, "Happy"), TalkInfo("text2", 0.5, "Neutral"))
The benefit of doing it this way is that it takes advantage of Luau’s type-checking capabilities to make sure you don’t mess up when typing your code (e.g. if you do TalkInfo(1.5, "text42", "Happy", "text43")
, the editor will tell you, “Hey, you gave TalkInfo
the wrong arguments!” On the other hand, you might find this approach rather verbose and cumbersome, so if you’re willing to do so for the ease of use, there’s nothing wrong with using the other two approaches.
Warning: Cursed Code Ahead
Open At Your Own Risk...
So, you’re fully intent on using a “normal” for
loop to iterate through the table? Then it appears we must create a custom iterator function! If the original poster is reading this, this is outside the scope of your question. Please use one of the other approaches.
-- The following code is actually completely valid in normal Lua as long as you remove the Luau-specific features
-- (remove type annotations, turn string interpolation into a formatted string)
local function npairs(list: {any}, n: number?)
if n == nil then n = 1 end
assert(n > 0 and math.floor(n) == n, `Attempt to call npairs with invalid n number {n}`)
local co = coroutine.create(function()
for i = 1, #list, n do
coroutine.yield(i, unpack(list, i, i + n))
end
return
end)
return function()
return select(2, coroutine.resume(co))
end
end
local stuff = {"text1", 1, "Happy", "text2", 0.5, "Neutral", "text3"}
for i, team, speed, mood in npairs(stuff, 3) do
print(i, team, speed, mood) --> 1 text1 1 Happy, 4 text2 0.5 Neutral, 7 text3 nil nil
end