Horizon Forbidden West PC Technology Discussion (Windows + Linux Benchmarks)

Horizon Forbidden West was one of the most visually impressive titles on the PlayStation 4 and PlayStation 5. Two years later, the same sentiment repeats on the PC. Despite no fancy raytracing features, Guerrila’s Decima Engine still produces a stunning game world and character rendering. I gushed enough about the visuals when I wrote my PS4 Pro and Burning Shores expansion reviews. Therefore, I will not elaborate further on this topic here. Instead, I will focus on the performance aspects. If you are interested in seeing a lot of screenshots, please read my reviews. The PC version is essentially the PS5 version, with a slightly higher level of detail in the distance and some PC-specific improvements, as Digital Foundry had discovered

The most significant benefit of this PC version is the “unlimited” performance that is unshackled from console hardware and the free choice of input peripherals. I played with a keyboard and a mouse because of RSI issues in my thumbs that operating a controller’s thumbsticks worsened. A mouse was also more accurate when aiming with the bow, but I would still have preferred a controller during traversal and combat. The proximity of all buttons to the fingers would have made coordinating the various skills and movement patterns much more effortless. Apart from that, PC’s stalwart input methods worked very well and did not hold me back much. I made up for what I lost in convenience with comfort and precision.

Unlike other modern releases that ate hardware for more or less good reasons, Horizon Forbidden West performed admirably. The YouTube channel eTeknix did enormous work testing 40 GPUs in three different resolutions. Nixxes did an excellent job making the game scalable, and Guerrilla’s initial work optimizing for the weaker consoles also paid off immensely. Even my former 3060 would have been enough to enjoy the Forbidden West with some help from DLSS upscaling.

Let The Numbers Do The Talking

Speaking of hardware and performance, here’s what I measured on my system. It is a Ryzen 7600 with 32GB of DDR5 6000 MT/s memory and an AMD Radeon 7900 XT. The Windows installation ran the game off a Samsung 980 Pro, while Linux had to make do with a Samsung 970 Evo.

I have results for two GPU settings on Windows. The “Default” setting lets the graphics card run as intended by the manufacturer, XFX. My “Tuned” profile slightly undervolts the chip, dials down the power target and maximum clock speed a little, and applies a custom fan curve to make the graphics card bearable under full load.

I recorded the performance in and around Plainsong, one of the larger settlements in the game. This three-minute recording shows my benchmark sequence.


Average FPS1% Low FPSGPU Usage %CPU Usage %
Windows Default



Very High101.086.499.164.2
High113.192.998.365.9
Windows Tuned



Very High109.090.699.063.0
High110.790.298.267.7
Linux Gnome Wayland



Very High102.155.797.949.3
High106.957.597.649.8
Linux Gnome Xorg



Very High100.854.598.147.5
Linux KDE Wayland



Very High101.354.798.248.3

As the numbers show, Linux’s average performance is similar to Windows 11. Unfortunately, this is only half of the story. Staying with the Windows results for a second, the average and 1% lows are very close, highlighting the game’s incredible performance profile.

What I found most curious was the discrepancy between the Default and Tuned GPU profiles using the Very High graphics preset. For some reason, the Tuned profile performed much closer to the High graphics preset in both situations. I verified the results, and the only explanation I can come up with is that the improved efficiency resulting from my tuning allowed for higher sustained clock speeds when under high load. This brought the FPS numbers closer to the lower-quality preset, indicating that the CPU may now be the limit. It was not, however. Lowering the resolution to 1080p yielded more of them frames per second.


Average FPS1% Low FPSGPU Usage %CPU Usage %
Windows Tuned



High131.2104.394.275.7

So… still a mystery.

Linux is a different story, though. At the time of testing, Kernel 6.8.4 and version 1.1.47.0 of Horizon Forbidden West were current. The averages look amazing, but the 1% minimum numbers reflect how the game felt to play. Roaming through the Forbidden West was very choppy and reminiscent of the worst examples of Unreal Engine’s traversal stutter. The combat ran perfectly without hitching, and I suspect the issue was not the raw performance. For some reason, streaming the game world did poorly on Linux. I found the same performance profile in Starfield, which, admittedly, really had its own performance issues. The averages were great, but the 1%-low numbers were dwarfed by the Windows result. Horizon’s problems may stem from Nixxes’ implementation of Direct Storage, although this technology is available on Linux. Limiting the framerate to 60 to give the CPU more time for other things did not change the outcome. I do not think the slower SSD is to blame, as loading the game from the desktop is no slower than on Windows. After all, the PS4 Pro with a SATA SSD also did not have issues.

Is there a CPU configuration issue on Linux that prevents it from delivering its full performance? Mangohud’s logs say the Kernel utilizes the “powersave” CPU governor. But how could it manage the high frame rates if it really saves power? What is noticeable is the lower CPU utilization on Linux. Is that a side-effect of the Proton emulation layer?

This behavior was already annoying at higher VRR frame rates. When I tested the game on my 4K TV, every dip under 60 was exacerbated by how Vsync works, severely impairing the enjoyment of the game. On Windows, 4k60 was as smooth as 60 fps can be. On the plus side, Windows and Linux output a proper surround sound mix when connected to my AV receiver. I loved to hear that.

Lastly, I must give proper kudos to Nixxes for implementing one of the fastest game launches ever. Until now, I considered Kena Bridge of Spirits to be exemplary in this aspect. Horizon Forbidden West was even quicker. The game allowed me to skip every intro movie and logo on launch with a single press of the Escape button. Immediately after, the main screen showed up, and I could continue with my last saved state by pressing Space. Because of the insanely short loading times, I was back in the game, ready to play in just a few seconds. That was true for Windows and Linux.

Famous Last Words

This YouTube recording, which I made for reference, provides an extended look at Linux performance. The video does not contain commentary and only consists of regular gameplay with Mangohud open all the time. The frequent spikes on the frame-time graph convey the experience when playing. The recording is relatively choppy overall, but that likely is a byproduct of having Vsync disabled.

While Linux gaming has become more accessible since the Steam Deck launched, I still cannot entirely replace Windows. There’s always the one game that does not provide a silky-smooth experience. This is only true for some titles, of course. However, everything I tested since quietly resurrecting my Linux experiment delivered imperfect performance.

But, as I certainly already said in my Starfield Technology Discussion, a more powerful processor may reduce this effect 🤷.

I hope this was informative.

Thank you for reading.

Starfield Technology Discussion (Windows & Linux Benchmarks)

In my game reviews, I usually include a section I call “The Nerdy Bits” to examine a game’s technology. I have decided to separate this content from the game review to keep the size manageable. My Marvel’s Midnight Suns review showed me how an expansive technology section can inflate the blog post and maybe even distract from discussing the gameplay, the content, and the story, or potentially deter and intimidate readers because of the total length.

(This blog post is dangerously close to 3000 words 😉.)

I firmly believe that technology is a crucial aspect of a video game. Still, sometimes, I can get carried away and focus too much on it. Other people may not be as interested in that or as curious as I am, and they prefer an overview of the gameplay and a brief summary of the visual fidelity.

For me, a lousy running game can break the immersion. Take Elden Ring on the PlayStation 5, for example. My sister bought the game and thinks it runs fine, like many others who believe it to be the greatest thing since sliced bread. I took a 10-second look, turned the camera around one time, and concluded it ran like crap, and I did not want to play this way. Playing for ten to fifteen more minutes solidified this initial perception. This technology discussion is for gamers like me who are also interested in the technical aspects of a video game and base their purchasing decisions on that.

With this explanation out of the way, let me discuss what I think of Starfield’s technology. I will touch on the art style, the visual fidelity and technology, audio, and performance on Windows and Linux.

Please note that this is not a Digital Foundry-level inspection. For that, click here and here.

Read More »

How To Execute PowerShell And Bash Scripts In Terraform

The first thing to know is what Terraform expects of the scripts it executes. It does not work with regular command line parameters and return codes. Instead, it passes a JSON structure via the script’s standard input (stdin) and expects a JSON structure on the standard output (stdout) stream.

The Terraform documentation already contains a working example with explanations for Bash scripts.

#!/bin/bash
set -e

eval "$(jq -r '@sh "FOO=\(.foo) BAZ=\(.baz)"')"

FOOBAZ="$FOO $BAZ"
jq -n --arg foobaz "$FOOBAZ" '{"foobaz":$foobaz}'

I will replicate this functionality for PowerShell on Windows and combine it with the OS detection from my other blog post.

The trick is handling the input. There is a specific way, since Terraform calls your script through PowerShell, something like this echo '{"key": "value"}' | powershell.exe script.ps1.

$json = [Console]::In.ReadLine() | ConvertFrom-Json

$foobaz = @{foobaz = "$($json.foo) $($json.baz)"}
Write-Output $foobaz | ConvertTo-Json

You access the C# Console class’ In property representing the standard input and read a line to get the data Terraform passes through PowerShell to the script. From there, it is all just regular PowerShell. The caveat is that you can no longer call your script as usual. If you want to test it on the command line, you must type the cumbersome command I have shown earlier.

echo '{"json": "object"}' | powershell.exe script.ps1

Depending on how often you work with PowerShell scripts, you may bump into its execution policy restrictions when Terraform attempts to run the script.

│ Error: External Program Execution Failed
│
│   with data.external.script,
│   on main.tf line 8, in data "external" "script":
│    8:   program = [
│    9:     local.shell_name, "${path.module}/${local.script_name}"
│   10:   ]
│
│ The data source received an unexpected error while attempting to execute the program.
│
│ Program: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
│ Error Message: ./ps-script.ps1 : File
│ C:\Apps\Terraform-Run-PowerShell-And-Bash-Scripts\ps-script.ps1
│ cannot be loaded because running scripts is disabled on this system. For more information, see
│ about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
│ At line:1 char:1
│ + ./ps-script.ps1
│ + ~~~~~~~~~~~~~~~
│     + CategoryInfo          : SecurityError: (:) [], PSSecurityException
│     + FullyQualifiedErrorId : UnauthorizedAccess
│
│ State: exit status 1

You can solve this problem by adjusting the execution policy accordingly. The quick and dirty way is to allow all scripts as is the default on non-Windows PowerShell installations. Run the following as Administrator.

Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine

This is good enough for testing and your own use. If you regularly execute scripts that are not your own, you should choose a narrower permission level or consider signing your scripts.

Another potential pitfall is the version of PowerShell in which you set the execution policy. I use PowerShell 7 by default but still encountered the error after applying the unrestricted policy. That is because the version executed by Terraform is 5. That is what Windows starts when you type powershell.exe in a terminal.

PowerShell 7.4.1
PS C:\Users\lober> Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine
PS C:\Users\lober> Get-ExecutionPolicy
Unrestricted
PS C:\Users\lober> powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\lober> Get-ExecutionPolicy
Restricted
PS C:\Users\lober> $PsVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.22621.2506
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.22621.2506
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Once you set the execution policy in the default PowerShell version, Terraform has no more issues.

A screenshot that shows the Windows Terminal output of the Terraform plan command.

And for completeness sake, here is the Linux output.

A screenshot that shows the Linux terminal output of the Terraform plan command.

You can find the source code on GitHub.

I hope this was useful.

Thank you for reading

How To Detect Windows Or Linux Operating System In Terraform

I have found that Terraform does not have constants or functions to determine the operating system it is running on. You can work around this limitation with some knowledge of the target platforms you are running on. The most common use case is discerning between Windows and Unix-based systems to execute shell scripts, for example.

Ideally, you do not have to do this, but sometimes, you, your colleagues, and your CI/CD pipeline do not utilize a homogeneous environment.

One almost 100% certain fact is that Windows addresses storage devices with drive letters. You can leverage this to detect a Windows host by checking the project’s root path and storing the result in a variable.

locals {
  is_windows = length(regexall("^[a-z]:", lower(abspath(path.root)))) > 0
}

output "absolute_path" {
    value = abspath(path.root)
}

output "operating_system" {
    value = local.is_windows ? "Windows" : "Linux"
}

The output values are for demonstration purposes only. All you need is the regex for potential drive letters and the absolute path of the directory. Any path would do, actually.

The regexall function returns a list of all matches, and if the path starts with a drive letter, the resulting list contains more than zero elements, which you can check with the length function.

You could also check for “/home” to detect a Linux-based system or “/Users” for a macOS computer. In those instances, the source code must always be located somewhere in a user’s directory during execution. That may not be the case in a CI/CD pipeline, so keep that in mind. Here is the result on Windows.

A screenshot that shows the Windows Terminal output of the Terraform plan command.

And here on Linux.

A screenshot that shows the Linux terminal output of the Terraform plan command.

You can find the source code on GitHub.

I hope this was useful.

Thank you for reading

How To Add Microsoft Store Games To Steam

As a gamer, you likely prefer Steam as a game launcher over everything else, notably the Microsoft Store. Steam supports adding non-Steam games, but Microsoft makes it stupidly complicated to run their store content from anywhere else – at least if you do not like Windows shortcuts.

I wanted to add Gears of War 4 to Steam, a game only available in the Microsoft Store. Here is what I did and what should also work for other titles or applications.

First, there is no way around a shortcut. However, it is only temporary and serves as the starting point. If you are lucky, it is all you need. You can delete the shortcut after all is said and done.

Read More »

Pentiment Review – I Recommend 66% Of It (PC & Xbox Series X)

It may come to you as a shocker, but I have never played a point & click adventure game, like the well-known Monkey Island series, for example. It is something I know exists and is beloved, yet I never touched it, despite several releases of the franchise being of my time. Pentiment falls into the same game category, and the coverage I follow had high praise for that title.

So, when I got sick recently, I figured this would be a chill game to pass the time while trying to recover.

Read More »

I Bestow Upon Thee “HotkeyAutoExecute”, My Game Screenshot Automator

HotkeyAutoExecute is a simple single-window tool that lets you manage a list of frequently used hotkeys, of which one is repeatedly executed in configurable intervals.

That was the TLDR blurp, and now let’s get into the details. This tool scratches an itch I had in 2020 when I wanted to simplify the process of taking game screenshots for my reviews. During intense gameplay moments, it is difficult to focus on the game and press a keyboard shortcut to take an image of on-screen action. Therefore, I hacked something that would do the job but was not quite baked to be open-sourced as an application. I have changed that now, and boy, was it more complicated than I would have liked.

Read More »

Convert QKeySequence of QKeySequenceEdit to Native Windows Virtual Key Codes VK_*

In a blog post in 2020, I described how to utilize the WinAPI SendInput() function to emulate hotkey presses to automatically take game screenshots for my video game reviews. While I intended to create a simple GUI application to do the task, I ended up with only a hack because of a massive boulder that Windows threw in my way. Or after me, chasing me down a narrow path.

Forget the boulder.

(Although it would be a fitting metaphor to describe Windows: tall, fat, and destructive to user privacy.)

I wanted a simple input field where the user can press a key sequence that will be executed repeatedly at an interval. Qt conveniently provides QKeySequenceEdit for this purpose, and when I tried to insert the Xbox Game Bar hotkey, it did not register. Well, it did, in that Windows took a screenshot. But it was not recorded by the widget. Windows seems to intercept and eat the key presses. That was when I decided to just hard-code my needs and call it a day.

Two years later, I figured that it was about damn time to fix this, and this is where I ran into issues with the translation of key codes from QKeySequenceEdit and QKeySequence to native Windows virtual key codes.

This is where our adventure begins.

Read More »

Automate Game Screenshot Capture: Windows API SendInput Function with C++

I am trying to write video game reviews after I have finished a game and I like to add some impressions in the form of screenshots to the reviews. There is one problem though: sometimes it is impossible to press the keyboard shortcut to capture a screenshot because the game requires my full attention – and all my fingers. Therefore, I miss out on a lot of action sequences. What does a programmer do in such a situation? Write a tool that scratches the itch.

Read More »

Windows Subsystem for Linux (WSL) Docker: error storing credentials – err: exit status 1, out: Cannot autolaunch D-Bus without X11 $DISPLAY

Recently at work, when copying an application from our internal Docker Registry to Azure, I ran into the following error in my WSL Ubuntu installation.

Login at docker..com
Username: 
Password:
Error saving credentials: error storing credentials - err: exit status 1, out: `Cannot autolaunch D-Bus without X11 $DISPLAY`
ERROR: source registry login failed

The easiest fix I found was to install the gnupg2 and pass packages.

sudo apt install gnupg2 pass 

One important thing to note regarding security: the output mentioned storing the credentials in plain text as a result somewhere in the WSL user’s /home directory. If you are very conscious about where passwords are stored, do not use this solution or remove the password file afterwards. That’s good enough for me at the moment, I just needed to get this to work somehow.

The Linux Experiment: One Month Later

It has been roughly a month since I switched from using Windows 10 as my main operating system to Linux. The reasons for that have all been detailed in The Switching Windows to Linux Experiment blog post. Now I will share a few of the experiences I have made during the first month (it’s been that long already) and what I think about how well it is going.

Let me address the elefant in the room first, the distribution. I think that is likely the first question you, the reader, would ask. The short answer is Pop!_OS by System76.

Read More »

Writing a Custom Backup Solution

If you are a user of any form of computer and care one bit about your sanity, then you probably have a backup strategy. Otherwise, if all hell breaks loose and your whole computer burns to ash or the hard drive melts to a heap of metal, turning it into an ugly door stop, you’ll likely be kinda angry, maybe slightly pissed, your pulse most definitely at 180, that you’ve lost all your data. I’d certainly be, especially about all my pictures of all the festivals and places I’ve been to. 

(And maybe some family 😅)

But, to be honest, I’ve been a bit lazy about backups for some time now. I do have copies of all my important files, but that’s not a backup. It’s a copy. A backup lets you go back in time and get an older version of a file or folder, not just the most recent one that has been synced.

So why is it, that I’m not as diligent as I should be? There are a few factors in that equation. It’s laziness for one, knowledge that I do have at least one copy, the fact that I haven’t had any data loss so far and stinginess. Why the latter? Up until now, being a Windows user (not any more though, on my main machine), I was relying on Acronis True Image, a commercial backup software. However, the version that I own – 2014, I think – stopped being reliable in one of the past Windows 10 versions. I simply don’t want to spend the money any more.

I’m not here to tell you that I have changed my mind on that. No. I’m, of course, coding my own solution. Why wouldn’t I? Everything is done multiple times in the Open Source community.

Read More »

Windows 10: First Impressions (Preview Build 10041)

While I was grooming my unicorn on Crazy-Talk Island I read on the Internet about a thing called Windows 10. Curious as I am, I went out to watch the huge presentation on Jan, 21 where Microsoft officially unveiled the mobile version of Windows 10 and the cool hardware stuff. There’s also a very nice set of videos by Scott Hanselman on YouTube that show the changes from version to version.

Actually I’m very much aware of Windows 10 since the beginning, as a developer I’d be crazy not to, so I registered as a Windows Insider yesterday and downloaded the technical preview build 10041. Here’s a summary of my first impressions.
Read More »

Windows 8.1: One Year Later – I Get It Now

Windows 8 wasn’t all too well received, hardly a secret if you follow the tech press, neither by customers nor by businesses. There are a few folks who like it but they are, like those Windows Phone enthusiasts (that really do exist), a very minor minority (without report).

*Ahem*

About a year ago, I started using Windows 8.1 as my main operating system (which I’ve written about a few months later). Before, it was just a necessity to get the Soundblaster audio card to work. However, going through the same positional-sound problem again after upgrading from 8.0 to 8.1, I’m sure using Windows 8 fixed the problem by accident. Creative’s drivers are just a bulk load of crap, as they’ve always been. Had I not had the iMac as a work computer at that time, I’m not sure I would’ve installed Windows 8 instead of 7, but rather gotten rid of the Soundblaster Z. If you’ve read the post about the sound card, you know I was one of the many people that had an axe to grind with this OS.
Read More »

Windows Phone: 3 Months Later

What started out as a reasonable decision at the beginning of 2014 now reached its climax with the Surface Pro 3: switching away from Apple, in every regard, and move to the Microsoft platform. First the PC, then the phone and lastly the tablet. Since having a Windows based PC is nothing unusual (although I might be one of the few that actually came to like Windows 8 – just as I was one of the few that liked Vista over XP; what does that say about me?) and the Surface is still too new to write about it in any meaningful way, that only leaves us with the phone.
Read More »