Not a bug. Player.Character = nil
unassigns the character from the player. Character:Destroy()
just parents it to nil
.
Actually, it is. From what I gather, the playerâs character stays in memory even after the player logs out. You have to call Model:Destroy()
on the character so it can be garbage collected. Unless youâre using a custom spawn/respawn system, the Roblox default system will leak memory. Just calling Player:LoadCharacter()
without called destroy first is what causes it.
So it seems that Robloxâs default system is missing a step. The problem is below the LUA interpreter so thereâs not much we can do about it except explicitly call Destroy()
on the character to try and keep the memory leak to a minimum.
Yes, I understand that, but I was referring to the message I was replying to.
Yeah. I missed that. Sorry, been a very long day.
Thanks for posting this. Stumbled on this by accident, but Iâm very happy I did .
Our game [đșCoyoteđș] Yellowstone Unleashed - Roblox is affected by this.
Tested using the following code:
while true do
local player = game:GetService("Players"):WaitForChild("apenzijncoolenleuk1")
SpawnAnimal(...)
task.wait(0.5)
player.Character.Humanoid.Health = 0
task.wait(0.5)
end
The âSpawnAnimalâ function clones the source model of a character, adjusts some properties and sets that as the playerâs character to spawn as. No references kept live anywhere.
Running the above code causes a 1-2MB (never cleaned) server memory jump every respawn.
Setting the characterâs parent to nil on death doesnât fix it.
If anyone knows a quick workaround please let me know.
Thanks.
EDIT: Destroying the character doesnât fix it either. I think weâll have to waitâŠ
let me know if this works
local Players=game:GetService("Players")
Players.PlayerAdded:Connect(function(plr)
plr.CharacterRemoving:Connect(function(char)
if char.Parent==workspace then
char.AncestryChanged:Wait()
end
char:Destroy()
end)
end)
Players.PlayerRemoving:Connect(function(plr)
if plr.Parent==Players then
plr.AncestryChanged:Wait()
end
plr:Destroy()
end)
Iâm fairly sure you would also have to do player.Character = nil like the OP did, not certain though.
Wow, all these years and I assumed this wasnât the case and Roblox had cleaned up properly. This explains a lotâŠ
Hopefully this gets fixed. This mustâve been plaguing so many projects and the overall platform for years.
Iâm skeptical. Explicitly setting Player.Character to nil seems superfluous, as subsequent LoadCharacter calls will reset the property with the latest Character Instance anyway. There also shouldnât be any worry that the reference will keep the Character and the hosting Player Instance from getting GCd once nil parented, as Iâd imagine this would only be problematic if the Character actually referenced back to the Player; otherwise the relationship would surely still be one directional, and not cyclic.
Anyone really. I replied to you, because you wrote that you were fairly sure that setting the Character property to nil would be necessary. Sorry for the confusion.
Did you mean to reply to me? Or to the OP?
Working with players and characters is a massive pain. Characters donât load atomically and it was deemed technically challenging to reorder avatar loading events, and then there are regular findings that players and characters leak memory and Roblox doesnât just destroy those objects which then leaves us to make strange boilerplate to do it properly - if we can even first agree on whatâs necessary amongst us as mature developers, while novice developers are left entirely in the dark.
Properly destroying players and characters really needs to be escalated with Roblox having avatars as a major part of their future vision.
As mentioned, something really strange happens if you donât set character=nil and call :LoadCharacter() in the provided example.
Itâs possibly a bug all on its own?
If you fail to set it, the client spams that weird error about having no humanoid for moveto()
As was already mentioned earlier in this thread, the warnings youâre referring to originate from a local corescript. They have nothing to do with :LoadCharacter()
being called, and are output any time the character is destroyed. This problematic script is likely reading Player.Character
, which is why these warnings are silenced from properly setting the property to nil
, when the Character is no longer present. I donât think this would be related to any of your memory concerns.
Am I wrong in thinking that calling Player.Character:Destroy() should automatically nil out Player.Character?
Because if so, the behavior should be identical if you nil manually or not.
But the behavior does actually change.
Hello.
Just wanted to mention that we are looking at introducing a mode where the engine will automatically call Destroy on players that are leaving and on characters that are being unloaded (after all the custom PlayerRemoving/CharacterRemoving callbacks are fired).
Until that is ready, we recommend manually calling Destroy.
We are also looking at ensuring that default character scripts disconnect any connection they make, without requiring a Destroy call.
hi
Do you have an example code that doesnât leak memory?
Destroying a character still leaks memory it seemsâŠ
You might have a different issue, you should open a separate topic with a description of your case.
This has been a headache for a while now, itâs great to see it finally being fixed!
Would it be possible to look into these as well? These make LoadCharacter()
dangerous to use, which results in developers needing to call them in a separate pseudothread to avoid hangs. They were reported a while ago but never actioned on:
First destroy the character then set it equal to nil
plr.Character:Destroy()
plr.Character = nil
This disconnects all connections and destroys the characterâs children