Horizon Zero Dawn Joystick or Gamepad support

Hello,
I want to play Horizon Zero Dawn, purchased the Gog Version. So installed it via Heroic and started the game, everything looks great, runs smooth no crashes.
Then i had the great idea i want to play via my DS4 Controller, so plugged it into my PC, but I could not get it to work with this specific game. If I use programs like sc-controller the game crashes after a few minutes, every time. I checked the controller in the system settings all works, checked the controller in wine control all fine, even rumble works. Added xinput with winetricks, no changes.
I already wasted a few hours with this problem.

Maybe somebody had a similar issue with another game or exactly the same game. I don’t want to crawl back to Win10 for joystick support.

Some games straight up don’t work. If the game already has controller issues on windows. It only gets worse on linux. I did a quick Google search for controller issues with that game on Windows and there are countless reddit results that seem to have that issue on Windows and a variety of things that work for some and not others. While I did not spend too much time going down this rabbit hole. One thing I read on a Reddit thread that seemed to work for one person was to enter the overworld via keyboard and mouse and then start using the controller. They said to never use it in the menu. Anyways. I don’t have the game, so I am not sure if the problem is solvable.

Thank you, I tried it, but no success.
Installed the game under win10 and the controller just works great. I really like Linux, and I am amazed how much games are working so great, but some things are still not that good, like controller support, don’t know why.

I meant to ask but did you try running the game via steam as a non steam game to see if Proton would fix the issue?

I have tried that, but it did not work. I have also tried proton-ge and wine-ge, but both did not work. At Friday I will try a Bluetooth dongle instead of usb, but my hopes are low.

i’m about to install the game and see if i can get it to work myself.

I used sc-controller and that made the controller work. The game has not crashed for me. Not yet at least. I haven’t made it past the intro movie yet, but I’ll let you know what happens when I get to the actual game play.

Edit:
For whatever reason the game only launches using regular wine, steam wouldn’t launch it at all. Anyways, it worked even during gameplay without crashing using sc-controller. I tried both wired and via bluetooth. Both worked fine for me.

Edit2:
After a bit more testing, sc controller seems to work better with bluetooth than through wired. For example if the wired connection is interrupted for any reason. sc controller and the game no longer recognize the controller. However with bluetooth. I just turn the controller back on and it kept working without having to restart the game or sc-controller.

Edit3:
Since sc-controller works for me without crashing. Let me know what error you are getting.

1 Like

Thank you very much. I have only tried usb with sc-controller, but the game crashes after a few minutes. The Bluetooth dongle was delivered yesterday. I was able to establish a connection, but it does not work yet, so I have to solve this problem first.

Can’t even get my DS4 to work via Bluetooth. Installed blueman, enabled Bluetooth, paired the DS4 controller, but no input. Can’t get my system to generate a joydev. Struggled to find a solution for the last few hours. Linux is a mystery, sometime everything works great, and sometimes I just can’t figure out why it does not work.

@d-air1 Finally worked out the bluetooth problem, different topic, but when i start the game with sc-controller it crashes after a few minutes.

What error happens when it crashes though? A random guess is maybe sc-controller needs to be rebuilt or something?

I’ve got this version from the AUR:

sc-controller 0.4.8.11-1

If it is possible then I call the system monitor and end the task of the game, if not I just reboot. I don’t know which message I get during a crash. Is there a way to read the logs?

Have the same version of sc-controller and I rebuilt it, but the game still crashes.

Launch the game from the terminal and when it crashes. Copy and paste the terminal output here. Maybe something there will be useful…

1 Like

Do you by chance have a nvidia gpu? This game is known to crash for multiple reasons: even on windblows. I played it for quite a while on EOS through steam, and ran into a crashing issue, but I think it s due to my nvidia gpu. I could play in windowed mode, but not full screen. Every time I started game I had to go to settings, change to full screen, save changes, and then immediately change to windowed mode again. I could then play game crash free. My problem is probably not related to yours, but you could try changing different resolution modes.

Not sure about OP but, I have an rtx 3080.

@sempterobit Yes i have a NVIDIA card RTX 3070. I am thinking about a rx 6800, because i can’t undervolt the nvidia card on Linux, or at least i have not found a solution.
So i have started both sc-controller and horizon via terminal here are the logs until crash.

  1. Horizon:
[saeniv@saeniv-b660mprors ~]$ xdg-open heroic://launch/gog/1209025141
[saeniv@saeniv-b660mprors ~]$ 
DevTools listening on ws://127.0.0.1:9222/devtools/browser/2e163b78-dc3d-4731-9770-40fe0ba35157
(09:22:59) INFO:    [Legendary]:        Legendary location: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary
(09:22:59) INFO:    [Gog]:              GOGDL location: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl
(09:22:59) INFO:    [Connection]:       Connectivity: check-online
(09:22:59) INFO:    [Connection]:       Pinging external endpoints
(09:22:59) INFO:    [Backend]:          DRM module staus {
  oimompecagnajdejgnnjijobebaeigek: {
    name: 'Widevine Content Decryption Module',
    status: 'new',
    version: '4.10.2557.0'
  }
}
libva error: vaGetDriverNames() failed with unknown libva error
APPIMAGE env is not defined, current application is not an AppImage
(09:22:59) WARNING: [Backend]:          Protocol already registered.
(09:23:00) INFO:    [Connection]:       Connectivity: online
(09:23:00) INFO:    [Gog]:              Checking if login is valid
(09:23:00) INFO:    [Gog]:              Running command: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json auth
(09:23:00) INFO:    [Backend]:          Loading Screen Ready
(09:23:00) INFO:    [Frontend]:         Refreshing undefined Library
(09:23:00) WARNING: [Backend]:          refresh not implemented on Sideload Library Manager
(09:23:00) INFO:    [Gog]:              Running command: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json auth
(09:23:00) INFO:    [Legendary]:        Refreshing library...
(09:23:00) INFO:    [Legendary]:        Refreshing Epic Games...
(09:23:00) INFO:    [Legendary]:        Game list updated, got 383 games & DLCs
(09:23:00) INFO:    [Backend]:          Frontend Ready
(09:23:00) INFO:    [ProtocolHandler]:  received 'heroic://launch/gog/1209025141'
(09:23:00) INFO:    [Backend]:          AreWeAntiCheatYet data downloaded
(09:23:00) INFO:    [Backend]:          Launching Horizon Zero Dawn™ Complete Edition (1209025141)
(09:23:00) INFO:    [Backend]:          Preventing display from sleep
(09:23:00) INFO:    [Backend]:          Preventing machine to sleep
(09:23:00) INFO:    [Backend]:          Checking for new Heroic Updates
(09:23:00) INFO:    [Backend]:          Checking for current version changelog
(09:23:00) INFO:    [Gog]:              Getting GOG library
(09:23:00) INFO:    [Gog]:              Running command: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json auth
(09:23:00) INFO:    [Legendary]:        Running command: XDG_CONFIG_HOME=/home/saeniv/.config/heroic/legendaryConfig /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary --version
(09:23:00) INFO:    [Gog]:              Running command: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json --version
(09:23:00) INFO:    [Nile]:             Running command: XDG_CONFIG_HOME=/home/saeniv/.config/heroic/nile_config /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/nile --version
(09:23:00) INFO:    [Gog]:              Saved username to config file
(09:23:00) INFO:    [Legendary]:        Running command: XDG_CONFIG_HOME=/home/saeniv/.config/heroic/legendaryConfig /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary list --third-party
(09:23:00) INFO:    [Backend]:          
System Information:
CPU: 12x 12th Gen Intel(R) Core(TM) i5-12500
Memory: 33.41 GB (used: 2.28 GB)
GPUs:
  GPU 0:
    Name: NVIDIA Corporation GA104 [GeForce RTX 3070]
    IDs: D=2484 V=10de SD=404c SV=1458
    Driver: nvidia
  GPU 1:
    Name: Intel Corporation Alder Lake-S GT1 [UHD Graphics 770]
    IDs: D=4690 V=8086 SD=4690 SV=1849
    Driver: i915
OS: EndeavourOS 6.5.4-arch2-1 (linux)

The current system is not a Steam Deck
We are not running inside a Flatpak container

Software Versions:
  Heroic: 2.9.2 Boa Hancock
  Legendary: 0.20.32 Dark Energy (hotfix #6)
  gogdl: 0.7.3
  Nile: 1.0.0 Jonathan Joestar

(09:23:00) INFO:    [Legendary]:        Running command: XDG_CONFIG_HOME=/home/saeniv/.config/heroic/legendaryConfig /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary --version
(09:23:00) INFO:    [Gog]:              Running command: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json --version
(09:23:00) INFO:    [Nile]:             Running command: XDG_CONFIG_HOME=/home/saeniv/.config/heroic/nile_config /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/nile --version
(09:23:01) INFO:    [Backend]:          Checking if wine version exists: Wine - Wine-GE-latest
(09:23:01) INFO:    [Backend]:          Stopping Power Saver Blocker
(09:23:01) INFO:    [Backend]:          Checking if wine version exists: Wine - Wine-GE-latest
(09:23:01) INFO:    [Backend]:          Checking if wine version exists: Wine - Wine-GE-latest
(09:23:01) INFO:    [Backend]:          Checking if wine version exists: Wine - Wine-GE-latest
(09:23:01) DEBUG:   [Backend]:          Running Wine command: wineboot --init
(09:23:01) INFO:    [Gog]:              Running command: /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json auth
(09:23:02) INFO:    [Winetricks]:       Downloading Winetricks
(09:23:03) INFO:    [DXVKInstaller]:    installing dxvk on... /home/saeniv/Games/Heroic/Prefixes/default/Horizon Zero Dawn Complete Edition
(09:23:03) INFO:    [DXVKInstaller]:    dxvk already installed!
(09:23:03) INFO:    [DXVKInstaller]:    installing dxvk-nvapi on... /home/saeniv/Games/Heroic/Prefixes/default/Horizon Zero Dawn Complete Edition
(09:23:03) INFO:    [DXVKInstaller]:    dxvk-nvapi already installed!
(09:23:03) INFO:    [DXVKInstaller]:    installing vkd3d on... /home/saeniv/Games/Heroic/Prefixes/default/Horizon Zero Dawn Complete Edition
(09:23:03) INFO:    [DXVKInstaller]:    vkd3d already installed!
(09:23:03) INFO:    [Gog]:              Launching Horizon Zero Dawn™ Complete Edition: HEROIC_APP_NAME=1209025141 HEROIC_APP_RUNNER=gog HEROIC_APP_SOURCE=gog LD_PRELOAD= DOTNET_BUNDLE_EXTRACT_BASE_DIR= WINEPREFIX="/home/saeniv/Games/Heroic/Prefixes/default/Horizon Zero Dawn Complete Edition" WINEDLLOVERRIDES=winemenubuilder.exe=d MANGOHUD_CONFIGFILE=/home/saeniv/.config/MangoHud/MangoHud.conf WINE_FULLSCREEN_FSR=0 WINEESYNC=1 WINEFSYNC=1 DXVK_ENABLE_NVAPI=1 DXVK_NVAPI_ALLOW_OTHER_DRIVERS=1 ORIG_LD_LIBRARY_PATH= LD_LIBRARY_PATH=/home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/lib64:/home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/lib GST_PLUGIN_SYSTEM_PATH_1_0=/home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/lib64/gstreamer-1.0:/home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/lib/gstreamer-1.0 WINEDLLPATH=/home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/lib64/wine:/home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/lib/wine /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/gogdl --auth-config-path /home/saeniv/.config/heroic/gog_store/auth.json launch "/home/saeniv/Games/Heroic/Horizon Zero Dawn" 1209025141 --wine /home/saeniv/.config/heroic/tools/wine/Wine-GE-latest/bin/wine --wrapper "/usr/bin/mangohud --dlsym /usr/bin/gamemoderun" --platform windows
(09:23:03) WARNING: [Winetricks]:       Error Downloading Winetricks Error: timeout of 1000ms exceeded
    at createError (/opt/Heroic/resources/app.asar/node_modules/axios/lib/core/createError.js:16:15)
    at RedirectableRequest.handleRequestTimeout (/opt/Heroic/resources/app.asar/node_modules/axios/lib/adapters/http.js:369:16)
    at RedirectableRequest.emit (node:events:513:28)
    at Timeout.<anonymous> (/opt/Heroic/resources/app.asar/node_modules/follow-redirects/index.js:169:12)
    at listOnTimeout (node:internal/timers:569:17)
    at process.processTimers (node:internal/timers:512:7) {
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 1000,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'User-Agent': 'axios/0.26.1'
    },
    method: 'get',
    url: 'https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks',
    data: undefined
  },
  code: 'ECONNABORTED',
  request: <ref *1> Writable {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      constructed: true,
      prefinished: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      errored: null,
      closed: false,
      closeEmitted: false,
      [Symbol(kOnFinished)]: []
    },
    _events: [Object: null prototype] {
      response: [Function: handleResponse],
      error: [Function: handleRequestError],
      socket: [Array]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _options: {
      maxRedirects: 21,
      maxBodyLength: 10485760,
      protocol: 'https:',
      path: '/Winetricks/winetricks/master/src/winetricks',
      method: 'GET',
      headers: [Object],
      agent: undefined,
      agents: [Object],
      auth: undefined,
      hostname: 'raw.githubusercontent.com',
      port: null,
      nativeProtocols: [Object],
      pathname: '/Winetricks/winetricks/master/src/winetricks'
    },
    _ended: true,
    _ending: true,
    _redirectCount: 0,
    _redirects: [],
    _requestBodyLength: 0,
    _requestBodyBuffers: [],
    _onNativeResponse: [Function (anonymous)],
    _currentRequest: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: true,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [TLSSocket],
      _header: 'GET /Winetricks/winetricks/master/src/winetricks HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'User-Agent: axios/0.26.1\r\n' +
        'Host: raw.githubusercontent.com\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/Winetricks/winetricks/master/src/winetricks',
      _ended: false,
      res: null,
      aborted: true,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: [HTTPParser],
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'raw.githubusercontent.com',
      protocol: 'https:',
      _redirectable: [Circular *1],
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kEndCalled)]: true,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kUniqueHeaders)]: null,
      [Symbol(kError)]: undefined
    },
    _currentUrl: 'https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks',
    _timeout: null,
    [Symbol(kCapture)]: false
  },
  response: undefined,
  isAxiosError: true,
  toJSON: [Function: toJSON]
}
(09:23:05) INFO:    [Backend]:          Starting the Download Queue
(09:23:10) INFO:    [Gog]:              Saved games data
(09:23:11) WARNING: [Backend]:          listUpdateableGames not implemented on Sideload Library Manager
(09:23:12) INFO:    [Gog]:              Found 0 game(s) to update
(09:23:13) INFO:    [Legendary]:        Checking for game updates: XDG_CONFIG_HOME=/home/saeniv/.config/heroic/legendaryConfig /opt/Heroic/resources/app.asar.unpacked/build/bin/linux/legendary list --third-party
(09:23:15) DEBUG:   [Legendary]:        Update is available for c9b51edbca4d496cb39c6871f510620b: 3272190-64 != 3296043-64
(09:23:15) INFO:    [Legendary]:        Found 1 game to update
(node:1881) UnhandledPromiseRejectionWarning: TypeError: Cannot read properties of undefined (reading 'invoke')
    at isGameAvailable (/opt/Heroic/resources/app.asar/build/electron/main.c2fc9376.js:90:11558)
    at /opt/Heroic/resources/app.asar/build/electron/main.c2fc9376.js:90:12250
(Use `heroic --trace-warnings ...` to show where the warning was created)
(node:1881) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 7)
[1881:0926/092453.038476:ERROR:command_buffer_proxy_impl.cc(325)] GPU state invalid after WaitForGetOffsetInRange.
[1881:0926/092453.040008:ERROR:zygote_communication_linux.cc(291)] Failed to send GetTerminationStatus message to zygote
[1881:0926/092453.041362:ERROR:network_service_instance_impl.cc(541)] Network service crashed, restarting service.
[1881:0926/092453.043924:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.044997:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.045360:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.045637:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.045849:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.046046:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.046391:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.046626:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.046824:ERROR:gpu_process_host.cc(937)] GPU process launch failed: error_code=1002
[1881:0926/092453.046831:FATAL:gpu_data_manager_impl_private.cc(440)] GPU process isn't usable. Goodbye.


  1. sc-controller:
[saeniv@saeniv-b660mprors ~]$ sc-controller

** (sc-controller:1828): WARNING **: 09:22:49.059: expected enumeration type void, but got PyGLibOptionArg instead

** (sc-controller:1828): WARNING **: 09:22:49.059: expected enumeration type void, but got PyGLibOptionArg instead

** (sc-controller:1828): WARNING **: 09:22:49.059: expected enumeration type void, but got PyGLibOptionArg instead
pidfile /home/saeniv/.config/scc/daemon.pid does not exist. Daemon not running?
W ContImage     Area for button DOTS not found
W ContImage     Area for button DOTS not found
W App           Failed to read release notes
E App           g-io-error-quark: Operation not supported (15)
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/scc/gui/app.py", line 1558, in http_ready
    stream = f.read_finish(task)
             ^^^^^^^^^^^^^^^^^^^
gi.repository.GLib.GError: g-io-error-quark: Operation not supported (15)
W App           (above error is not fatal and can be ignored)
W App           Daemon reported unknown profile: 'None'; Overriding.

P.S. Sorry for the long period had to work.

Nothing from that output in the sc-controller looks to be fatal and the stuff from the game looks more to do with issues using the heroic launcher rather than the game itself. I am not using the heroic launcher, but rather I launched the game directly using wine.

I will try to import the game into Lutris or I will look up how to start a game directly frome wine.

For me it went like this env MANGOHUD_CONFIG=gpu_temp,vram mangohud wine start /unix "/Installs/Horizon - Zero Down CE/HorizonZeroDawn.exe"

Edit: this assume you have your system wine set up and configured and you have all the runtimes and other stuff that the games depend on installed.

1 Like

I installed the game via Lutris in a new wine bottle and it worked. Thank you very much. Heroic did work for all previous games, but not for this one. Next time i will start with Lutris from the beginning.

What i still don’t get is the controller is recognized from the wine config and you can try it out, even rumble works there, but in the game it does not work. I will try to add input.dll from windows created with the x360 emulator, maybe that works, I don’t know.

So my last problem to solve with Linux is how do i undervolt a nvidia card under linux, but this is something for the weekend. I have already read the arch article, but there you only can set a power threshold, which is not really undervoting like in windows, where I can save up to 44% by just loosing 3,9% performance.

Yeah wine recognizes the controller and in most games it works as long as it recognizes them. I have run into a few where that is not the case I believe this one and forza horizon (can’t remember which one) off the top of my head. Does sc-controller still not work even launching the game via lutris. I didn’t see you mention that part. Lastly for undervolting, I’m using greenwithenvy. It works great although they need a new maintainer, so I’m not sure for how long it will continue to work.