Skip to content

Fix SynchronizationManger Not Updating Local Config Changes when AdminOnlyStrictness.IfOnServer and Jotunn not on Server - #505

Open
searica wants to merge 13 commits into
Valheim-Modding:devfrom
searica:fix-sync-manger-local-config-changes
Open

searica wants to merge 13 commits into
Valheim-Modding:devfrom
searica:fix-sync-manger-local-config-changes

Conversation

@searica

@searica searica commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

So I ran into a really non-intuitive issue with MoreVanillaBuildPrefabs (which has AdminOnlyStrictness.IfOnServer) when it was used as a client side only mod where the dedicated server is entirely unmodded and the client is not an admin. Here is a description of the issue and what occurs when connected to a dedicated server without Jotunn installed versus when not connected to a dedicated server at all.

When connected to the dedicated server:

For any config entries that were AdminOnly, changing the value via the local config file had no effect in game while connected to the dedicated server, despite MoreVanillaBuildPrefabs using the ConfigFileWatcher provided by Jotunn.

Changing the value for AdminOnly configs using an in-game config manager while connected to the dedicated server did update the value in-game and immediately took effect, but the changes were not saved to the local config file.

For non-AdminOnly configs, changing them in the local file immediately updated the value in-game and changing them via an in-game config manager immediately saved those changes to the local config file.

When not connected to a dedicated server:

For all config entries, whether they were AdminOnly or not, changing them in the local file immediately updated the value in-game and changing them via an in-game config manager immediately save those changes to the local config file.

Troubleshooting
So I did some digging into both the ConfigFileWatcher and SynchronizationManager classes. First, I started logging of which config files SynchronizationManager was trying to manage settings for and found that everything was working as intended based on whether mods depend on Jotunn and the AdminOnlyStrictness.IfOnServer attribute setting. So, I dug into ConfigFileWatcher to see if it was redirecting changes to a server that wasn't actually there to receive them, but it also appeared to be working as intended.

I did some more testing and confirmed that the values for AdminOnly config entries were straight up not changing even when a reload of the local config file was triggered so I suspected that something was interfering with the actual reloading of just the AdminOnly config entries, since non-AdminOnly config entries were reloading as intended. Then I caught that the methods SubscribeToConfigReload, UnsubscribeToConfigReload, and SynchronizeChangedConfig did not include a check to see whether SynchronizationManager should be managing those configs or not.

This meant that when the config was reloaded, the SynchronizeChangedConfig method would run and trigger an update of all the AdminOnly values when the event ConfigFile.ConfigReloaded is invoked which occurs before the event ConfigFileWatcher.OnConfigFileReloaded is invoked. From there I can't quite tell exactly what was happening as the events were invoked but I know values accessed via ConfigEntry<T>.Value for all AdminOnly config entries were not changing as a result.

I added ShouldManage(config) checks to the methods SubscribeToConfigReload, UnsubscribeToConfigReload, and SynchronizeChangedConfig and it restored the intended behavior of changing an AdminOnly config entry value in the local config file updating the value in-game when connected to a dedicated server without Jotunn for a mod with AdminOnlyStrictness.IfOnServer. It also restored saving changes made via an in-game config manager to the local config file.

This has the added benefit of not requiring Jotunn to scan for changes in large config files that it should not even be managing when it synchronizes config changes.

Upon further testing though, if Jotunn is present on the dedicated server then mods with AdminOnlyStrictness.IfOnServer still had the same issue as before when Jotunn was not present on the dedicated server. Any changes made to the local config file would be reset when saving changes made to non-AdminOnly config entries via an in-game config manager. I thought this could be due the process of caching values for comparison to check what changed so I added a check in GetSyncConfigValues to only cache AdminOnly config values from configs that should be managed. While that still seems like a worthwhile change to include, it did not solve the issue.

Solution
After lots of debugging and testing it turned out the issue was that control is never returned back to the local config entries if they should not be managed. So I've added events to check when mod version info is received from the server and a very late check on Game.SpawnPlayer to handle cases where Jotunn is not on the server at all. When either the event fires or the late check finds that no version info was received, SynchronizationManager now returns control of all config entries that it should not manage to the local config.

I have tested connecting to a unmodded dedicated server with MoreVanillaBuildPrefabs and changes from the local config are shown in game and changes in game are shown in the local config file. This is true even when I'm not an admin since MoreVanillaBuildPrfabs only enforces AdminOnly when it is on the server.

The same is behavior occurs when Jotunn is present on the server.

Once MoreVanillaBuildPrefabs is present on the server, all AdminOnly configs are locked unless I am an admin, as intended. Furthermore, if I am an admin and I make changes to the config in-game then those changes are correctly redirected to the server config file. Similarly, if I change the server config file on disk, those changes take effect in-game without altering my local config file.

I have not tested connecting with two different versions of Jotunn as of yet though.

Final Notes
I hope I covered everything. I wanted to be more thorough on this PR since changes to config syncing can have significant impacts for users. This took a long time to trace and solve though so I need to stop here for now.

Fixes issue with AdminOnly config entries for mods with AdminOnlyStrictness.IfOnServer where changing the settings for AdminOnly entries via the local file would not update in-game and changing settings in-game would not save to disk.
Save time parsing long config files that Jotunn should not manage and helps fix the issue of not updating AdminOnly config entries for mods with AdminOnlyStrictness.IfOnServer when Jotunn is not on the server.
Resets the cache upon a new connection, disconnection, and upon receiving server version data
Added a late check to see if mod version info was received from the server or not. If no version info is received then set the flag AllowShouldManageCheckWithoutVersionData and update the admin configs to return control to those we shouldn't manage.

Added convenience method `IsShouldManageValid` for checking if ShouldManage result is valid for use throughout.
These changes can be reverted or excluded from a PR. This is just to make deployment easier in my dev env.
@searica

searica commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Sorry for the extra commits at the end, I hadn't realized that the buildtask dll got included and it was preventing things from building.

This got removed when I was cleaning up all the places I had added a check doing troubleshooting. So I'm restoring the original check now and updating the method description.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant