Unpredictable execution sequencing of the 'SpawnedEvent' and subscribed handlers within 'OnBegin'.

Hi everyone,

I’m encountering unpredictable execution sequencing of the ‘SpawnedEvent’ (defined within the ‘player_spawner_device’ class) and its subscribed handlers within ‘OnBegin’ (defined within the ‘creative_device’ class). That is, sometimes the handlers will be subscribed prior to the event being signaled/triggered (and resultingly, are invoked to handle the event), whereas other times the handlers aren’t subscribed until after the event has already been signaled/triggered (and consequently, aren’t invoked and don’t handle the event).

Whilst the documentation (such as this example) foregoes the technical details as if to presume that it should simply work (i.e. “trust me, bro!”), it seems to be arbitrarily-timed and, consequently, error-prone.

My presumption (due to ‘OnBegin’ being asynchronous) is that if the logic prior to subscribing the handlers exceeds the current simulation update interval (such as simply calling Sleep(0.0)), it won’t execute until after the ‘SpawnedEvent’ is signaled/triggered. Is this somewhat accurate or is there more at play?

Ultimately, how can one guarantee the successful subscription of handlers for the ‘SpawnedEvent’ within ‘OnBegin’ prior to it being signaled/triggered (especially if there is computationally expensive initialisation logic)?

Any insight will be greatly appreciated. Thanks!

Hi @Ben85,

Can you please share the code you’re using that’s giving you the problem you’re describing? If we have code to reproduce the issue we can direct it to the right team to fix it.

Hey dude, if you want to apply some modifications to your in game players, you can try something like this.

    GetPlayspace().PlayerAddedEvent().Subscribe(OnPlayerJoined)
    # Or replace with spawner device, and add a GetFortCharacter[].IsActive[] filter on the following loop

    for(Player : GetPlayspace().GetPlayers()):
        OnPlayerJoined(Player)

Still, your device should work fine just with the way you set it up, so you might have a problem somewhere that in fact delays the subscribing of the events. Also, maybe you’re disabling spawner somewhere else ?

Additionally, If you have many scripts that act on the same devices, it can be smart to delay the activation of some of the scripts by setting a Sleep(1.0) in the OnBegin() of one of the script for example.

I’ve heard from multiple accounts that using PlayerAddedEvent() can be inconsistent, it’s recommended to use SpawnedEvent() on player spawners or even more consistent is using a player counter with a zone. Just wanted to add that so ya’ll know.

1 Like

The very first thing I would do is start your listener for spawned event. Then run whatever other code you need. Like mentioned above you can always use Sleep in async functions to allow other processes to finish.
Something that I do is spawn an await function, then make a custom event and signal it at the end of my dependency process.

ReinitEvent : event() = event(){}

  Players := Self.GetPlayspace().GetPlayers()
                  for (Player : Players, Agent:= agent[Player]):
                      Ultimate.CheckForReinit(Agent)
                      Print("Info: Triggering Player Class Reinitialization")
                      ReinitEvent.Signal()

In my other device:

    #this goes in OnBegin
    spawn{PersistenceListener()}

    PersistenceListener()<suspends>:void=
        UltimateDevice.ReinitEvent.Await()
        PersistenceReinit()