Skip to content

Fix Two Point Museum Steam Cloud save placement#1465

Open
kiequoo wants to merge 2 commits into
utkarshdalal:masterfrom
kiequoo:fix/two-point-museum-cloud-save
Open

Fix Two Point Museum Steam Cloud save placement#1465
kiequoo wants to merge 2 commits into
utkarshdalal:masterfrom
kiequoo:fix/two-point-museum-cloud-save

Conversation

@kiequoo
Copy link
Copy Markdown
Contributor

@kiequoo kiequoo commented May 21, 2026

Description

Fix Steam Auto-Cloud path mapping for games whose UFS manifest uses Windows rootoverrides that remap the local save directory away from the cloud upload prefix.

Two Point Museum cloud files were downloading under the raw cloud prefix, where the game could not see them:

AppData/LocalLow/75264032/Saves/Slot1/1003.sav

They now land in the remapped local UFS path:

AppData/LocalLow/Two Point Studios/Two Point Museum/Cloud/75264032/Saves/Slot1/1003.sav

This also bumps the UFS parse cache version for affected remapped apps. On upgrade, the app stores cloud change number 0 to force one full Steam Cloud query while preserving the local file snapshot and prior sync state. That avoids treating the app as never synced and prevents an empty refreshed cloud listing from deleting existing local saves.

Tests added for:

  • Two Point Museum upload prefix mapping.
  • Two Point Museum download placement with compact cloud prefixes.
  • Preserving local saves when a UFS refresh sees empty cloud state.

Recording

N/A - Steam Cloud save path handling is covered by unit tests and does not have a visible UI flow.

Type of Change

  • Bug fix
  • Performance / stability improvement
  • Compatibility improvements
  • Other (requires prior approval)

Checklist

  • If I have access to #code-changes, I have discussed this change there and it has been green-lighted. If I do not have access, I have still provided clear context in this PR. If I skip both, I accept that this change may face delays in review, may not be reviewed at all, or may be closed.
  • This change aligns with the current project scope (core functionality, stability, or performance). If not, it has been explicitly approved beforehand.
  • I have attached a recording of the change.
  • I have read and agree to the contribution guidelines in CONTRIBUTING.md.

Testing

  • ./gradlew :app:testDebugUnitTest --tests "app.gamenative.service.SteamAutoCloudTest"

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced Steam Cloud save synchronization to correctly handle complex cloud directory structures with nested paths
    • Improved cache refresh to preserve local save files during cloud updates
    • Refined cloud path mapping logic for more accurate sync behavior

Review Change Stack

Steam can report Auto-Cloud files under the original cloud prefix even when a Windows rootoverride adds a local subdirectory. Two Point Museum exposes this as cloud prefixes like %WinAppDataLocalLow%75264032/Saves/Slot1/ while the game reads from AppData/LocalLow/Two Point Studios/Two Point Museum/Cloud/75264032/.

Map both compact and slash-separated cloud prefixes to the remapped local path, then preserve any nested suffix from the Steam prefix so downloaded slot saves land where the game expects them.

Adds a SteamAutoCloud regression test using the observed Two Point Museum prefix/filename split.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 945e27d1-e721-4b33-afd1-cdf4fb49cfcc

📥 Commits

Reviewing files that changed from the base of the PR and between 4a6e79d and 998da63.

📒 Files selected for processing (4)
  • app/src/main/java/app/gamenative/service/SteamAutoCloud.kt
  • app/src/main/java/app/gamenative/service/SteamService.kt
  • app/src/main/java/app/gamenative/utils/KeyValueUtils.kt
  • app/src/test/java/app/gamenative/service/SteamAutoCloudTest.kt

📝 Walkthrough

Walkthrough

Steam Cloud save file synchronization logic is refactored to support longest-prefix matching for cloud-to-local path resolution with multiple key variants. UFS path change handling now preserves local file snapshots by writing a cache entry instead of deleting cached metadata, and the parse version is bumped to trigger app definition reparse.

Changes

Steam Cloud sync path resolution and cache preservation

Layer / File(s) Summary
Cloud prefix-to-local path resolution with longest-prefix matching
app/src/main/java/app/gamenative/service/SteamAutoCloud.kt, app/src/test/java/app/gamenative/service/SteamAutoCloudTest.kt
cloudPrefixToLocalPath map now generates multiple cloud-key variants from normalized uploadPath values (including root-only and both concatenated/slash-separated forms). Prefix lookup trims trailing slashes and selects the longest matching key, appending the unmatched remainder to the local base path. Tests validate Two Point Museum upload paths using account-ID child prefixes and download paths with trailing slashes in cloud metadata.
Cache snapshot preservation and version bump
app/src/main/java/app/gamenative/service/SteamService.kt, app/src/main/java/app/gamenative/utils/KeyValueUtils.kt, app/src/test/java/app/gamenative/service/SteamAutoCloudTest.kt
When UFS path logic changes for an app with rootoverrides, the sync handler now writes a change number 0L to changeNumbersDao instead of deleting cached file-change lists, preserving the local file snapshot for the next sync. CURRENT_UFS_PARSE_VERSION bumps from 3 to 4 to trigger reparse of affected Steam app definitions. Test validates that empty cloud listings do not delete preserved local files.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • utkarshdalal/GameNative#142: Modifies SteamAutoCloud cloud-save path/prefix handling using UserFileInfo.substitutedPath, overlapping with this PR's prefix-to-local path mapping logic.
  • utkarshdalal/GameNative#1297: Adjusts SteamAutoCloud's cloudPrefixToLocalPath mapping around normalizing trailing slashes and prefix lookups, directly overlapping with this PR's path-resolution changes.
  • utkarshdalal/GameNative#1157: Modifies KeyValueUtils UFS parse version bumping, directly related to this PR's version update from 3 to 4.

Suggested reviewers

  • utkarshdalal

Poem

🐰 Hop through clouds with longest keys,
Slash-trimmed paths now dance with ease,
Snapshots safe, no files lost,
Parse again to check the cost!
Museums saved, the test suite sings.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix Two Point Museum Steam Cloud save placement' directly and clearly describes the primary change: fixing where Steam Cloud saves are placed for Two Point Museum, which is the main bug being addressed.
Description check ✅ Passed The description is comprehensive and complete, covering the problem, solution, cache version bump, tests added, and testing instructions. It includes most required template sections with detailed context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Bump the UFS parse version so cached SteamApp rows using older path mapping are regenerated.

For apps with UFS rootoverrides, clear the stored Steam app change number while preserving the local file snapshot. The next sync performs a full cloud query and can download files using the corrected path mapping, without turning existing local files into an unnecessary conflict.
@kiequoo kiequoo force-pushed the fix/two-point-museum-cloud-save branch from b3a9885 to 998da63 Compare May 21, 2026 09:59
@kiequoo
Copy link
Copy Markdown
Contributor Author

kiequoo commented May 21, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@kiequoo kiequoo marked this pull request as ready for review May 21, 2026 11:28
@kiequoo kiequoo requested a review from utkarshdalal as a code owner May 21, 2026 11:28
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Re-trigger cubic

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