Skip to content

fix: set ExeRunDir to game root in ColdClientLoader.ini#775

Merged
utkarshdalal merged 1 commit intoutkarshdalal:masterfrom
kiequoo:new-star-gp
Mar 22, 2026
Merged

fix: set ExeRunDir to game root in ColdClientLoader.ini#775
utkarshdalal merged 1 commit intoutkarshdalal:masterfrom
kiequoo:new-star-gp

Conversation

@kiequoo
Copy link
Copy Markdown
Contributor

@kiequoo kiequoo commented Mar 9, 2026

Since the initial ColdClientLoader implementation (77c8e15), ExeRunDir has been left empty. When empty, ColdClientLoader defaults the working directory to the executable's parent directory. This is fine for games whose exe sits at the game root, but breaks games like New Star GP where the exe lives in a subdirectory (e.g. release/NSGP.exe).

Steam itself always launches games with the working directory set to the game install root, not the exe's subdirectory. New Star GP stores its save file (UserData.txt) in the game install root, and its UFS config declares it there too. The game opens UserData.txt as a relative path, so when CWD is release/ instead of the game root, the file is never found and progress cannot be loaded.

Setting ExeRunDir=steamapps\common<gameName> matches Steam's behaviour and fixes cloud save loading for any game whose executable is not at the root of the install directory.


Summary by cubic

Set ExeRunDir in ColdClientLoader.ini to the game install root (steamapps\common\<gameName>) using the actual install folder name from getAppDirName(). This matches Steam’s working directory and fixes cloud save loading for New Star GP and other games with executables in subfolders.

Written for commit 657ea54. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes
    • Generated Steam client INI files now populate the game's runtime directory from the Steam installation path.
    • The runtime directory field is no longer left empty for installed games, improving launch configuration accuracy and reducing manual edits.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 9, 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: c8bba704-ef47-4dd0-824f-a4ceaf7aa1cd

📥 Commits

Reviewing files that changed from the base of the PR and between 4d9708d and 657ea54.

📒 Files selected for processing (1)
  • app/src/main/java/app/gamenative/utils/SteamUtils.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/app/gamenative/utils/SteamUtils.kt

📝 Walkthrough

Walkthrough

In writeColdClientIni, gameName is obtained from SteamService.getAppDirPath(steamAppId), a new local exeRunDir = "steamapps\\common\\$gameName" was added, and the generated INI's ExeRunDir is set to that value instead of being empty.

Changes

Cohort / File(s) Summary
Steam configuration update
app/src/main/java/app/gamenative/utils/SteamUtils.kt
gameName now taken from SteamService.getAppDirPath(steamAppId); added exeRunDir = "steamapps\\common\\$gameName" and populated ExeRunDir=$exeRunDir in the generated ColdClientLoader.ini (replacing previous empty value).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐇 I hopped through folders, noses twitching bright,
Found steamapps\common under moonlight,
I set ExeRunDir with a handy cheer,
No empty lines, the path is clear,
A little hop — the launcher’s right.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: set ExeRunDir to game root in ColdClientLoader.ini' directly and clearly summarizes the main change: setting the ExeRunDir field to the game root directory in the ColdClientLoader.ini configuration.

✏️ 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.

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 1 file

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/app/gamenative/utils/SteamUtils.kt`:
- Around line 327-330: The Exe/ExeRunDir are built from
getAppDirName(getAppInfoOf(steamAppId)) which can differ from the real on-disk
folder; change the construction to use the actual install directory name derived
from File(SteamService.getAppDirPath(steamAppId)).name (or a shared helper) so
the INI paths match createAppManifest() and the manifest/symlink. Update the
occurrences that build exePath/exeRunDir (lines using getAppDirName(...) and
container.executablePath) and the analogous code at the other site (around lines
353-354) to compute gameDirName =
File(SteamService.getAppDirPath(steamAppId)).name and then build
"steamapps\\common\\$gameDirName\\$executablePath" and
"steamapps\\common\\$gameDirName" accordingly. Ensure container.executablePath
is still normalized (replace "/" with "\\") before composing the final strings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 28250dee-726d-42b9-b8bf-c97385a285bc

📥 Commits

Reviewing files that changed from the base of the PR and between cf29ca7 and 1e1d9d4.

📒 Files selected for processing (1)
  • app/src/main/java/app/gamenative/utils/SteamUtils.kt

@kiequoo kiequoo force-pushed the new-star-gp branch 3 times, most recently from 5f528b3 to 4d9708d Compare March 13, 2026 15:48
@utkarshdalal
Copy link
Copy Markdown
Owner

Are you sure about this? It should work just fine for nested folders, for instance release/NSGP.exe's executable directory will be release

@kiequoo
Copy link
Copy Markdown
Contributor Author

kiequoo commented Mar 18, 2026

Are you sure about this? It should work just fine for nested folders, for instance release/NSGP.exe's executable directory will be release

I forgot to actually mention that this is about the save file. While the game boots fine without this fix, setting the ExeRunDir means it can find the save file correctly.

@utkarshdalal
Copy link
Copy Markdown
Owner

@kiequoo , which game did this fix? Surprised this affects game saves at all!


internal fun writeColdClientIni(steamAppId: Int, container: Container) {
val gameName = getAppDirName(getAppInfoOf(steamAppId))
val gameName = File(SteamService.getAppDirPath(steamAppId)).name
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This line doesn't need changing no?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

True, this was a suggestion of your coderabbitai :)

@kiequoo
Copy link
Copy Markdown
Contributor Author

kiequoo commented Mar 22, 2026

@kiequoo , which game did this fix? Surprised this affects game saves at all!

New Star GP (appid 2217580), whose save (UserData.txt) uses root: gameinstall with no subdirectory, and the executable lives in release/. Without ExeRunDir, Wine sets CWD to release/, so the save ends up at .../release/UserData.txt instead of .../UserData.txt where SteamAutoCloud looks.

Since the initial ColdClientLoader implementation (77c8e15), ExeRunDir
has been left empty. When empty, ColdClientLoader defaults the working
directory to the executable's parent directory. This is fine for games
whose exe sits at the game root, but breaks games like New Star GP where
the exe lives in a subdirectory (e.g. release/NSGP.exe).

Steam itself always launches games with the working directory set to the
game install root, not the exe's subdirectory. New Star GP stores its
save file (UserData.txt) in the game install root, and its UFS config
declares it there too. The game opens UserData.txt as a relative path,
so when CWD is release/ instead of the game root, the file is never
found and progress cannot be loaded.

Setting ExeRunDir=steamapps\common\<gameName> matches Steam's behaviour
and fixes cloud save loading for any game whose executable is not at the
root of the install directory.
@utkarshdalal
Copy link
Copy Markdown
Owner

Can you confirm that other games that have executables in subdirectories and at the root keep working? And can find cloud saves? Worried that games may stop working - we had to set this for wine (not Goldberg as you've done here) because games would only run through the container and not the play button.

@kiequoo
Copy link
Copy Markdown
Contributor Author

kiequoo commented Mar 22, 2026

Can you confirm that other games that have executables in subdirectories and at the root keep working? And can find cloud saves? Worried that games may stop working - we had to set this for wine (not Goldberg as you've done here) because games would only run through the container and not the play button.

I just checked my library and I found JellyCar Worlds has it's executable in a windows/ directory - can confirm it's working fine on this branch. Also tried various other games and they also work fine.

@utkarshdalal utkarshdalal merged commit 69cae38 into utkarshdalal:master Mar 22, 2026
2 checks passed
@utkarshdalal
Copy link
Copy Markdown
Owner

Need to revert this, people are reporting games breaking
Uploading Screenshot_20260324_163842_Discord.jpg…

@kiequoo
Copy link
Copy Markdown
Contributor Author

kiequoo commented Mar 25, 2026

Need to revert this, people are reporting games breaking

Uploading Screenshot_20260324_163842_Discord.jpg…

Not having much luck with my PRs recently 😅

kiequoo added a commit to kiequoo/GameNative that referenced this pull request Mar 25, 2026
PR utkarshdalal#775 introduced ExeRunDir to fix save loading in New Star GP, whose
exe lives in a subdirectory (release/NSGP.exe) and opens saves via a
relative path from the game install root. Without ExeRunDir, ColdClient-
Loader defaults the working directory to the exe's parent, so the save
file was never found.

However, hardcoding ExeRunDir to the game root broke games like Batman:
Arkham Asylum GOTY (reverted in PR utkarshdalal#950), which declares workingdir:
Binaries in its appinfo. For these games, the correct CWD is the
subdirectory, not the root — and the previous empty ExeRunDir happened
to work because ColdClientLoader defaulted to the exe's parent.

The fix reads workingDir from the Steam launch config (LaunchInfo) and
appends it to the game root for ExeRunDir when present, falling back to
the game root when absent. This matches Steam's own behaviour across all
cases observed in the wild.

The INI content is extracted into generateColdClientIni() for testability,
with unit tests covering the Batman and New Star GP cases and edge cases
such as trailing slashes and forward-slash normalisation.

Fixes: utkarshdalal#775
Fixes: utkarshdalal#950
@kiequoo
Copy link
Copy Markdown
Contributor Author

kiequoo commented Mar 25, 2026

Attempt 2: #1012

Confirmed working with both New star GP (as per this PR) and Batman Arkham Asylum

kiequoo added a commit to kiequoo/GameNative that referenced this pull request Mar 27, 2026
PR utkarshdalal#775 introduced ExeRunDir to fix save loading in New Star GP, whose
exe lives in a subdirectory (release/NSGP.exe) and opens saves via a
relative path from the game install root. Without ExeRunDir, ColdClient-
Loader defaults the working directory to the exe's parent, so the save
file was never found.

However, hardcoding ExeRunDir to the game root broke games like Batman:
Arkham Asylum GOTY (reverted in PR utkarshdalal#950), which declares workingdir:
Binaries in its appinfo. For these games, the correct CWD is the
subdirectory, not the root — and the previous empty ExeRunDir happened
to work because ColdClientLoader defaulted to the exe's parent.

The fix reads workingDir from the Steam launch config (LaunchInfo) and
appends it to the game root for ExeRunDir when present, falling back to
the game root when absent. This matches Steam's own behaviour across all
cases observed in the wild.

The INI content is extracted into generateColdClientIni() for testability,
with unit tests covering the Batman and New Star GP cases and edge cases
such as trailing slashes and forward-slash normalisation.

Fixes: utkarshdalal#775
Fixes: utkarshdalal#950
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.

2 participants