I’m making a MOBA game as education project. Basically, this is a dedicated server setup, but I want to support host setups as well.
I need to pass some data from Lobby (LobbyGameState) to the actual game (CombatGameState) on seamless travel. For PlayerState this is straightforward - I’ve overridden the CopyProperties method. But GameState doesn’t have equivalent.
I’ve looked at the common solutions in the internet and I’m not quite satisfied with any of it:
Store the data in GameInstance/GameInstanceSubsystem. It seems like antipattern as GameInstance has a completely difference lifetime. The passing data should live maximum during travel (or even less), but GameInstance lives while application lives.
Save the data to disk (Json, Database, etc.). I don’t see why I’d pay the I/O cost for data that only needs to live during transition. In fact, the data lifetime is even bigger than GameInstance’s one.
Pass the data inside the travel URL. I found that solution as the most promising. The URL survives server travel, I can access it in GameMode::InitGame. But it’s still it’s not quite obvious how to encode and fetch collections from there.
Also Gemini advised to inherit the AWorldSettings class and override SeamlessTravelTo method. But fast documentation research revealed that this method does not exist.
None of these feel like the right answer. Is there a cleaner pattern I’m missing?
I would appreciate any thoughts on this.
i think you’re over analyzing, any of those solutions are fine.
another option is to merge the GameState data and just persist through seamless travel, or make them actor components of the GameState so its separate but still persists.
generally speaking i’d say saving is the correct solution since you may need that in the future (replays, disconnects etc) and you dont have to save to disk you can just save to an object thats kept in memory say on the GameInstance
Thank you for input!
Merge GameStates is not option for me as the most of the properties there are completely different.
There are some reasons why I wouldn’t like to store the transition data inside GameInstance/GameInstanceSubsystem:
GameInstance’s lifetime is much longer (obviously) than transition. After transition ended the variables are invalid. That adds complexity to the transition module and adds unobvious dependency.
And later I will definitely make a transition from the Combat mode to a Result mode. Again I’ll need to add extra variables to make the transition. Probably I’ll want to add other Combat mode with completely different transition data. And so on.
its hard to really help not knowing what the data is,
is still think SaveGameObject (or really any object) on the GameInstance (again you dont have to write to disk) is the best idea, you can clear it after merging the data with your new GameState.
if you want something lighter you can use an FInstanceStruct instead.
I’m really surprised that there is no clean way just to pass data between GameStates.
From my point of view using GameInstance for this feels like saving temporary data to a class field just to avoid passing it as a parameter. Passing the data explicitly through parameters is much cleaner