Last active
May 5, 2026 06:35
-
-
Save Benjamin-Wegener/2289ee830a1b0195d4fb86d47833d6d6 to your computer and use it in GitHub Desktop.
Hogwarts Legacy – Heroic Launcher fix script (Mac M4)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Hogwarts Legacy – Heroic Launcher fix script v3 (Mac M4) | |
| LOG="$HOME/hogwarts_fix_$(date +%Y%m%d_%H%M%S).log" | |
| exec > >(tee -a "$LOG") 2>&1 | |
| ok() { echo " [OK] $*"; } | |
| warn() { echo " [!!] $*"; } | |
| info() { echo " --> $*"; } | |
| section() { echo; echo "=== $* ==="; } # renamed: was head(), clashed with /usr/bin/head | |
| echo "Hogwarts Legacy fix script v3" | |
| echo "Log: $LOG" | |
| GAME_DIR="/Users/user/Games/Heroic" | |
| HEROIC_CFG="$HOME/Library/Application Support/heroic" | |
| # ── 1. Locate Wine prefix ──────────────────────────────────── | |
| section "1. Locating Wine prefix" | |
| PREFIX="" | |
| SEARCH_DIRS=() | |
| [[ -d "$HEROIC_CFG" ]] && SEARCH_DIRS+=("$HEROIC_CFG") | |
| [[ -d "$GAME_DIR" ]] && SEARCH_DIRS+=("$GAME_DIR") | |
| [[ -d "$HOME/Games" ]] && SEARCH_DIRS+=("$HOME/Games") | |
| info "Searching in: ${SEARCH_DIRS[*]}" | |
| if [[ ${#SEARCH_DIRS[@]} -gt 0 ]]; then | |
| while IFS= read -r dc; do | |
| [[ -z "$dc" ]] && continue | |
| CANDIDATE=$(dirname "$dc") | |
| info "Found drive_c at: $CANDIDATE" | |
| if echo "$CANDIDATE" | grep -qi "hogwart\|legacy"; then | |
| PREFIX="$CANDIDATE" | |
| break | |
| fi | |
| [[ -z "$PREFIX" ]] && PREFIX="$CANDIDATE" | |
| done < <(find "${SEARCH_DIRS[@]}" -maxdepth 6 -name "drive_c" -type d 2>/dev/null) | |
| fi | |
| for FIXED in \ | |
| "$HEROIC_CFG/wineprefix/HogwartsLegacy" \ | |
| "$HEROIC_CFG/prefixes/HogwartsLegacy" \ | |
| "$HEROIC_CFG/wineprefix/default" \ | |
| "$HOME/my-game-prefix" \ | |
| "$GAME_DIR/Hogwarts Legacy/wine" \ | |
| "$GAME_DIR/HogwartsLegacy/wine"; do | |
| if [[ -d "$FIXED/drive_c" && -z "$PREFIX" ]]; then | |
| PREFIX="$FIXED" | |
| info "Matched fixed path: $PREFIX" | |
| fi | |
| done | |
| if [[ -z "$PREFIX" ]]; then | |
| warn "No Wine prefix found. Dumping dirs for manual inspection:" | |
| echo "--- heroic config ---" | |
| ls -la "$HEROIC_CFG/" 2>/dev/null || echo "(not found)" | |
| echo "--- game dir ---" | |
| ls -la "$GAME_DIR/" 2>/dev/null || echo "(not found)" | |
| echo "--- find drive_c (10s timeout) ---" | |
| timeout 10 find ~ -name "drive_c" -type d 2>/dev/null || true | |
| warn "Re-run with: PREFIX=\"/path/to/prefix\" bash fix_hogwarts.sh" | |
| exit 0 | |
| fi | |
| ok "Using prefix: $PREFIX" | |
| DRIVE_C="$PREFIX/drive_c" | |
| # ── 2. Delete ProgramData relaunch blocker ─────────────────── | |
| section "2. ProgramData relaunch blocker" | |
| PD="$DRIVE_C/ProgramData/Hogwarts Legacy" | |
| if [[ -d "$PD" ]]; then | |
| info "Found: $PD" | |
| ls -lh "$PD" 2>/dev/null | sed 's/^/ /' || true | |
| rm -rf "$PD" | |
| ok "Deleted ProgramData/Hogwarts Legacy" | |
| else | |
| ok "Not present (already clean)" | |
| fi | |
| # ── 3. Patch MSync / ESync ─────────────────────────────────── | |
| section "3. MSync / ESync settings" | |
| SETTINGS_FILE="" | |
| while IFS= read -r f; do | |
| [[ -z "$f" ]] && continue | |
| if grep -qi "hogwart\|HogwartsLegacy" "$f" 2>/dev/null; then | |
| SETTINGS_FILE="$f" | |
| break | |
| fi | |
| done < <(find "$HEROIC_CFG" -name "*.json" -maxdepth 5 2>/dev/null) | |
| if [[ -z "$SETTINGS_FILE" ]]; then | |
| warn "No settings JSON found for Hogwarts Legacy" | |
| warn "Manual fix: Heroic -> game -> Settings -> Wine -> disable MSync + ESync" | |
| else | |
| ok "Settings file: $SETTINGS_FILE" | |
| cp "$SETTINGS_FILE" "${SETTINGS_FILE}.bak" 2>/dev/null && info "Backup: ${SETTINGS_FILE}.bak" | |
| python3 - "$SETTINGS_FILE" <<'PYEOF' | |
| import json, sys | |
| path = sys.argv[1] | |
| try: | |
| with open(path) as f: | |
| d = json.load(f) | |
| changed = [] | |
| for key in ('enableMsync', 'enableEsync'): | |
| old = d.get(key, 'NOT SET') | |
| print(f" {key}: {old}", end="") | |
| if old is not False: | |
| d[key] = False | |
| changed.append(key) | |
| print(" --> false (patched)") | |
| else: | |
| print(" (already false)") | |
| if changed: | |
| with open(path, 'w') as f: | |
| json.dump(d, f, indent=2) | |
| print(" [OK] Saved changes") | |
| else: | |
| print(" [OK] No changes needed") | |
| except Exception as e: | |
| print(f" [!!] Could not patch: {e}") | |
| PYEOF | |
| fi | |
| # ── 4. vcrun2022 check ─────────────────────────────────────── | |
| section "4. vcrun2022 / Visual C++ runtime" | |
| VC_OK=true | |
| for dll in msvcp140.dll vcruntime140.dll vcruntime140_1.dll; do | |
| f="$DRIVE_C/windows/system32/$dll" | |
| if [[ -f "$f" ]]; then | |
| ok "$dll present ($(du -sh "$f" | cut -f1))" | |
| else | |
| warn "$dll MISSING" | |
| VC_OK=false | |
| fi | |
| done | |
| if [[ "$VC_OK" == false ]]; then | |
| echo " ACTION: Heroic -> game -> Settings -> WineTricks -> install vcrun2022" | |
| fi | |
| # ── 5. Game executable ─────────────────────────────────────── | |
| section "5. Game executable" | |
| EXE=$(find "$GAME_DIR" -name "HogwartsLegacy.exe" 2>/dev/null | grep -v "^\s*$" | /usr/bin/head -n 1) | |
| if [[ -n "$EXE" ]]; then | |
| ok "Found: $EXE" | |
| info "Size: $(du -sh "$EXE" 2>/dev/null | cut -f1)" | |
| else | |
| warn "HogwartsLegacy.exe not found under $GAME_DIR" | |
| info "Searching home dir..." | |
| find ~ -name "HogwartsLegacy.exe" 2>/dev/null | /usr/bin/head -n 3 || true | |
| fi | |
| # ── 6. Recent Heroic error logs ───────────────────────────── | |
| section "6. Recent Heroic error logs" | |
| HEROIC_LOG="" | |
| for LOGDIR in \ | |
| "$HOME/Library/Logs/Heroic" \ | |
| "$HOME/Library/Application Support/heroic/logs"; do | |
| if [[ -d "$LOGDIR" ]]; then | |
| MAYBE=$(find "$LOGDIR" -name "*.log" 2>/dev/null | sort -r | /usr/bin/head -n 1) | |
| if [[ -n "$MAYBE" ]]; then | |
| HEROIC_LOG="$MAYBE" | |
| break | |
| fi | |
| fi | |
| done | |
| if [[ -n "$HEROIC_LOG" ]]; then | |
| ok "Log: $HEROIC_LOG" | |
| echo | |
| grep -iE "(error|uproject|fail|crash|warn|hogwart)" "$HEROIC_LOG" 2>/dev/null \ | |
| | /usr/bin/tail -n 30 | sed 's/^/ /' || echo " (no matching lines)" | |
| else | |
| warn "No Heroic log file found" | |
| fi | |
| # ── Done ──────────────────────────────────────────────────── | |
| section "Done" | |
| echo "Full output saved to: $LOG" | |
| echo | |
| echo "Next steps:" | |
| echo " 1. Launch Hogwarts Legacy from Heroic" | |
| echo " 2. If shaders fail on first launch, close and relaunch once" | |
| echo " 3. If still broken, share: $LOG" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment