Deleting the game state and recreating one does work but last time we used it, we had to manually trigger a fake Event Begin Play because it was not triggering on the new game state.
When you spawn a GameState it automatically becomes the new game state. But the previous one is not destroyed and remains idle, unused. What we did was GetGameState->Store the reference, CreateNewGameState, Destroy stored reference.
If you want the fastest reload time, you’ll have to manually build a system to “reset” things.
You could create a simple “Reset” Interface that you would implement on every actors / objects that need to be reset. Then you implement the reset function on each of them and tell them what they do. For instance OnReset, characters teleport to their starting location, go back to idle and restore their resources. For instance NPC’s go back to their starting locations. For instance GameState resets its variable, destroys ongoing recorded objects that need to be destroyed between reloads (like destructibles / items) and spawns new destructibles.
Maybe your interface could also implement an “Initialize” function that only triggers once in the beginning of the map just so you can implement a simple logic for each object that need to store information at the beginning of the game (like storing its starting transform).
And the correct way to sync’ multiplayer here would be to simply have every clients listen to the BeginPlay of the new GameState you spawn when resetting the game. Unfortunately as I mentioned, the last time we tried that the ‘EventBeginPlay’ was not firing on the GameState spawned. So we had to do a little “cheat”: the Server was spawning the GameState alongside a replicated actor named “WitnessGameState”. WitnessGameState BeginPlay event was triggering on every machine so every client would receive it, and it was launching the GameState fake begin play. In your case, the BeginPlay would call “Reset” on every objects in your game.