Question about Player Spawner Device

Hi all, I wanted to ask something. I have a little issue with spawn pads and I want to know if anyone can help me solve the problem. I have several spawn pads set up so that only players of a specific class can spawn (For example: Class 1 spawns at Class 1 spawn, Class 2 spawns at Class 2 spawn, etc.). The game mode is FFA, and players progress through different classes. When a player dies, they change to a previous class. This is where I have the problem. Everything works fine except the spawns. When a player dies and moves down a class, the player spawns at the spawn pad of his previous class, not their current class. In other words: imagine that Player is on class 2. Dies. Changes to Class1 but spawn on class 2 spawner. If he dies again, he spawns at the correct spawn for his current class. Does this mean that Fortnite detects where to spawn a player when he dies before assigning him another class? If so, how can I force the player to spawn at the spawn pad corresponding to his current class? I’m doing everything on Verse, btw.

I hope I’ve explained it clearly. If not, please let me know.

Thank you very much!

Can you share your Verse code? It does seem like a timing issue. What you could do is OnPlayerEliminated have a suspends function with a sleep of 1 or something that respawns the player at correct spawn pad after a short delay.

Sure!

Sorry if the code hurts the eyes of programmers, I’m not a programmer and I’ve been putting the code together by grabbing pieces from other people’s codes. It’s the Frankenstein of codes hahaha. I’m learning, so yeah, sorry for this :melting_face:

If you need something else, let me know!

OnPlayerAdded (NewPlayer : agent) : void=
        Print("Jugador añadido")
        if(PlayerObj := player[NewPlayer]):
            # Comprueba si el jugador ya existe
            if(PlayerExists := AllPlayersMap[NewPlayer]):
                # No se hace nada, el jugador ya existe en el map
            else:
                if(set AllPlayersMap[PlayerObj] = PlayerStats{}):
                    Print("Estadísticas añadidas")
                    if(AgentStats := AllPlayersMap[PlayerObj]):
                        Print("Mis Eliminaciones: {AgentStats.GetEliminationCount()}")

                    if(FortChar : fort_character := NewPlayer.GetFortCharacter[]):
                        FortChar.EliminatedEvent().Subscribe(OnEliminated)

OnEliminated (Result : elimination_result) : void =
        Eliminator := Result.EliminatingCharacter
        Eliminated := Result.EliminatedCharacter

        if (FortCharacter := Eliminator?, EliminatorAgent := FortCharacter.GetAgent[]):
            AddElimination(EliminatorAgent)

        if (FortCharacter := Eliminated, EliminatedAgent := FortCharacter.GetAgent[]):
            AddDeath(EliminatedAgent)

AddDeath (Agent : agent) : void =
        if (PlayerObj := player[Agent]):
            if(AgentStats := AllPlayersMap[PlayerObj]):
                Print("Muerte añadida")
                AgentStats.AddDeath(1)
                AgentStats.RestKstreak(1)
                if (AgentStats.Kstreak < AgentStats.ElimsToBack):
                    ChangeClassWhenDeath(PlayerObj)
                    #TeleportToPrevLevel(PlayerObj, AgentStats)
                    set AgentStats.Kstreak = 0
                    Print("Nivel bajado")

ChangeClassWhenDeath(Agent: agent): void =
        if (PlayerObj := player[Agent]):
            if (AgentStats := AllPlayersMap[PlayerObj]):
                if (AgentStats.Kstreak < AgentStats.ElimsToBack):
                    set AgentStats.NivelActual -= 1
                    var NewLevel: int = AgentStats.NivelActual
                        if (AgentStats.NivelActual < 1):
                            set AgentStats.NivelActual = 1
                            
                        else if (Selector := ClassSelector[NewLevel]):
                            
                            Selector.ChangeClass(PlayerObj)
                            Print("Clase: {NewLevel}")

This code looks all good to me, you must be right that by the time you change their class, the game has already decided where they will respawn. To get around this you can add a functionOnDeath(A : agent)<suspends>: void = Sleep(1.0)
You might want longer or shorter sleep than 1.0 though, test it out.
Call this in OnEliminated like spawn{OnDeath(Eliminated)} and it will start your new async function separately, so after the Sleep(1.0) you can Respawn the character, and they should go to the correct spawner. I’m not sure if this will call OnEliminated again, if so only call OnDeath if there is an eliminator.

Also, here is a forum post where they just ended up teleporting players to where they need to be after spawning in. https://forums.unrealengine.com/t/agent-respawn-works-in-uefn-session-but-not-out-in-published-fortnite/833855

Sorry if I don’t fully understand. As I said, I’m not a programmer and I’m not sure where I should place what you told me. Yes, I understand creating the new function, but where should I place the spawn for the function in OnEliminated? Before the if statements or inside the if of EliminatedAgent?

I’m sorry for my lack of understanding, I’m terrible at programming, although I’m putting a lot of effort into learning. And thank you for trying to help me! :grin:

Like this will make it so it is only called when killed by another player:

OnEliminated (Result : elimination_result) : void =
        Eliminator := Result.EliminatingCharacter
        Eliminated := Result.EliminatedCharacter

        if (FortCharacter := Eliminator?, EliminatorAgent := FortCharacter.GetAgent[]):
            AddElimination(EliminatorAgent)
            spawn{OnDeath(Eliminated)}

        if (FortCharacter := Eliminated, EliminatedAgent := FortCharacter.GetAgent[]):
            AddDeath(EliminatedAgent)

I think I’ve solved it. Adding a player_spawner_device array. I did this (could not be the best way to do it, but it worked):

@editable
    LevelSpawnNivel1 : []player_spawner_device = array{}

@editable
    LevelSpawnNivel2 : []player_spawner_device = array{}

@editable
    Teleports : []teleporter_device = array{}

var CurrentSpawnerIndex: int = 0

OnBegin<override>()<suspends>:void=
    for (Spawner : LevelSpawnNivel1):
        Spawner.SpawnedEvent.Subscribe(OnPlayerSpawnedNivel1)

    for (Spawner : LevelSpawnNivel2):
        Spawner.SpawnedEvent.Subscribe(OnPlayerSpawnedNivel2)


OnPlayerSpawnedNivel1(Agent: agent): void=
        set CurrentSpawnerIndex = 1
        CompareAndTeleport(Agent)

OnPlayerSpawnedNivel2(Agent: agent): void=
        set CurrentSpawnerIndex = 2
        CompareAndTeleport(Agent)

CompareAndTeleport(Agent: agent): void=
        if (PlayerObj := player[Agent]):
            if (AgentStats := AllPlayersMap[PlayerObj]):
                var NivelJugador: int = AgentStats.NivelActual
               
                if (NivelJugador < CurrentSpawnerIndex):
                    if (Teleport := Teleports[NivelJugador])
                        Teleport.Teleport(PlayerObj)

Actually, no need to do it with level 1 cuz is the lowest level, so nothing changes. It worked rn, so Idk if it will work on private island yet. Thank you for helping me!