Avatar Loading Event Ordering Improvements

Hi Developers,

UPDATE: This change is not live yet but is still planned.

In late May we are going to make some changes to the ordering of events that are fired during the avatar loading process. We will announce the exact date for this change closer to when it is going to go live.

The aim of this change is to make the avatar loading event ordering easier for developers to understand and to make it easier to write code which interacts with avatar loading. Currently there are a number of idiosyncrasies with avatar loading, for example the avatar is not in the Workspace when the CharacterAdded event is fired and the avatars rig is not finalized when the CharacterAppearanceLoaded event is fired. These idiosyncrasies can lead to bugs when developers write code which interacts with the avatar loading process and make it more difficult to achieve some use cases.

With the new event ordering we will add the avatar to the DataModel only after the avatar position, rig and appearance are finalized. Then the CharacterAdded and CharacterAppearanceLoaded events will be fired.

Event Changes

    Current Ordering                            New Ordering

1.  Call LoadCharacter                          Call LoadCharacter 
2.  Player.Character is set                     Character appearance is initialized 
3.  CharacterAdded fires                        Character rig built/character scaled
4.  Player.Character changed event              Character is cframed to spawn location   
5.  Character appearance is initialized         Player.Character is set
6.  CharacterAppearanceLoaded fires             Player.Character changed event  
7.  Character parented to DataModel             Character parented to DataModel
8.  Character rig built/character scaled        CharacterAdded fires  
9.  Character is cframed to spawn location      CharacterAppearanceLoaded fires 
10. LoadCharacter returns                       LoadCharacter returns 

Benefits

This new ordering fits a few common use cases much better than the current event ordering:

  • Applying character appearance items can be done easily without worrying about interference from the avatar loading code.
  • Assigning custom collision groups for the character when it is added will be easier as the rig will be guaranteed to be finalized.
  • Using APIs that require the character to be in the DataModel can be done immediately after CharacterAdded, an example is loading animations for the new character with the Humanoid:LoadAnimation() API.
  • Custom spawn positioning can be done by listening to the CharacterAdded event and moving the character immediately.

Impact

This change could break code which is relying on the current ordering of events. For example, this will break code which is waiting for the character to be added to the Workspace as follows.

player.CharacterAdded:connect(function(character)
    -- With the new ordering AncestryChanged won't be fired because the character will already be in the Workspace
    character.AncestryChanged:wait()
    -- do stuff
end)

The changes required to so that code is compatible with the new event ordering should be minimal, the above example can be changed to the following during the migration period.

player.CharacterAdded:connect(function(character)
    -- When the new ordering is enabled it will be guaranteed that the character is in the Workspace when CharacterAdded is fired.
    -- This check is temporary to migrate from the old event ordering
    if not character.Parent then
        character.AncestryChanged:wait()
    end
    -- do stuff
end)
180 Likes
Why are Release Notes released late?
Replacing players avatar without StarterPlayer?
LoadCharacter at a specific position
Respawn Improvements
Character spawn overriding
Undefined GetMass behavior on hat handles
Rainbow trail game pass and user only trail
Character Added Exists On Server But Not Client
Character's PrimaryPart attempt to index nil with 'Position'
My script runs too early, what solutions are there?
CharacterAdded vs CharacterAppearanceLoaded
CFrame set during CharacterAdded gets overridden
Trouble cloning the character
Quick question about CharacterAdded and remote events
How to change custom character during game
Make character visible after 10 seconds
Task Scheduler Priority order confusion?
Player Models In Custom Folder
Question about LoadCharacter methods yielding?
LoadCharacter at a specific position
Player::LoadCharacter should return the new character
How to change player character parent
Avatar loading events ordering improvements need to be revisited
HumanoidRootPart CFrame not changing on character spawn
Character Rigs Load Differently Based on Morph R15
Removing ThumbnailConfigurations During Character Loading
Setting Transparency not working
Tool in StarterPack showing Character.Parent = nil after respawning
Further Respawn Improvements
Further Respawn Improvements
Puzzling issue with LoadAnimation
Weird problem with HumanoidDescription
Weird problem with HumanoidDescription
Annoying Humanoid Problem (A Character Doesn't Change Correctly)
January 2020 Recap: Starting the year off with a bang!
2 collision groups collide and don't collide with each other randomly
Sound Plays When You Spawn In
Reparenting the characters
Doesn't print out the entire character, just HumanoidRootPart

Anything related to simplifying/straightening out logic behind characters is a great change.

I personally have had a lot of trouble in a few projects because “Character rig built/character scaled” had no event attached to it and could occur a (seemingly) arbitrary amount of frames later (i.e. player would have regular HipHeight and then it would change a few frames later to match their website appearance) so this should make dealing with that a whole lot easier.

Also a big fan of these benefits

35 Likes

Nice! Definitely this will make working with character appearance much more easier than before!

1 Like

This change is a solid 10/10 in my book.

Question: Do you happen to know how this change will impact the behavior of ScreenGui.ResetOnSpawn? The documentation mentions the LayerCollector will be cloned into each Player PlayerGui when they respawn. What is considered respawn in the event order here?

9 Likes

Good question, this should not cause any issues or changes with GUI loading from a developer perspective. The PlayerGui is reset when the Player.Character property is set.

11 Likes

Thanks for the hotfixes - I was having some headaches the other day due to the odd inconsistent ordering between R6 and R15 rigs, which should hopefully not exist anymore :slight_smile:

Much clearer and cleaner. This will make it so much easier for new developers who have not had to deal with all the idiosyncrasies of the old loader. :+1:

1 Like

Nice, now I don’t have to compete with Roblox on parenting the character to a specific Folder or to CFrame it somewhere. This was super frustrating behavior.

3 Likes

Is this going to make it any easier to swap out characters or do I have to write a feature request regarding that? I have an upcoming project that relies heavily on swapping between characters and it needs to be done smoothly. CharacterAdded is a huge pain when it fires as I change characters.

Or I’m just not reading the post properly.

1 Like

This change makes life so much easier! Favorite change this month (so far).

Will there be any reason to use CharacterAppearanceLoaded over CharacterAdded after this? Will it be deprecated?

5 Likes

This is a good point and something that I forgot to mention in the post. Currently the CharacterAdded event is fired whenever the Character property is changed for a Player. This will be changed so that the CharacterAdded event is explicitly when the character is added to the Workspace during the avatar loading process. If you are interested in any changes to the Character property the Changed signal can be used for this.

Yes, with the new ordering it will not be necessary to use this. It will continue to work for compatibility with scripts currently using this.

7 Likes

Will CharacterAppearanceLoaded fire on the Client?

Yes, this issue is fixed with the new event ordering changes.

1 Like

When will these changes be ready to be tested on the Studio?

Is there some way to test this before it’s live? Is this currently behind a flag? It would be a decently large task to try and screen my codebase for things that might break since my game does lots of avatar voodoo.

We will make this available to test in Studio before it is released. I will post updates about that on this thread in around two weeks.

3 Likes

I was under the impression that in some cases LoadCharacter would not yield. How does this effect those cases?

In the past I have wanted to place all characters into a single folder, parented to the workspace, what would be the best way to override the engine parenting them to the workspace?

Is this still moving forward or has it been enabled yet?

@Polymorphic This is still moving forward, I will see if I can release the Studio beta next week.

8 Likes

Any news or progress with this?

2 Likes