I work with Aero Game Framework and I’ve encountered an issue that I can’t quite understand. My code warns me that an infinite yield has been detected if I use an in-scope variable but not for an upvalue.
In Aero, each service has an Init method. This method is called when the internal bootstrapper sets things up and is ready to run through each service. Since I don’t use ServerScriptService except to fetch the ChatServiceRunner, I decided to move it into my Init function.
-- Barebones excerpt of my code
function ChatSetupService:Init()
local ServerScriptService = game:GetService("ServerScriptService")
-- Other setup code here
local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
end
For some reason, setting up my function like this warns me of an infinite yield. On the other hand, if I define ServerScriptService outside of the function, that isn’t the case.
-- Barebones excerpt of my code, once again
local ServerScriptService = game:GetService("ServerScriptService")
-- Other code here: adding methods, other constants and variables, so on.
function ChatServiceSetup:Init()
local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
end
Is anyone able to explain the behaviour behind this? I wanted to remove the ServerScriptService constant as an upvalue to avoid keeping a reference when I don’t use it except for this one time, but the warning turns me away from doing so.
I can’t replicate your issue. This is how my code has been set up to try to reproduce your issue.
local TestService = {Client = {}}
function TestService:Init()
local ServerScriptService = game:GetService("ServerScriptService")
local ChatService = require(ServerScriptService:WaitForChild("ChatServiceRunner").ChatService)
print(ChatService.GetSpeaker)
end
return TestService
Output:
--> function: ...
Edit: Console suddenly decides it doesn’t want to randomly warn me now? I’m getting sporadic behaviour right now, still don’t understand what’s wrong with perfectly fine code.
Aero Game Framework is at its latest version, except I use a modified version which ports the ServerStorage section to ServerScriptService. Shouldn’t change anything, especially since hierarchy is only relevant during bootstrapping.
Honestly I haven’t the slightest what’s happening. I know it’s not a bug and I goofed something in my implementation but I don’t understand what or why. ChatServiceRunner doesn’t get injected late enough for WaitForChild to warn me that an infinite yield is possible.
You know how when you install Aero Game Framework, you receive two folders in each respective server container? ServerStorage and ServerScriptService.
ServerScriptService
Aero
Internal
AeroServer
ServerStorage
Aero
Modules
Services
version
I moved the Modules and Services folders from ServerStorage.Aero to ServerScriptService.Aero and deleted the empty ServerStorage folder along with the version ValueObject. Hierarchy changes to this:
The only modification I made to the server bootstrapper is where it fetches its server-side components from by changing GetService(“ServerStorage”) to GetService(“ServerScriptService”).
The only possible explanation I can give is that somehow the code is somehow being run locally (extremely unlikely), or the Module is indeed taking a very long time to load.
I have more faith in the latter circumstance than the former. LocalScripts will always warn you of infinite yields when you use WaitForChild on any server container as the service itself will exist but its contents will not as they aren’t replicated.
I can’t get accurate results for that kind of a test because it seems to be intermittently happening now.
I’m going to mark this as the solution for now. It’s a complete assumption but I believe longer load time as a probable cause than anything and this problem’s generating an unneeded headache.