hello i am working on a game and came across this error but i have no idea how to fix it
if anybody is nice enough to help me out here
the error is happening inside of a module script
local ItemProperties = require(game.ServerScriptService.ItemProperties)
local Items = game.ServerStorage.Items
local ItemDistribution = {}
function ItemDistribution.SpawnItem(spawner)
local ItemTable = ItemProperties[spawner.Name]
if math.random(1, 3) > 1 then
for val = 1, math.random(2, 3) do
local RandomItem = Items:FindFirstChild(ItemTable[math.random(1, #ItemTable)]):Clone() -- this is where the error is happening
RandomItem.Parent = workspace.Items
if RandomItem:IsA("Model") then
RandomItem:MoveTo(spawner.Position+Vector3.new(math.random(-5, 5), -3, math.random(-5, 5)))
elseif RandomItem:IsA("BasePart") then
RandomItem.Position = spawner.Position+Vector3.new(math.random(-5, 5), -3, math.random(-5, 5))
end
end
end
end
return ItemDistribution
2 Likes
This might be because #ItemTable
is 0
to confirm, print it, and if it is, then only run the function if #ItemTable
is over 0
1 Like
just checked if it prints 0 and it does
and how can i fix it the error?
Work backwards; find out why your table is empty
i also have tried printing the ItemTable
and it prints all the stuff inside of the table
the table isint empty i have tested print(ItemTable)
and it does print every single thing inside of the table but if i do print(#ItemTable)
it prints out 0
Thats probably because you have non-number indexes/keys and #
only works on arrays
to fix this, insert this after the local ItemTable
line
local len = 0
for i,_ in ItemTable do
len += 1
end
this gives us the actual length of the table, even if it has non-number indexes/keys!
Now you can replace #ItemTable
with len
in the script
1 Like
I see the problem here. Tables are divided into two categories: dictionaries and arrays. The length operator only reports the length of the table’s array component–dictionary length is always 0. Arrays are characterized by ascending numerical indices starting from 1, which is why we can pull random elements from the array through generating a random index between 1-#array. A dictionary’s key-value pairs are not characterized by this, meaning the same math.random
approach will not work.
To get a random key-value pair from a dictionary, you need to collect its keys into an array and chose one by random. Do this, or try to convert your dictionary into an array
now it throws another error Argument 1 missing or nil
Put this after the loop I sent earlier
local Iteration,RandomIter,RandomValue = 0, math.random(1,len), nil
for i,v in ItemTable do
i += 1
if i == RandomIter then
RandomValue = v
break
end
end
and replace ItemTable[math.random(1, len)]
(in FindFirstChild) with RandomValue
its sending a error at i += 1
attempt to perform arithmetic (add) on string and number
oops, i meant to write Iteration
instead of i
in that line and the line after
the rest works but now its sending an error at local RandomItem = Items:FindFirstChild(RandomValue):Clone()
Argument 1 missing or nil
local function randomKeyValue<K, V>(dictionary: {[K]: V}): (K, V)
local length = 0
for _ in dictionary do
length += 1
end
local index = 0
local randomIndex = math.random(length)
for key, value in dictionary do
index += 1
if index == randomIndex then
return key, value
end
end
-- Silence NACP
return nil :: any, nil :: any
end
where should i add it? like this local RandomItem = Items:FindFirstChild(math.random(1, randomKeyValue(ItemProperties))):Clone()
local _, randomItem = randomKeyValue(ItemTable)
should it look like this? local RandomItem = Items:FindFirstChild(randomItem):Clone()
What if you put it above the local RandomItem
line? (The whole local Iteration… for i,v… i mean)
1 Like
That depends on what your key-value pair is. Is the item name the key, or the value associated with the key?