Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Why does this say "bad argument" when it works in other places of the script?

Asked by
camxd01 48
8 years ago
Edited 8 years ago

In my script for my sword fighting game, I am trying to give participants points(Cyvicz are the currency) and it give points to the winner but not the participants. the error message is --ServerScriptService.Main:83 : bad argument #2 to '?' (string expected, got Object) . As I said, it is used earlier in the script so I think the method works. I will show only some cause it has nothing to do with the rest. The error is on the 57th line of the inline code. Thanks!

    --Setsup participants
        participants = {}
        for _, player in pairs (game.Players:GetPlayers()) do
            local humanoid = player.Character:WaitForChild("Humanoid")
            if humanoid and humanoid.Health > 0 then
                table.insert(participants, player)
            end
        end
    --Gets map and teleports
    local maps = ss.Maps:GetChildren()
    local chosenmap = maps[math.random(1, #maps)]
    chosenmap:Clone().Parent = mapHolder
    status.Value = "Beginning soon!"
    wait(3)
    local spawns = chosenmap:FindFirstChild('Spawns'):GetChildren()
    for _, player in pairs(game.Players:GetPlayers()) do
        if player and #spawns > 0 then
            local torso = player.Character:FindFirstChild('Torso')
            local allspawns = math.random(1, #spawns)
            local randomspawn = spawns[allspawns]
            if randomspawn and torso then
                table.remove(spawns, allspawns)
                torso.CFrame = CFrame.new(randomspawn.Position + Vector3.new(0, 2, 0))

                local sword = game.ReplicatedStorage.Sword
                local newsword = sword:Clone()
                newsword.Parent = player.Backpack
            end
        end
    end 
        --Round timer
    for i = 60, 0, -1 do
        if i == 0 then
            status.Value = "Time's up!"
            break
        end     
        wait(1)--Round end
        if #_G.gameplrs == 1 then--*Winner Points
            for i, v in pairs (_G.gameplrs) do
                if i ~= nil and v ~= nil then
                    status.Value = v.." is the winner!"
                    game.Players[v].leaderstats.Cyvicz.Value = game.Players[v].leaderstats.Cyvicz.Value + 50
                    game.Players[v].leaderstats.XP.Value = game.Players[v].leaderstats.XP.Value + 100
                    table.remove(participants, i)
                    break
                end
            end
            break
        else
            status.Value = i.. " seconds left"
        end
    end
    wait(8)
    --Participant Points
    if #participants > 0 then
        for _, player in pairs (participants) do
                game.Players[player].leaderstats.Cyvicz.Value = game.Players[player].leaderstats.Cyvicz.Value + 25
                game.Players[player].leaderstats.XP.Value = game.Players[player].leaderstats.XP.Value + 50
                game.Players[player].Backpack.Sword.Parent = game.Lighting
                for i, v in pairs(_G.gameplrs) do
                game.Players[v].Backpack.Sword.Parent = game.Lighting
            end
        end
    end

1 answer

Log in to vote
0
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

The error

"Bad argument" in this case is referring to the argument to the __index meta method (which really is a function). Specifically, dealing with foo[bar].

In foo[bar], the first argument is foo and the second argument is bar.

The error is telling you that the subscript on line 57 "expected a string but got an Object".

This means that player isn't a string, it's an object. Very likely, it's a player object.


The fix

It should give you pause when you find yourself writing statements like game.Players[player].

Is looking for the object by the name really what you should be doing? You should just use the object itself which is a player (line 6).

There is no reason to check if #participants > 0. Iterating over something empty just does exactly nothing.

wait(8)

-- Participant points
for _, player in pairs(participants) do
    player.leaderstats.Cyvicz.Value = player.leaderstats.Cyvicz.Value + 25
    player.leaderstats.XP.Value = player.leaderstats.XP.Value + 50
end

Blah

There are lots of other sketchy things going on in your code.

You should go back and simply. You do not need _G. You should not be nesting for loops. You should not be moving objects back to game.Lighting. You should be careful about checking for things in the backpack (they can also be in the character or could have been lost altogether). You should check that Character is not nil and that the Character has a Torso. You should not check if i == 0 inside a for loop -- you should just do that code after the loop. for ...... in pairs can't produce nil as either an index or a value, so you should not check for that. You should tab your code correctly. You should not use table.remove how you are (you don't need table.remove at all, I don't think -- you shouldn't bother trying to keep participants up to date you should just compute it when needed).

Ad

Answer this question