I looked through all the source on how ControllerList is populated. The Controller.uc class has these two methods:
Code: Select all
native(529) final function AddController();
native(530) final function RemoveController();
Controller.PreBeginPlay() calls AddController(). Controller.Destroyed() calls RemoveController().
So it seems like a controller is getting destroyed before or during that loop. I think the garbage collector will change any references to a destroyed object to None so you get the None access here.
It might be helpful to add logging to BS_xPlayer (UTComp's PlayerController class) Destroyed() method to see when the controllers are getting destroyed.
Also something to mention is I've seen very similar errors in other mutators like 3SPN/TAM. Looping through Level.ControllerList seems to be problematic. It's done quite a lot throughout the engine but there may be cases it's unsafe to do.