Has anyone got the Steamworks.net API working with Linux and proton users?
I’ve got a game released on Steam that has been working fine for Windows users. I had no Steamworks API integrated.
Recently I launched v2.1 of the game, which includes some Steamworks API stuff. Previously the save file was just stored in the “C:\Users\Admin\AppData\LocalLow\Developer\Game” folder.
Since adding the Steamworks API, I’m now grabbing the users unique SteamID to create a unique sub folder with the save data, which enables multiple Steam users on the same windows account to have their own save file - something I didn’t realise was being shared before. This also means the game will work better with cloud saves.
Since enabling this feature, however, and adding in cloud saves, I had a friend test the game who did it with Linux + Proton and his game crashes. It loads fine, but as soon as the game tries to read from the save file, it just stalls. The reason appears to be because the game is not creating a save file since adding in the Steamworks API and trying to use the SteamID for the filepath.
A quick birds eye view of what my code is doing.
This is the old filePath pre-Steamworks, which I called “genericFilePath”:
genericFilePath = Application.persistentDataPath + "/save.data";```
Then on "Start()" I set the 'UniqueFilePath' which is what's created with the Steamworks.net API for each Steam user:
```csharp
private void Start()
{
genericFilePath = Application.persistentDataPath + fileName;
if (SteamManager.Initialized)
{
steamID = SteamUser.GetSteamID().m_SteamID;
uniqueUserFilePath = Application.persistentDataPath + "/" + steamID + fileName;
}
}
Here is saving:
public void SaveGame(GameData saveData)
{
string filePath = genericFilePath;
if (SteamManager.Initialized)
filePath = uniqueUserFilePath;
if (SaveFileExistsAt(uniqueUserFilePath) == false)
Directory.CreateDirectory(Path.GetDirectoryName(uniqueUserFilePath));
FileStream dataStream = new FileStream(filePath, FileMode.Create);
BinaryFormatter converter = new BinaryFormatter();
converter.Serialize(dataStream, saveData);
dataStream.Close();
}
And here is loading:
public GameData LoadGame()
{
GameData saveData;
if (SteamManager.Initialized && SaveFileExistsAt(uniqueUserFilePath))
{
// File exists
FileStream dataStream = new FileStream(uniqueUserFilePath, FileMode.Open);
BinaryFormatter converter = new BinaryFormatter();
saveData = converter.Deserialize(dataStream) as GameData;
dataStream.Close();
}
else if (SaveFileExistsAt(genericFilePath))
{
FileStream dataStream = new FileStream(genericFilePath, FileMode.Open);
BinaryFormatter converter = new BinaryFormatter();
saveData = converter.Deserialize(dataStream) as GameData;
dataStream.Close();
SaveGame(saveData);
}
return saveData;
}
This isn’t the whole file, just the key points. Bear in mind it does work for Windows, but not on Linux / Proton.
In the Load() function, if there is no save file at the UniqueFilePath, but there is one at the GenericFilePath, it copies the save data into the unique path.
Anyway, Application.persistentDataPath is supposed to be cross-platform which is why I use it so I can’t see what’s wrong? Hence why I’m wondering if anyone has had experience with Linux and Proton and got it working, and can see something I’m missing.