Reproduction Steps
Have a SpawnLocation on the ground no higher than 1 stud (use the Baseplate template) and set SignalBehavior to Deferred. Start a test session (I used F5) and walk around.
Expected Behavior
As with Default (Immediate) SignalBehavior, the Running character sound should be played when the character spawns and starts moving around.
Actual Behavior
When the character spawns, the Running sound will not be played. The Running sound will not play until the HumanoidStateType changes to a different state (e.g. by Jumping) and then re-enters Running or RunningNoPhysics.
Workaround
I use task.spawn to immediately execute the transition function for the active state if a transition function exists for that HumanoidStateType. I drop the following after the StateChanged connection is created:
task.spawn(function()
local state = stateRemap[activeState] or activeState
local transitionFunc: () -> () = stateTransitions[state]
if transitionFunc then
transitionFunc()
end
end)
This workaround is safe to deploy in both Immediate and Deferred. The code is mainly intended for Deferred mode as it is effectively ignored in Immediate because no transition function exists for the None HumanoidStateType.
I decided to include my research as part of my workaround. tl;dr of the bottom section:
In Immediate, running sound plays because HumanoidStateType None → RunningNoPhysics. In Deferred, running sound does not play because HumanoidStateType Running → RunningNoPhysics which are treated as equivalents in the code. The problem lies in how this transition function code is written.
With a new found love for Deferred mode, some testing and very extensive debugging, I was able to isolate the problem here to the transition functions being executed in the Humanoid StateChanged lambda. A lot of assumptions and workarounds that RbxCharacterSounds uses do not apply in Deferred mode. I assume these were made because of Immediate SignalBehavior and the unfixed avatar loading events ordering that could trigger potential memory leaks or because of avatar loading edge cases.
The main problem is the aforementioned StateChanged lambda. RbxCharacterSounds does not execute any transition functions until the state is changed. This wouldn’t be a problem since both SignalBehaviors detect a change in the HumanoidStateType when the character loads in however the difference lies in how activeState initialises (a variable holding the initial HumanoidStateType after spawning).
local activeState: Enum.HumanoidStateType = stateRemap[humanoid:GetState()] or humanoid:GetState()
print("Initial state:", activeState)
During the avatar loading process it seems the character silently enters RunningNoPhysics (StateChanged does not fire None → RunningNoPhysics) and flicks between RunningNoPhysics and Running once or twice. As Running (and by default RunningNoPhysics due to the remapping behaviour) is different from None, the transition function can be successfully called in Immediate.
In Deferred, activeState initialises with HumanoidStateType.Running. The state flicking is still present in Deferred however because RunningNoPhysics is treated the same as Running the state is never recognised as changed. Look at the function:
humanoid.StateChanged:Connect(function(_, state)
state = stateRemap[state] or state
if state ~= activeState then
local transitionFunc: () -> () = stateTransitions[state]
if transitionFunc then
transitionFunc()
end
activeState = state
end
end)
RunningNoPhysics is treated the same as Running and activeState initialises as Running in Deferred so the conditional does not pass and thus the transition function for Running does not get called. So at the heart of the problem, transition functions are only called when StateChanged fires and the conditional passes. None → RunningNoPhysics will pass but Running → RunningNoPhysics will not. So players can hear their Running sound in Immediate after they spawn in and move around but that does not hold for Deferred.
Issue Area: Engine
Issue Type: Other
Impact: Moderate
Frequency: Constantly
Date First Experienced: 2021-09-15 00:09:00 (-04:00)
Date Last Experienced: 2021-09-15 06:09:00 (-04:00)