I’ve recently been working on a little RPG project and i wanted to write my own quest system. Most of the tutorials i found online suggested turning the quests into actors and placing them in the world, however i disliked that approach because to me quests aren’t something that is in the world.
So i defined my own approach to quests. The quests are to be data container assets, containing a list of objectives, conditions and events and such. A level designer would just create the asset, define all the objectives and the quest would exist in the game. I employed the use of a game instance subsystem to easily manage my quests as well as completion data for save games. For this, the subsystem fetches all assets with the appropriate type at the time of initialization.
This all works fine and dandy in PIE because the asset registry will always load all assets in the content directory. I can make it work fine in a packaged game too if i add the directory my quests are in to the list of directories to always cook in the project settings. However if possible i would like to avoid having to do this and manage the asset type in a way that it always gets cooked.
Moreover i cant think of a proper way that would allow me to always get the quests in the standalone game view of the editor.
Would anyone happen to know a trick that could make this work? Thanks a lot in advance!
Make a list that you manually manage of what is present in the release.
Say the quest list was an array of references right?
Only the references used in this array are actually going to be baked. (And as a bonus the engine will do exactly just that for you).
Which also means you can have test quests and extra stuff in your project and not have to worry about having to manage and remove things since you have to manage the array itself.
I too like dynamic approaches, but in this case you create more issues with a dynamic approach then you do with a fixed one…
I suggest a game mode array. Since the possible quests are part of the game mode you are in…
Yeah that makes plenty of sense… I kind of dislike the idea of an array with multiple hundreds of elements to reference each quest the game holds, but i can see the merits in it too.
Though it appears the problem already solved itself. When i made my initial version of the Quest Subsystem, i made a journal and wanted it to show me just every possible quest asset i made. But that doesnt make much sense to be honest. In the end, unreferenced quests (like any other asset type) shouldnt be packaged because theres no way to initiate them anyway - since the initiation is done via an asset reference. So every quest that can be initiated one way or another got referenced and thusly cooked and loaded for both standalone and packaged games.
Though i’d still be kinda interested if theres a way to cook assets for standalone, since theres a way to cook them for packaged too.
Theoretically (because I have never verified this) launching in standalone is just a different development build being baked up following the settings of the project settings applicable to all publishing.
So, in theory at least, it should bake all the assets that need baking if you set up your configuration for the publish settings to always include a folder or a level…
Mayhapd it has to do with different load times then? The subsystem got the quest references from the asset registry upon initialize, its a game instance subsystem. In standalone it got nothing, but in packaged it properly got the entire quest list :o
That’s pretty much what i ended up doing. Moved the content from my Initialize function to a custom initialization function that i call on begin play in the game mode and now it works perfectly.
The only minor problem with this is that the game mode is bound to the map, and thu it will try to initialize the game instance subsystem every time a level is loaded, but that shouldn’t be a problem since it’ll just load quest progression flags from the save data and initialize the quest list. And if it ever turns into a problem a simple flag to check if it’s already initialized would fix that.