Attempt to call table value

local Table = {}

if Table then

end

that doesn’t error, as you can see no values

Yeah, but i want to check if it has at least 1 thing inside.
if i use it’s lenght and arithmetics it would error whenever the table was empty

It’s likely that you are destroying the part after getting the touched parts, remove the destroy parts line and see what happens there.

1 Like

@D0RYU It would be significantly more helpful if you tested some of the things you suggested in Studio yourself first to see what they’d do for you before replying to the thread. It helps prevent reply bloat with things that don’t actually work.

In any case, while I’m not particularly well-versed with coroutines and am absolutely the wrong person to give advice on such a thread dealing with them, this error is occurring because you’re returning in the coroutine. If you change the return value to say a string, the error will change to “Attempt to call string value”. Pretty sure you’re supposed to use coroutine.yield here.

local SeekTargets = coroutine.create(function()
	local Part = Instance.new("WedgePart")
	Part.CanCollide = false
	Part.Transparency = 0.9
	Part.Size = Vector3.new(3, 30, 30)
	Part.Position = script.Parent.Position + script.Parent.CFrame.LookVector * Vector2.new(30,30).Magnitude
	Part.Orientation = script.Parent.Orientation + Vector3.new(0, 45, 90)
	Part.Anchored = true
	Part.Parent = workspace
	wait(0.1)
	Part.Touched:Connect(function () end)
	local Parts = Part:GetTouchingParts()
	Part:Destroy()
	return coroutine.yield()
end)

while true do
	local success, result = coroutine.resume(SeekTargets)
	print(success, result)
	if result and success == true then
		local ray = workspace:Raycast(script.Parent.Position , result[math.random(1,#result)].Position)
		script.Parent.Parent.Humanoid:Move(-ray.Direction)
	end
	wait(0.5)
end

Doesn’t result in the “attempt to call TYPE value” error but it does attempt to resume a dead coroutine, so at a fundamental level you’ll probably want to look over your overall use of coroutines or your code structuring and ask yourself if this is the right way to go or if this can be done differently.

3 Likes

yea but then we will have memory leaks, because we never destroy the part

also if you set the table before you delete it, you shouldn’t have a problem

Ok this worked!!
But then the coroutine “Dies” for some reason? how do i un-die it?

local Table = {}

print(#Table)

that doesn’t error, I got the length like you wanted

literally in a hotel without my pc, not everyone has the ability to go on studio 24/7

yeah but try this:
if #Table > 0 then
end
this yields an error

#Table would return 0 with no values, it wouldn’t error

it also returns 0 when using dictionaries

1 Like

Inside the function there is a wait(), so it needs to wait a little bit to return something, however, the function runs somewhere in the cpu so the script you are using doesn’t wait for coroutine.resume(SeekTargets) to return something because they are running in different threads and the coroutine is being yield , therefore it tries to call whatever the function returns (in this case a table) instead of returning it like always with coroutine.resume()

i’m sorry if this isn’t clear enough, i am very bad at English but if you want your code to work you should delete the part where ´wait()´ is, it worked for me.

Do you just so happen to speak spanish?

You could consider using a demo environment or an online runner with a Lua VM (e.g. Lua Demo page) to simulate the code without the Roblox globals or just not post. Asking for additional information is fine but some of the things asked for are searchable.

I did try what Nube suggested and I also got a parts table afterward.

local SeekTargets = coroutine.resume(function()
	local Part = Instance.new("WedgePart")
	Part.CanCollide = false
	Part.Transparency = 0.9
	Part.Size = Vector3.new(3, 30, 30)
	Part.Position = script.Parent.Position + script.Parent.CFrame.LookVector * Vector2.new(30,30).Magnitude
	Part.Orientation = script.Parent.Orientation + Vector3.new(0, 45, 90)
	Part.Anchored = true
	Part.Parent = workspace
	Part.Touched:Connect(function () end)
	local Parts = Part:GetTouchingParts()
	Part:Destroy()
	return coroutine.yield(Parts)
end)

while true do
	local success, parts, part = coroutine.resume(SeekTargets)
	print(success, parts, part)
	if parts and success == true then
		local ray = workspace:Raycast(script.Parent.Position , parts[math.random(1,#parts)].Position)
		script.Parent.Parent.Humanoid:Move(-ray.Direction)
	end
	wait(0.5)
end

Yes i do speak spanish,again, I am very sorry for my bad english

Ok i speak spanish too, can you explain it to me in spanish?

Ok this works :pray: , but how can i prevent the coroutine from “dying”

Again, I’m not well-versed on coroutines so I’m not the best person to ask for advice when it comes to them, but pretty sure you can’t “unkill” a coroutine. Dead means that the body’s finished executing and can’t be used anymore, which is why I mentioned taking a look at your structure.

From the Developer Hub:

dead: The function has halted (returned or thrown an error). The coroutine cannot be used further.

AFAIK coroutines are not repeatedly callable like functions. Resuming and yielding are just defining points at which those things occur, but once the thread finishes executing then its served its purpose (and thus it dies).

EDIT: Found a thread expressing a similar issue?

1 Like

Maybe if i make it into a while loop since it yields.

This should work

local SeekTargets = coroutine.create(function()
	while true do
		local Part = Instance.new("WedgePart")
		Part.CanCollide = false
		Part.Transparency = 0.9
		Part.Size = Vector3.new(3, 30, 30)
		Part.Position = script.Parent.Position + script.Parent.CFrame.LookVector * Vector2.new(30,30).Magnitude
		Part.Orientation = script.Parent.Orientation + Vector3.new(0, 45, 90)
		Part.Anchored = true
		Part.Parent = workspace
		
		local Parts = Part:GetTouchingParts()
		game.Debris:addItem(Part,0.1)--this will destroy the part in 0.1 seconds but will not yield the current thread
		coroutine.yield(Parts)
	end
end)

while true do
	local success, parts, part = coroutine.resume(SeekTargets)
	print(success, parts, part)
	if parts and success == true then
		local ray = workspace:Raycast(script.Parent.Position , parts[math.random(1,#parts)].Position)
		script.Parent.Parent.Humanoid:Move(-ray.Direction)
	end
	wait(0.5)
end

My bad.
This worked for me

local SeekTargets = coroutine.create(function()
	while true do
		local Part = Instance.new("WedgePart")
		Part.CanCollide = false
		Part.Transparency = 0.9
		Part.Size = Vector3.new(3, 30, 30)
		Part.Position = script.Parent.Position + script.Parent.CFrame.LookVector * Vector2.new(30,30).Magnitude
		Part.Orientation = script.Parent.Orientation + Vector3.new(0, 45, 90)
		Part.Anchored = true
		Part.Parent = workspace
		
		local Parts = Part:GetTouchingParts()
		game.Debris:addItem(Part,0.1)--this will destroy the part in 0.1 seconds but will not yield the current thread
		coroutine.yield(Parts)
	end
end)

while true do
	local success, parts, part = coroutine.resume(SeekTargets)
	print(success, parts, part)
	if #parts>0 and success == true then
		local pos = parts[math.random(1,#parts)].Position
		local dir = pos-script.Parent.Position
		local ray = workspace:Raycast(script.Parent.Position ,dir)
		local point = dir
		if ray then
			point = ray.Position-script.Parent.Position
		end
		script.Parent.Parent.Humanoid:Move(-point)
	end
	wait(0.5)
end