cd /news/developer-tools/running-alecaframe-overwolf-with-war… · home topics developer-tools article
[ARTICLE · art-38530] src=gist.github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Running AlecaFrame (Overwolf) with Warframe on Linux — non-Steam, umu-launcher + Proton

A developer has created a working solution to run AlecaFrame, a Warframe companion app built on Overwolf, with Warframe on Linux using umu-launcher and Proton without Steam. The setup enables live data tracking of inventory and relics through a standalone window, though the in-game overlay remains non-functional under DXVK/Proton. The solution involves a single command that launches Warframe and auto-prepares AlecaFrame, with self-healing capabilities across reboots and updates.

read15 min views2 publishedJun 24, 2026

Goal: Get AlecaFrame — a Warframe companion app built on Overwolf — to actually read live in-game data (inventory, relics, missions, etc.) when Warframe runs on Linux through ** umu-launcher + Proton**,

withoutSteam.

What this achieves (verified working):

  • ✅ AlecaFrame's data/tracking works— inventory and the rest populate from the live game. - ✅ A single command launches Warframe and auto-prepares AlecaFrame in the correct order. - ✅ It is self-healing and survives reboots, Overwolf self-updates, and AlecaFrame data updates. - ❌ The transparent in-game overlay (Ctrl+Tab) does NOT work under DXVK/Proton and almost certainly can't without upstream changes. You use AlecaFrame'sstandalone window instead. (Full technical reason below — it's a real wall, not a missing setting.)

This guide was largely written by AI (Opus 4.8).Every step was validated on a live system, but treat the Wine/Overwolf internals as "true as of the versions tested" (see[Versions]) and adapt paths to your setup. Nothing here modifies the game itself — it only adds launcher scripts, window rules, and a couple of harmless local files.

Contents: TL;DR · Prerequisites · Background · 1. ptrace_scope · 2. Scripts · 3. First-run seed · 4. Hide junk windows · 5. Daily use · Overlay limitation · Versions

  • Warframe runs via umu-launcher + Proton (DXVK). Overwolf is a separate Windows app; it can only read the game if it runs inside the same Proton/pressure-vessel container as the game. - umu can re-enter that container: a second umu-run

with thesame plusWINEPREFIX

+GAMEID

UMU_CONTAINER_NSENTER=1

andPROTON_VERB=runinprefix

"nsenters" into the running game container. - AlecaFrame's data does not come from the EE.log — it comes from Overwolf'smemory scanner(gep_warframeext.dll

) reading the game's RAM. Three things must all be true for that to work:(Wine reads process memory viakernel.yama.ptrace_scope = 0

ptrace

).- The game must have in Overwolf's<OOPO>True</OOPO>

GamesList

(otherwise, under DXVK, Overwolf's renderer-detection fails and it never loads the scanner). - AlecaFrame's data cache ( cachedData/json.7z

) must be present & match the remote MD5, or its .NET inithangs trying to re-download over Wine's TLS.

  • AlecaFrame must finish initializing before the game process starts (load order matters). - Two small launcher scripts automate all of this, including self-healing #3 on every launch.

  • Warframe already installed and working via umu-launcher + Proton (this guide does not cover installing Warframe itself). - Overwolf + AlecaFrame already installed into the same Warframe Proton prefix. Doing this on a non-Steam umu prefix is fiddly (the Overwolf web installer fails under Wine) — seeInstalling Overwolf into a Proton / umu-launcher prefixfor the working route, then install AlecaFrame from Overwolf's App Store. You should have launched Overwolf at least once so theOverwolf/

folders andGamesList*.xml

exist in the prefix. curl

(orwget

),awk

,grep

,md5sum

on the host.- Passwordless sudo

(or root) once, to set a sysctl. - A compositor/WM where you can add window rules (examples use Sway; adapt for yours).

Throughout, replace these with your values:

Placeholder Meaning
WINEPREFIX
Your Warframe Proton prefix, e.g. $HOME/Games/Warframe-Proton-Prefix
GAMEID
The umu game id you launch Warframe with, e.g. umu-warframe
LAUNCHER_EXE
Unix path to Warframe's Tools/Launcher.exe

Inside a Proton prefix the user folder is

, so app data lives understeamuser

"$WINEPREFIX/drive_c/users/steamuser/AppData/Local/..."

. Use that, not your Linux username.

AlecaFrame is an Overwolf app. Overwolf can only see Warframe if it shares the game's wine/Proton session (same wineserver

, same pressure-vessel mount/PID namespaces). A plain second umu-run

builds its own container and is blind to the game.

umu-launcher solves this: launch a second umu-run

with the same WINEPREFIX and GAMEID and set

UMU_CONTAINER_NSENTER=1

  • PROTON_VERB=runinprefix

. umu then re-enters the existing container (you'll see "Re-entering container through bus …"). The injected Overwolf processes end up sharing the game's namespaces.

AlecaFrame's inventory/relics/etc. are not parsed from EE.log

. Overwolf's General Game Events Provider (GEP) loads a native plugin ** gep_warframeext.dll** that scans

Warframe.x64.exe

's memory (ReadProcessMemory

/VirtualQueryEx

). Only the player name comes from

EE.log

.The GEP only loads that scanner if it knows the game's renderer or the game is flagged out-of-process-overlay (OOPO). Under DXVK, Overwolf's renderer detection returns ** Unknown**, so without OOPO the scanner is never loaded (GEP just logs

"Waiting for renderer.."). Setting

<OOPO>True</OOPO>

for Warframe forces the scanner to load — and, as a bonus, the renderer then detects as D3D11. With it set you can confirm in the GEP log: Warframe plugin loaded: {"status":"success"}

and "oopOverlay":true

.Under Wine/Proton, wineserver

performs ReadProcessMemory

using Linux ** ptrace** (

/proc/<pid>/mem

). The scanner, the game, and wineserver

are siblingprocesses, so the kernel's Yama

restricted-ptrace(

ptrace_scope = 1

, the common default) blocks the cross-process reads and AlecaFrame shows no data. Setting

kernel.yama.ptrace_scope = 0

allows it.

Security note:ptrace_scope = 0

lowers system-wide ptrace hardening (any process of your user can read another's memory). That's a normal tradeoff on a single-user gaming desktop, but make the call for your threat model.= 1

will break the data feature.

On startup AlecaFrame's .NET client MD5-checks cachedData/json.7z

. If that archive is missing (only the extracted json/

folder present), it logs Got local data MD5: |==FILE-NOT-FOUND==|

and tries to re-download the data over HTTPS — which hangs forever under Wine's TLS, pinning a CEF process near 100% CPU. AlecaFrame deletes/renews json.7z

whenever the upstream data changes, so this recurs over time. Keep json.7z

present and matching the remote MD5 → it logs "no data download is needed" and initializes in ~25s. The script below self-heals this from the CDN.

If AlecaFrame (re)initializes after Warframe.x64.exe

is already running, it hits the hang in #4. So: start the launcher, inject + initialize AlecaFrame to "ready", then press Play.

sudo tee /etc/sysctl.d/50-alecaframe-ptrace.conf >/dev/null <<'EOF'
kernel.yama.ptrace_scope = 0
EOF
sudo sysctl --system
cat /proc/sys/kernel/yama/ptrace_scope   # must print 0

Put both on your $PATH

(e.g. ~/.local/bin

) and chmod +x

them. Edit the CONFIG block at the top of each to match your prefix, game id, and launcher path.

#!/bin/sh
#
#

WINEPREFIX="$HOME/Games/Warframe-Proton-Prefix"
GAMEID="umu-warframe"
LAUNCHER_EXE="$HOME/Games/Warframe-Proton-Prefix/drive_c/users/steamuser/AppData/Local/Warframe/Downloaded/Public/Tools/Launcher.exe"

if [ -z "$NO_ALECA" ] && command -v alecaframe >/dev/null 2>&1; then
    setsid alecaframe wait-prepare >/tmp/alecaframe-autostart.log 2>&1 &
fi

exec env \
  WINEPREFIX="$WINEPREFIX" \
  GAMEID="$GAMEID" \
  STORE=none \
  umu-run "$LAUNCHER_EXE" "$@"

Add

gamemoderun

beforeenv

if you use gamemode. Keep the umu knobs identical to thealecaframe

script (below) or umu computes a different prefix hash and won't re-enter the container.

#!/bin/sh

WINEPREFIX="$HOME/Games/Warframe-Proton-Prefix"
GAMEID="umu-warframe"
STORE="none"

OW_LAUNCHER='C:\Program Files (x86)\Overwolf\OverwolfLauncher.exe'
AF_EXTID="afmcagbpgggkpdkokjhjkllpegnadmkignlonpjm"     # AlecaFrame's Overwolf extension id (stable)
WF_GAME_ID="89541"                                       # Warframe's Overwolf game id (stable)
LOG="/tmp/alecaframe-overwolf.log"
OW_BASE="$WINEPREFIX/drive_c/users/steamuser/AppData/Local/Overwolf"
AF_BGLOG="$OW_BASE/Log/Apps/AlecaFrame/BackGround.html.log"
AF_DATA_CDN="https://cdn.alecaframe.com/warframeData"

gameslist_files() {
    for d in "$OW_BASE" "$WINEPREFIX/drive_c/Program Files (x86)/Overwolf"/*/Resources; do
        [ -d "$d" ] || continue
        for f in "$d"/GamesList*.xml; do [ -f "$f" ] && printf '%s\n' "$f"; done
    done
}
oopo_present_in() {  # 0 if Warframe's block in $1 already has <OOPO>True</OOPO>
    awk -v id="$WF_GAME_ID" '
        /<GameInfo>/ { blk=""; isWF=0 }
        { blk=blk $0 ORS }
        $0 ~ ("<ID>" id "</ID>") { isWF=1 }
        /<\/GameInfo>/ { if (isWF && blk ~ /<OOPO>True<\/OOPO>/) found=1 }
        END { exit(found?0:1) }' "$1" 2>/dev/null
}
ensure_oopo() {
    gameslist_files | while IFS= read -r GL; do
        oopo_present_in "$GL" && continue
        cp -f "$GL" "$GL.bak.$(date +%Y%m%d-%H%M%S)" 2>/dev/null
        awk -v id="$WF_GAME_ID" '
            /<GameInfo>/ { isWF=0 }
            $0 ~ ("<ID>" id "</ID>") { isWF=1 }
            (isWF && /<\/GameInfo>/ && !done) { print "    <OOPO>True</OOPO>"; done=1; isWF=0 }
            { print }' "$GL" > "$GL.tmp" 2>/dev/null && mv "$GL.tmp" "$GL"
        oopo_present_in "$GL" && \
            echo "  (re-applied <OOPO>True</OOPO> to Warframe in $(basename "$GL") so data/inventory works)"
    done
}

ensure_data_cache() {
    tool=""
    for t in curl wget; do command -v "$t" >/dev/null 2>&1 && { tool="$t"; break; }; done
    [ -n "$tool" ] || return 0
    for U in steamuser "$USER"; do
        CD="$WINEPREFIX/drive_c/users/$U/AppData/Local/AlecaFrame/cachedData"
        [ -d "$CD" ] || continue
        want=""; [ -f "$CD/receivedMD5.txt" ] && want=$(awk '{print $1; exit}' "$CD/receivedMD5.txt" 2>/dev/null)
        cur="";  [ -f "$CD/json.7z" ] && cur=$(md5sum "$CD/json.7z" 2>/dev/null | awk '{print $1}')
        [ -n "$cur" ] && [ -n "$want" ] && [ "$cur" = "$want" ] && continue
        if [ "$tool" = curl ]; then rmd5=$(curl -fsSL "$AF_DATA_CDN/json7z.md5" 2>/dev/null | awk '{print $1; exit}')
        else rmd5=$(wget -qO- "$AF_DATA_CDN/json7z.md5" 2>/dev/null | awk '{print $1; exit}'); fi
        [ -n "$rmd5" ] || continue
        if [ -n "$cur" ] && [ "$cur" = "$rmd5" ]; then printf '%s  json.7z\n' "$rmd5" > "$CD/receivedMD5.txt"; continue; fi
        echo "  (refreshing AlecaFrame data cache json.7z so init won't hang...)"
        if [ "$tool" = curl ]; then curl -fsSL "$AF_DATA_CDN/json.7z" -o "$CD/json.7z.dl" 2>/dev/null
        else wget -qO "$CD/json.7z.dl" "$AF_DATA_CDN/json.7z" 2>/dev/null; fi
        got=$(md5sum "$CD/json.7z.dl" 2>/dev/null | awk '{print $1}')
        if [ -n "$got" ] && [ "$got" = "$rmd5" ]; then
            mv -f "$CD/json.7z.dl" "$CD/json.7z"; printf '%s  json.7z\n' "$rmd5" > "$CD/receivedMD5.txt"
            echo "  (data cache ready: $rmd5)"
        else rm -f "$CD/json.7z.dl"; echo "  (WARN: could not refresh json.7z)"; fi
    done
}

launcher_container_up() { ps -eo args 2>/dev/null | grep -E 'umu-run.*Launcher\.exe' | grep -qv grep; }
game_running()          { ps -eo comm 2>/dev/null | grep -q 'Warframe.x64'; }
overwolf_running()      { ps -eo args 2>/dev/null | grep -i 'OverwolfBrowser.exe' | grep -qv grep; }

inject() {
    setsid nohup env \
        WINEPREFIX="$WINEPREFIX" GAMEID="$GAMEID" STORE="$STORE" \
        PROTON_VERB="runinprefix" UMU_CONTAINER_NSENTER=1 UMU_RUNTIME_UPDATE=0 \
        umu-run "$@" </dev/null >"$LOG" 2>&1 &
}

wait_for_init() {  # 0 once AlecaFrame reports success, 1 on timeout
    secs="${1:-120}"; i=0
    while [ "$i" -lt "$secs" ]; do
        grep -q "Plugin initialization successful" "$AF_BGLOG" 2>/dev/null && return 0
        game_running && echo "[alecaframe] WARNING: game started before AlecaFrame finished init (will hang). Don't press Play until READY."
        i=$((i + 1)); sleep 1
    done
    return 1
}

do_prepare() {
    if overwolf_running; then echo "Overwolf already running. For a clean start: alecaframe stop, then prepare."; return 0; fi
    if ! launcher_container_up; then
        echo "The Warframe LAUNCHER isn't running yet. Start it (e.g. 'NO_ALECA=1 warframe'),"
        echo "stay on the launcher, then run 'alecaframe prepare' and wait for READY before Play."
        return 1
    fi
    if game_running; then echo "Game already running; AlecaFrame can't init cleanly now. Close it and retry from the launcher."; return 1; fi

    echo "Injecting Overwolf + AlecaFrame..."
    ensure_oopo
    ensure_data_cache
    : > "$AF_BGLOG" 2>/dev/null || true     # truncate so init-detection can't read a stale success line
    inject "$OW_LAUNCHER"

    echo "Waiting for Overwolf to come up..."
    i=0; ow=0
    while [ "$i" -lt 60 ]; do overwolf_running && { ow=1; break; }; i=$((i+1)); sleep 1; done
    [ "$ow" -eq 1 ] || { echo "Overwolf did not start."; return 1; }
    sleep 5

    echo "Opening AlecaFrame (retrying until it starts)..."
    started=0; try=0
    while [ "$try" -lt 5 ]; do
        try=$((try+1)); inject "$OW_LAUNCHER" -launchapp "$AF_EXTID"; j=0
        while [ "$j" -lt 20 ]; do
            grep -qE 'Plugin (early )?initialization (started|completed)|Starting plugin initialization|Plugin instantiated' "$AF_BGLOG" 2>/dev/null && { started=1; break; }
            grep -q 'Plugin initialization successful' "$AF_BGLOG" 2>/dev/null && { started=1; break; }
            j=$((j+1)); sleep 1
        done
        [ "$started" -eq 1 ] && break
        echo "  (didn't start on attempt $try; retrying...)"
    done
    [ "$started" -eq 1 ] || { echo "AlecaFrame would not start. Try: alecaframe stop, then prepare."; return 1; }

    echo "Waiting for AlecaFrame to finish initializing (up to 120s)..."
    if wait_for_init 120; then
        echo; echo "==== READY — AlecaFrame initialized. You can now press PLAY in the launcher. ===="
        return 0
    fi
    echo "AlecaFrame did NOT initialize in time. Check: tail -n 40 \"$AF_BGLOG\""
    echo "If stuck at FILE-NOT-FOUND, the game likely started too early: alecaframe stop, close game, retry."
    return 1
}

case "$1" in
    stop)
        echo "Stopping Overwolf/AlecaFrame (never touches the game)..."
        PIDS=$(ps -eo pid,args 2>/dev/null | grep -i 'Overwolf' | grep -v grep | awk '{print $1}' | tr '\n' ' ')
        [ -n "$PIDS" ] && { kill -TERM $PIDS 2>/dev/null; sleep 3; echo "  stopped: $PIDS"; } || echo "  (not running)"
        ;;
    status)
        launcher_container_up && echo "Launcher: RUNNING" || echo "Launcher: not running"
        game_running        && echo "Game:     RUNNING"  || echo "Game:     not running"
        overwolf_running    && echo "Overwolf: RUNNING"  || echo "Overwolf: not running"
        ;;
    wait-prepare)
        if overwolf_running && ! grep -q 'Plugin initialization successful' "$AF_BGLOG" 2>/dev/null; then
            echo "[alecaframe] stale Overwolf detected; cleaning it first." >&2
            PIDS=$(ps -eo pid,args 2>/dev/null | grep -i 'Overwolf' | grep -v grep | awk '{print $1}' | tr '\n' ' ')
            [ -n "$PIDS" ] && { kill -TERM $PIDS 2>/dev/null; sleep 3; }
        fi
        i=0
        while [ "$i" -lt 180 ]; do
            game_running && { echo "[alecaframe] game already running before prepare; skipping." >&2; exit 0; }
            launcher_container_up && { sleep 3; do_prepare; exit 0; }
            i=$((i + 1)); sleep 1
        done
        ;;
    prepare|"") do_prepare ;;
    *) echo "Usage: alecaframe [prepare|stop|status]"; exit 2 ;;
esac

The scripts self-heal both on every launch, but you can seed them once manually to confirm:

PREFIX="$HOME/Games/Warframe-Proton-Prefix"          # your WINEPREFIX
OW="$PREFIX/drive_c/users/steamuser/AppData/Local/Overwolf"
CD="$PREFIX/drive_c/users/steamuser/AppData/Local/AlecaFrame/cachedData"

for GL in "$OW"/GamesList*.xml "$PREFIX/drive_c/Program Files (x86)/Overwolf"/*/Resources/GamesList*.xml; do
  [ -f "$GL" ] || continue
  awk '/<GameInfo>/{b="";w=0}{b=b $0 RS}/<ID>89541<\/ID>/{w=1}/<\/GameInfo>/{if(w&&b~/<OOPO>True<\/OOPO>/)k=1}
       END{exit(k?0:1)}' "$GL" \
    && echo "OOPO ok : $GL" || echo "OOPO MISSING (run 'alecaframe prepare' to fix): $GL"
done

mkdir -p "$CD"
curl -fsSL https://cdn.alecaframe.com/warframeData/json.7z   -o "$CD/json.7z"
curl -fsSL https://cdn.alecaframe.com/warframeData/json7z.md5 | awk '{print $1"  json.7z"}' > "$CD/receivedMD5.txt"
md5sum "$CD/json.7z"; cat "$CD/receivedMD5.txt"        # the two hashes must match

(Just running alecaframe prepare

once does all of the above automatically.)

Under Wine/Xwayland, several Overwolf/Wine windows show up as class steam_app_warframe

and are useless or broken on Linux: the black out-of-process overlay surface (title ow overlay

), the Quick Launcher, and Wine's tiny title-less explorer.exe /desktop

artifact. Hide them (Sway shown; translate the idea to your WM):

for_window [class="steam_app_warframe" title="^Overwolf$"]   floating enable, move position 230 130
for_window [class="steam_app_warframe" title="^AlecaFrame$"] floating enable, move position 80 100

for_window [class="steam_app_warframe" title="^Overwolf Quick Launcher$"] floating enable, move scratchpad
for_window [class="steam_app_warframe" title="^ow overlay$"]              floating enable, move scratchpad
for_window [class="steam_app_warframe" title="^$"]                       floating enable, move scratchpad

Reload your WM config. (title="^$"

catches the title-less Wine desktop window; the real Overwolf/ AlecaFrame/launcher/game windows all map with a title, and move-to-scratchpad is non-destructive.)

warframe            # starts the launcher AND auto-prepares AlecaFrame

NO_ALECA=1 warframe # launch the game only
alecaframe stop     # stop Overwolf/AlecaFrame without touching the game

Open AlecaFrame's standalone window (from the Overwolf client) on a second monitor for your data.

If something gets stuck, the reliable reset is:

alecaframe stop
WINEPREFIX="$HOME/Games/Warframe-Proton-Prefix" \
  "$HOME/.local/share/umu/compatibilitytools/UMU-Latest/files/bin/wineserver" -k   # adapt path to your Proton
rm -f "$HOME/Games/Warframe-Proton-Prefix/pfx.lock"

Symptom: pressing Ctrl+Tab shows a fully black surface over the game (and Overwolf's own Settings

window is black too).

Root cause:

  • Overwolf renders the overlay UI with CEF (Chromium) off-screen, then hands the pixels to its compositorow-overlay.exe

as across-process D3D11 shared texture(NT-handle / keyed-mutex), optionally via** DirectComposition**. DXVK does not support cross-process D3D11 shared textures: its shared-resource table is per-process, so the texture created by CEF's GPU process can't be opened byow-overlay.exe

(D3D11Device::OpenSharedResourceGeneric: Handle not found

). DXVK also lacksCreateSwapChainForComposition

. CEF itself reportsshared texture compatibility: False

anddirect_composition: false

. Result: the pixels never reach the overlay surface → black.

Things that don't fix it (tested):

  • Forcing only ow-overlay.exe

ontowined3d(whichdoesimplement composition swapchains): it shares a folder with Overwolf's CEF browser, so CEF picks up wined3d too and renders broken; and a per-app WineDllOverride

ofdxgi/d3d11=builtin

can't beat DXVK because DXVK is installed by physically replacingsystem32\dxgi.dll

. Even if it loaded, the failure is also on the CEF-GPU side, so the handoff still breaks. - There's no Overwolf/CEF setting found to force a CPU/shared-memory overlay transport.

So the overlay needs upstream support (DXVK cross-process shared NT-handle textures, or an Overwolf CPU-copy overlay path). Until then: use the standalone window. Everything else works.

Non-fatal noise you can ignore: gamemodeauto: dlopen failed libgamemode.so

, occasional worldState.php

404s (an upstream Warframe endpoint moved; only affects a world-timer panel), Uninstall registry key not found

.

  • umu-launcher + UMU-Proton 10.0(Wine 10),** DXVK 2.5.1**. - Overwolf client 0.304.x

, AlecaFrame2.6.89

, GEP307.4.3

. - AMD GPU (RADV/amdgpu), Wayland (Sway). The data approach is GPU-agnostic; the overlay limitation is DXVK-wide, not vendor-specific.

Overwolf/AlecaFrame are third-party software; their internals can change and break these specifics. The general approach (container re-entry, OOPO, ptrace, data-cache, load order) should remain valid.

── more in #developer-tools 4 stories · sorted by recency
── more on @alecaframe 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/running-alecaframe-o…] indexed:0 read:15min 2026-06-24 ·