Far Cry Primal

Far Cry Primal

Not enough ratings
Advanced Save Manager for Permadeath Mode
By VaultBoee
Far Cry Primal - Save Backup Tool for Permadeath Mode

This tool automatically backs up your Far Cry Primal saves while playing and lets you restore previous backups.

Перейти на версию на Русском
   
Award
Favorite
Favorited
Unfavorite
Features:
  • Creates backups every minute (customizable) or when you press Enter
  • Organizes saves with timestamps for easy reference
  • Press R to restore any previous backup (perfect for Permadeath!)
  • Keeps your progress safe during challenging gameplay
Disabling cloud save synchronization in Uplay
Before I start explaining how to manipulate with your save files, I must strongly recommend you to disable cloud save synchronization. Methods I'm going to suggest might not work properly with cloud synchronization turned on. Furthermore, it is better to make your own saves backup rather than rely on Ubisoft cloud – there are numerous cases when cloud saves became corrupt and users lost their entire progress.
Disable cloud save synchronization in Uplay general settings:
Code
$Source="2029"; $BackupRoot=$Source+"-backups"; $GameProcess="FCPrimal*" $TimeoutSeconds=60; $MaxBackups=100; $PageSize=10 if(-not(Test-Path $BackupRoot)){ New-Item -ItemType Directory -Path $BackupRoot -Force|Out-Null } function Update-StatusLine{ param([string]$Message,[System.ConsoleColor]$Color=[System.ConsoleColor]::White) Write-Host -NoNewline "`r$(' '*120)"; Write-Host -NoNewline "`r$Message" -ForegroundColor $Color } function Get-LastBackupInfo{ $backups=@(Get-ChildItem -Path $BackupRoot -Directory|Sort-Object CreationTime -Descending) if($backups.Count -eq 0){return "No backups found"} return "$($backups[0].Name) - Created: $($backups[0].CreationTime)" } function Reset-Screen{ Clear-Host; Write-Host "===== Far Cry Primal Save Backup System =====" -ForegroundColor Cyan Write-Host "Backup interval: $TimeoutSeconds seconds" -ForegroundColor Gray Write-Host "Maximum backups: $MaxBackups" -ForegroundColor Gray Write-Host "Last backup: $(Get-LastBackupInfo)" -ForegroundColor Yellow Write-Host "=============================================" -ForegroundColor Cyan Write-Host "Press [Enter] for manual backup, [R] to restore." -ForegroundColor Cyan; Write-Host } function List-Backups{ param([int]$Page=1,[switch]$CountOnly) $backups=@(Get-ChildItem -Path $BackupRoot -Directory|Sort-Object CreationTime -Descending) if($backups.Count -eq 0){ Update-StatusLine "No backups found." -Color Red; Write-Host; return $false } if($CountOnly){return $backups} $totalPages=[math]::Ceiling($backups.Count/$PageSize) if($Page -lt 1){$Page=1}; if($Page -gt $totalPages){$Page=$totalPages} $start=($Page-1)*$PageSize; $end=[math]::Min($start+$PageSize-1,$backups.Count-1) Write-Host; Write-Host "Available backups (Page $Page of $totalPages):" -ForegroundColor Cyan for($i=$start;$i -le $end;$i++){ Write-Host "[$(($i+1))] $($backups[$i].Name) - Created: $($backups[$i].CreationTime)" -ForegroundColor Green } Write-Host; Write-Host "Showing backups $($start+1)-$($end+1) of $($backups.Count)" -ForegroundColor Gray if($totalPages -gt 1){ Write-Host "Type 'N' for next page, 'P' for previous page, or a backup ID to restore." -ForegroundColor Cyan } return $backups } function Cleanup-OldBackups{ $backups=@(Get-ChildItem -Path $BackupRoot -Directory|Sort-Object CreationTime) $backupsToRemove=$backups.Count-$MaxBackups if($backupsToRemove -gt 0){ for($i=0;$i -lt $backupsToRemove;$i++){ Remove-Item -Path $backups[$i].FullName -Recurse -Force } } } function Create-Backup{ $saveFile=Join-Path $Source "1.save" if(-not(Test-Path $saveFile)){ Update-StatusLine "Save file does not exist!" -Color Red; Start-Sleep -Seconds 1; return } $fileAccessible=$false; $attempts=0 while(-not $fileAccessible -and $attempts -lt 5){ try{ $stream=[System.IO.File]::Open($saveFile,'Open','Read','ReadWrite'); $stream.Close(); $fileAccessible=$true } catch{ $attempts++; Update-StatusLine "Waiting for save file to be unlocked... (Attempt $attempts/5)" -Color Yellow; Start-Sleep -Seconds 1 } } if(-not $fileAccessible){ Update-StatusLine "Could not access save file after 5 attempts." -Color Red; Start-Sleep -Seconds 1; return } $now=Get-Date; $dest=Join-Path $BackupRoot ("backup-{0:yyyy-MM-dd_HH-mm-ss}\2029" -f $now) New-Item -ItemType Directory -Path $dest -Force|Out-Null Update-StatusLine "Backing up save files to $dest..." -Color Green Copy-Item -Path "$Source\*" -Destination $dest -Recurse -Force Update-StatusLine "Backup completed at $($now.ToString("HH:mm:ss"))" -Color Green Cleanup-OldBackups; Reset-Screen } function Restore-Backup{ $inRestoreMode=$true; Write-Host Write-Host "IMPORTANT: Make sure you're closed the game before restoring a save!" -ForegroundColor Yellow; Write-Host try{ $page=1; $backups=List-Backups -Page $page if(-not $backups){ Reset-Screen; return } $restored=$false while(-not $restored){ $input=Read-Host "Enter backup ID to restore, 'N' for next page, 'P' for previous page, or press Enter to cancel" if([string]::IsNullOrEmpty($input)){ Reset-Screen; return } if($input -eq "N" -or $input -eq "n"){ $page++; $backups=List-Backups -Page $page; continue } elseif($input -eq "P" -or $input -eq "p"){ $page--; $backups=List-Backups -Page $page; continue } $idNum=0 if(-not [int]::TryParse($input,[ref]$idNum)){ Update-StatusLine "Invalid input. Please enter a number or N/P for pagination." -Color Red; Start-Sleep -Seconds 1; continue } if($idNum -lt 1 -or $idNum -gt $backups.Count){ Update-StatusLine "ID out of range. Please enter a valid ID." -Color Red; Start-Sleep -Seconds 1; continue } $selectedBackup=$backups[$idNum-1]; $backupSourcePath=Join-Path $selectedBackup.FullName "2029" if(-not(Test-Path $backupSourcePath)){ Update-StatusLine "Backup files not found. The backup may be corrupted." -Color Red; Start-Sleep -Seconds 1; continue } Update-StatusLine "Restoring backup: $($selectedBackup.Name)" -Color Yellow if(-not(Test-Path $Source)){ New-Item -ItemType Directory -Path $Source -Force|Out-Null } Copy-Item -Path "$backupSourcePath\*" -Destination $Source -Recurse -Force Update-StatusLine "Backup restored successfully!" -Color Green; Start-Sleep -Seconds 1 $restored=$true; Reset-Screen Update-StatusLine "Backup $($selectedBackup.Name) restored. Next backup in $TimeoutSeconds seconds." -Color Green } }finally{ $inRestoreMode=$false } } Reset-Screen $lastBackupTime=Get-Date; $gameWasRunning=$false; $inRestoreMode=$false; $lastStatusMessage="" while($true){ $gameIsRunning=$null -ne (Get-Process|Where-Object{$_.ProcessName -like $GameProcess}|Select-Object -First 1) if($gameIsRunning -and -not $gameWasRunning){ Update-StatusLine "Game is running. Backup system active." -Color Green; Start-Sleep -Seconds 1 }elseif(-not $gameIsRunning -and $gameWasRunning){ Update-StatusLine "Game is not running. Waiting for game to start..." -Color Yellow } $gameWasRunning=$gameIsRunning if(-not $inRestoreMode -and [Console]::KeyAvailable){ $key=[Console]::ReadKey($true) if($key.Key -eq "Enter"){ Update-StatusLine "Manual backup requested" -Color Cyan if($gameIsRunning){ Create-Backup; $lastBackupTime=Get-Date } else{ Update-StatusLine "Game is not running, backup not created." -Color Yellow; Start-Sleep -Seconds 1 } }elseif($key.Key -eq "R"){ Update-StatusLine "Restore requested" -Color Cyan; Start-Sleep -Milliseconds 500 $inRestoreMode=$true; Restore-Backup; $inRestoreMode=$false; $lastBackupTime=Get-Date } } if(-not $inRestoreMode -and $gameIsRunning){ $currentTime=Get-Date; $timeDiff=($currentTime-$lastBackupTime).TotalSeconds if($timeDiff -ge $TimeoutSeconds){ Create-Backup; $lastBackupTime=Get-Date } $timeLeft=[Math]::Max(0,$TimeoutSeconds-$timeDiff) $statusMessage="Next backup in $([Math]::Ceiling($timeLeft)) seconds. Press [Enter] for manual backup, [R] to restore." if($statusMessage -ne $lastStatusMessage){ Update-StatusLine $statusMessage -Color Cyan; $lastStatusMessage=$statusMessage } }elseif(-not $inRestoreMode -and -not $gameIsRunning){ $statusMessage="Waiting for game to start. Press [Enter] to force backup, [R] to restore." if($statusMessage -ne $lastStatusMessage){ Update-StatusLine $statusMessage -Color Yellow; $lastStatusMessage=$statusMessage } } Start-Sleep -Milliseconds 100 }
How to Set Up & Use
Create the script file:
  • Open Notepad
  • Copy and paste the code above
  • Save as "Save_backup.ps1" in this location:
    C:\Program Files (x86)\Ubisoft\Ubisoft Game Launcher\savegames\YOUR-UNIQUE-ID\
  • The script must be in the same folder that contains your "2029" game save folder

Finding Your Save Location:
  • Look for a folder containing the "2029" directory
  • Place the script alongside the "2029" folder, not inside it

Run the script:
  • Right-click the PS1 file
  • Select "Run with PowerShell"
  • If prompted about execution policy, type "Y"

Using it:
  • Keep the PowerShell window open while playing
  • Press Enter anytime for immediate backup
  • Press R to view and restore backups
  • IMPORTANT: Close game before restoring a save!
Notes
  • Run the script before starting the game
  • To change backup frequency, edit the $TimeoutSeconds value (60 = 1 minute)
  • To change maximum backups kept, edit the $MaxBackups value (default: 100)
  • Enjoy playing without the frustration of permanent death!

Customization Options:
You can modify these parameters at the top of the script:
  • $TimeoutSeconds - Time between automatic backups (in seconds)
  • $MaxBackups - Maximum number of backups to keep before deleting old ones
  • $PageSize - Number of backups shown per page when restoring
Troubleshooting Execution Policy Issues when running PS1 File
Special thanks to PatrikManus07 for this helpful solution!

When attempting to run a PowerShell script file with a
.ps1
extension, you might encounter an error related to the script execution policy. This guide will show you how to resolve this issue without requiring administrator privileges, using the
Set-ExecutionPolicy
command. If your file runs without any issues, you won't need to follow these steps.

Step-by-Step Instructions
    [] Open PowerShell: Search for "PowerShell" in your Windows Start menu and open it. You do not need to run it as an administrator for this method.[] Change the Execution Policy: In the PowerShell window, type the following command:
    Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
    This command sets the RemoteSigned execution policy only for the current user. This means that scripts you create on your own computer will run without issues, while scripts downloaded from the internet must be signed by a trusted publisher before they can be executed. This strikes a balance between security and convenience.[] Confirm the Change: PowerShell might ask you to confirm the change to the execution policy. Press
    Y
    and then
    Enter
    to proceed.[] Run Your PS1 File: You can now run your
    .ps1
    file by simply typing its full path in PowerShell (e.g.,
    C:\MyScripts\MyScript.ps1
    ) or by navigating to the directory where the file is located and typing its name (e.g.,
    .\MyScript.ps1
    ).

11 Comments
DogeChipszz 3 Aug @ 7:52am 
oh no way! beluga! and aiden!
PatrikManus07 17 Jul @ 5:24am 
No problem. I hope that i could help out some people :D
VaultBoee  [author] 17 Jul @ 3:50am 
Thanks for your info PatrikManus07! I added your solution to the guide :)
PatrikManus07 16 Jul @ 7:36am 
Yes, sure! The first thing i needed to do just open the Powershell and you type this this commad if you don't want to run anything as an administrator .
Here the code: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
After this i could open the PS1 file.
VaultBoee  [author] 15 Jul @ 1:55am 
PatrikManus07, Great! Please share your workaround, it will be very helpful for others who might encounter this issue in the future.
PatrikManus07 14 Jul @ 1:28pm 
I needed some help from Chat GPT to set up this powershell policy but its working thanks <3
VaultBoee  [author] 22 May @ 3:09am 
Can you try copying your save files to a safe location and then start a new game?
Do the lags disappear when you do that?
VaultBoee  [author] 22 May @ 3:08am 
Bee nis The COOM LORD, Totally bizarre...
All this script does is copy and paste save folders and make backups. Nothing more, nothing less.
Bee nis The COOM LORD 21 May @ 6:41pm 
Yes, Close the game, Clicked r, then 1 for the first auto save. waited a min, booted it up. It was in the correct save but it absolutly would not stop dropping frames and freezing at 1fps.
VaultBoee  [author] 21 May @ 2:27pm 
Bee nis The COOM LORD, did you closed the game before loading save?