Hi Chris,
We’re working on a multi-platform Unity project using Adventure Creator v1.79.3, and we’ve created a custom iSaveFileHandler implementation for PS4/PS5 to override the default save system.
We’ve successfully implemented label assignment like this:
string scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
string time = DateTime.Now.ToString("dd/MM/yyyy HH:mm");
string label = $"{scene} ({time})";
saveFile.label = label;
This works great on Xbox (which uses its own handler), but on PS4/PS5, where we assign SaveSystem.SaveFileHandler = new CustomSaveFileHandler() at runtime, the SaveList UI still displays "Save 0", "Save 1", etc. — not the label from our custom handler.
We also call
PlayerMenus.GetMenuWithName("SaveGame")?.Recalculate();
to refresh the UI, but still no change.
Our setup:
* AC version: 1.79.3
* Unity version: [add your Unity version here]
* Menu type: Unity UI-based or Adventure Creator? [whichever you use]
* Custom handler assigned via: InitSaveHandler.cs in Awake()
* Save labels stored in PlayerPrefs, along with scene name and timestamp
* Labels show correctly in Xbox (using a different iSaveFileHandler)
* Label field on SaveFile is definitely being set and logged
Questions:
In AC 1.79.3, how does the SavesList element determine the label to show, and is there a way to force it to use saveFile.label?
Is there a known way to override those “Save X” defaults without upgrading to AC 1.81+ (which would break our custom integrations)?
Can we access or modify MenuSavesList.labels or similar fields to manually force the labels?
Let me know if you’d like a sample of the full script — happy to share.
Thanks in advance!
– James
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
With a custom iSaveFileHandler implementation, you can create an override of the GetDefaultSaveLabel function to return your custom label.
I’ve already implemented a custom iSaveFileHandler, and GetDefaultSaveLabel(int saveID) is overridden to return a custom label using scene name and timestamp. I also assign the label directly to saveFile.label during Save() and again in GatherSaveFiles() like so:
string label = $"{scene} ({time})";
saveFile.label = label;
Despite this, the SavesList menu still displays the default “Save X” format instead of the custom label. This happens even though my handler is correctly registered and used (confirmed via debug logs). I’m using AC v1.79.3.
Is there anything else that needs to happen for the label to show correctly in the UI? For example, is the SavesList menu supposed to reference GetDefaultSaveLabel(), or should it always rely on the label stored in SaveFile?
Thanks again!
James
Got this sorted, thanks!
Hi Chris,
I'm currently integrating Adventure Creator v1.79.3 with a custom save system for Xbox using the Microsoft GDK. My goal is to ensure save slot labels (e.g. "Jungle\n24/06/2025 17:30") persist across sessions — not just in-memory, but stored and recalled correctly even after quitting and relaunching the game.
I’ve implemented a custom iSaveFileHandler (called XboxSaveFileHandler) that writes and loads save blobs using Xbox GameSave. The saves themselves load and persist fine — however, I’m struggling to persist the save labels between sessions in a way that AC’s UI (i.e., SavesList menu elements) will continue to display them correctly.
Here’s the problem:
Questions:
Thanks so much — any advice would be hugely appreciated, especially as we’re trying to get Xbox save/load certified and functional across all platforms.
I'm not clear on the underlying problem. What's the actual behaviour you're getting?
The save labels are set by the iSaveFileHandler - but this data is stored within your game's Options Data, so that they can be retrieved without having to load the saves themselves.
This should be handled automatically. If the wrong labels are showing, how are you saving options data? That can similarly be customised with an iOptionsFileHandler override.
Are regular Options, e.g. SFX volume, saving/restoring correctly between sessions?
Hi Chris,
Thanks again for your help earlier — we’ve made progress, but I wanted to follow up on a couple of areas we’re still stuck on regarding save labels and options persistence using custom handlers in AC 1.79.3.
Current Issues
* Save Labels Not Persisting Across Sessions
* We assign saveFile.label during Save() and again inside GatherSaveFiles(), and the label displays correctly in the SavesList menu during the same session. However, after restarting the game, AC’s SavesList reverts to showing “Save 0”, “Save 1”, etc.
* Options Are Not Persisting Either
* We’ve implemented a custom iOptionsFileHandler and confirmed that save/load callbacks are being hit — but changes to options like SFX volume don’t persist between sessions.
**Our Handlers
**Here’s a simplified version of our implementation:
Remaining Questions
* Should save slot labels be written into Options data automatically by AC when saveFile.label is set, or do we need to manually handle that in iOptionsFileHandler?
* Does AC’s SavesList element always rely on Options data for displaying labels, or does it fall back to saveFile.label or GetDefaultSaveLabel() if none is found?
* Do we need to store save labels in a particular field/format inside the options string for AC to recognize them?
* Any obvious issues with our approach that would explain why labels and options both reset on restart?
Really appreciate any guidance — this is the final blocker before we wrap platform integration for certification.
AC handles the serialization/deserialization of Options data - iOptionsFileHandler only needs to save/load all data as a single string value, dataString in SaveOptions.
If the Options data is not found, it'll revert back to the SaveFile list sent as a callback in the iSaveFileHandler's GatherSaveFiles function.
The fact that the regular Options data (SFX volume etc) isn't persistent is the main issue, here. There may be an additional issue with labels, but the former needs to be addressed first.
I can't comment on your implementaion of iOptionsFileHandler, but you've confirmed it's being used by AC with Debug.Logs?
Thanks for the clarification — very helpful.
We’ve confirmed that our custom iOptionsFileHandler (XboxOptionsFileHandler) is being used to save both options data and save slot label metadata. Our logs confirm that the save process is working, for example:
[XboxOptionsFileHandler] Options and labels saved for profile 0
However, no options data is persisting between sessions — SFX volume and other preferences are reset on each launch. This suggests that while the data is being saved, it is not being loaded correctly at startup.
We currently have no evidence that our LoadOptions() method is being called — it doesn’t appear in the Xbox logs, so we can’t confirm whether it’s ever executed without adding explicit in-game logging.
Based on the log order and observed behavior, we suspect the handler is being assigned after AC has already called Options.LoadPrefs(), which would result in the default handler (likely PlayerPrefs) being used instead.
Our setup begins in a non-Adventure Creator scene, where we initialize Xbox GDK systems (sign-in, achievements, save system, etc.). The first Adventure Creator scene is loaded afterwards. We attempted to assign the handler via a script called InitSaveHandlerWhenReady during the first (non-AC) scene, but this had no effect — likely because AC was not yet initialized and LoadPrefs() hadn’t yet been triggered.
However, when InitSaveHandlerWhenReady runs in the first AC scene, it appears to run after AC has already initialized and loaded the default options — again, too late to have any effect.
Regarding save slot labels:
We are assigning saveFile.label manually and persisting it alongside the options data, for example:
[XboxSaveFileHandler] Saving saveID 0 with label: AUTOSAVE - LABORATORY [02/07/2025 14:21]
As you explained, Adventure Creator relies on the options data to store and retrieve custom labels across sessions — so if the iOptionsFileHandler isn’t active by the time Options.LoadPrefs() is called, both the options and labels will fail to load.
That seems to be exactly what’s happening here: although the labels are saved correctly, they don’t persist between sessions because our handler isn’t active when AC initializes.
We’re currently looking to identify a reliable way to ensure the handler is assigned before AC reaches LoadPrefs(), without modifying core AC scripts. Any guidance on this would be much appreciated.
Cheers
Setting OptionsFileHandler before AC is present should be fine, I would have thought. It's a static variable and not one tied to a particular instance.
Leaving AC's core scripts alone may be the ultimate goal, but you can test this by setting your own handler to be the AC default. In AC's Options script, see the OptionsFileHandler property at the bottom. Its getter returns OptionsFileHandler_PlayerPrefs unless an override is set - try replacing this with your own.
Hi Chris,
We’ve followed your advice and updated the Options.OptionsFileHandler fallback logic to return our custom Xbox handler by default on GDK builds. We also assign it manually via script at runtime just to be safe. Saving works (logs confirm blobs are written), and the blob options_profile_0 exists after reboot.
But despite the blob being read, AC’s optionsData always resets to defaults on restart. We’ve confirmed:
We've tried:
Still, the options UI shows default values every time. We suspect AC’s LoadPrefs() logic may be running before our data finishes loading, or that the optionsData assignment is overwritten somewhere internally.
Can you confirm:
When exactly Options.LoadPrefs() is called on startup relative to KickStarter.Initialise()?
Thanks again,
James
LoadPrefs is called from the chain that begins in KickStarter.Initialise's SetPersistentEngine function call. Here's the stacktrace for the log that appears when starting up AC with OptionsFileHandler_PlayerPrefs:
Where are you getting LoadOptionsAsync from? It's not an implementation of OptionsFileHandler.
Thanks Chris — that’s super helpful.
Just to clarify, the LoadOptionsAsync method I mentioned was part of our own custom implementation using Xbox Game Save. But I now realize that because Options.LoadPrefs() is triggered early via KickStarter.Initialise → SetPersistentEngine, our handler was being registered too late.
Based on your explanation, we’re now assigning our XboxOptionsFileHandler and explicitly setting Options.optionsData = LoadOptions(...) inside a script that runs immediately after instantiating the PersistentEngine, but before any UI or save menus are used. This should ensure our options (volume, labels, etc.) persist correctly.
Really appreciate the clarity on where LoadPrefs() is triggered — that’s exactly what we needed to move forward.
Hi Chris,
We’re running into an issue with options not persisting on Xbox using a custom iOptionsFileHandler implementation in Adventure Creator v1.79.3. We’re integrating with the Xbox GDK GameSave API, which loads options data asynchronously from a blob (e.g. options_profile_0).
In the logs, we can confirm that:
The options blob is successfully written and present in the save container.
However, Adventure Creator appears to call Options.LoadPrefs() before our handler has a chance to load the data, resulting in the warning:
[XboxOptionsFileHandler] AC called LoadOptions synchronously. Returning empty JSON.
We’ve verified this happens during both CompleteSignInSetup() and again when AC initializes via OnInitPersistentEngine().
Would you recommend delaying Adventure Creator’s Options.LoadPrefs() call until our async read has completed and Options.optionsData is initialized?
Would modifying our InitSaveHandlerWhenReady script to wait for the GameSave system and options to fully load before allowing AC to proceed be the correct approach?
Appreciate your advice on how best to handle this in AC’s initialization lifecycle.
Thanks,
James
Am I talking to an AI, James?
AC Menu Type
Unity Version: 2022.3.51f1
I am asking ai to help me write more concise responses, rather than my haphazard replys. We had this working months back, then I had to switch to PS5 to fix a bug and do an update. Then I switched back and have lost the options working. Saves work fine. Ironically, options were working first before on xbox and saves was the issue. I am sure it is to do with when we initialise the handlers, but I seem to have tried everyything. I feed the watson logs in to chat gpt to understand what they are telling me. And they are telling me this:
Adventure Creator tries to load options too early:
[XboxOptionsFileHandler] AC called LoadOptions synchronously. Returning empty JSON.
Root Problem
InitSaveHandlerWhenReady is logging "Handlers already assigned" before options are loaded, causing AC to use defaults.
Solution?
Delay setting handlersSet = true until options are loaded and Options.optionsData is assigned, then call Options.SavePrefs().
Let me know if you'd like a version of this explanation to post to a forum or share with your team.
This is our InitSaveHandlerWhenReady script:
I'd really appreciate any help, it is getting me down!!1
this is my xboxoptionshandler:
and my xboxsavehandler:
I’ve given up on chat GPT - it just gets lost and muddled: right now saves persist, but options do not.