feat(perf): add one-step tier setup script for existing players

Default Options only seeds configs when absent, so existing players never
got the tuned settings. build.py --ship now also writes the Deck/Mid/High
tier files to config/onion-perf/<tier>/, and onion-perf-setup.{sh,ps1,bat}
(installed into the instance folder) backs up and replaces the tier's
config files and merges only the tuned video keys into options.txt,
keeping keybinds, audio and vsync/max-FPS choices.

PLAYER-TUNING: point players at the script; bench B4 GC verdict (G1 for
everyone; ZGC/Shenandoah tested worse); 16 GB PCs 5-6 GB heap.
This commit is contained in:
logan committed 2026-10-18 15:31:20 -04:00
1 parent cf7ea5617e
commit f949c169a2
34 files changed
+4348 -22

No files matched your search

+157
View File
@@ -0,0 +1,157 @@
#!/bin/sh
# Onion MC: apply a performance tier's tuned settings to this instance.
#
# sh onion-perf-setup.sh [deck|mid|high] [--yes]
#
# Run it from (or point it at) the instance's game folder - the one that holds
# config/ and options.txt; this script lives there after a pack update.
# Close Minecraft first. Every file it changes is backed up to
# onion-perf-backup/<date-time>/ first. options.txt is merged key by key: only the
# tier's video keys change; keybinds, audio, resource packs etc. are left alone.
# No network access. Windows: double-click onion-perf-setup.bat instead.
die() { echo "error: $*" >&2; exit 1; }
case "$0" in
*/*) GAME=$(cd "${0%/*}" && pwd) || die "cannot find the script's folder" ;;
*) GAME=$(pwd) ;;
esac
TIER=""
YES=0
for a in "$@"; do
case "$a" in
deck|mid|high) [ -z "$TIER" ] || die "more than one tier given"; TIER=$a ;;
-y|--yes) YES=1 ;;
-h|--help) sed -n '2,11p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
*) die "unknown argument '$a' (use: deck | mid | high, optionally --yes)" ;;
esac
done
PERF="$GAME/config/onion-perf"
[ -d "$PERF/mid" ] || die "$PERF not found. Update the modpack first (it ships these
settings), and run this script from the instance's game folder."
INTERACTIVE=0
[ -t 0 ] && INTERACTIVE=1
if [ -z "$TIER" ]; then
if [ "$INTERACTIVE" = 1 ]; then
cat <<'EOF'
Which tier fits this machine?
deck Steam Deck, handheld, laptop/integrated graphics
mid GTX 1060 / RX 580 class (~6 GB VRAM), 4-6 core CPU [pack default]
high 8 GB+ VRAM graphics card (GTX 1080 Ti, RTX 3060 and up)
EOF
printf 'Tier [mid]: '
read -r TIER || TIER=""
[ -n "$TIER" ] || TIER=mid
case "$TIER" in deck|mid|high) ;; *) die "unknown tier '$TIER'" ;; esac
else
TIER=mid
fi
fi
SRC="$PERF/$TIER"
[ -d "$SRC" ] || die "$SRC not found. Update the modpack first."
if [ "$YES" != 1 ]; then
[ "$INTERACTIVE" = 1 ] || die "not running interactively: close Minecraft, then re-run with --yes"
printf 'Is Minecraft closed? [y/N]: '
read -r ans || ans=""
case "$ans" in y|Y|yes|YES|Yes) ;; *) echo "Close Minecraft and run this again."; exit 1 ;; esac
fi
STAMP=$(date +%Y%m%d-%H%M%S)
BACKUP="$GAME/onion-perf-backup/$STAMP"
n=1
while [ -e "$BACKUP" ]; do BACKUP="$GAME/onion-perf-backup/$STAMP-$n"; n=$((n + 1)); done
mkdir -p "$BACKUP" || die "cannot create $BACKUP"
backup() { # backup <path relative to the game dir>, if it exists
[ -f "$GAME/$1" ] || return 0
case "$1" in */*) mkdir -p "$BACKUP/${1%/*}" || die "cannot create backup folder" ;; esac
cp -p "$GAME/$1" "$BACKUP/$1" || die "cannot back up $1"
}
LIST=$(mktemp "${TMPDIR:-/tmp}/onion-perf.XXXXXX") || die "mktemp failed"
REPORT=$(mktemp "${TMPDIR:-/tmp}/onion-perf.XXXXXX") || die "mktemp failed"
trap 'rm -f "$LIST" "$REPORT"' EXIT
(cd "$SRC" && find config -type f) | sort > "$LIST" || die "cannot list $SRC"
replaced=0
unchanged=0
echo "Applying tier '$TIER' to $GAME"
while IFS= read -r rel; do
if [ -f "$GAME/$rel" ] && cmp -s "$SRC/$rel" "$GAME/$rel"; then
unchanged=$((unchanged + 1))
continue
fi
backup "$rel"
case "$rel" in */*) mkdir -p "$GAME/${rel%/*}" || die "cannot create folder for $rel" ;; esac
cp "$SRC/$rel" "$GAME/$rel" || die "cannot write $rel"
echo " replaced $rel"
replaced=$((replaced + 1))
done < "$LIST"
OPT="$GAME/options.txt"
if [ ! -f "$SRC/options.txt" ]; then
echo " (tier has no options.txt)"
elif [ ! -f "$OPT" ]; then
echo " options.txt not found: skipped (Default Options seeds it on first launch)"
else
TMP="$OPT.onion-perf.tmp"
awk -v rep="$REPORT" '
NR == FNR {
sub(/\r$/, "")
i = index($0, ":")
if (i == 0) next
k = substr($0, 1, i - 1)
if (k == "version" || k == "maxFps" || k == "enableVsync") next
if (!(k in want)) order[++n] = k
want[k] = substr($0, i + 1)
next
}
{
cr = ""
if (sub(/\r$/, "")) { cr = "\r"; crlf = 1 }
i = index($0, ":")
if (i > 0) {
k = substr($0, 1, i - 1)
if ((k in want) && !(k in done)) {
v = substr($0, i + 1)
if (v != want[k]) print " " k ": " v " -> " want[k] > rep
print k ":" want[k] cr
done[k] = 1
next
}
}
print $0 cr
}
END {
for (j = 1; j <= n; j++) {
k = order[j]
if (!(k in done)) {
print " " k ": (unset) -> " want[k] > rep
print k ":" want[k] (crlf ? "\r" : "")
}
}
}
' "$SRC/options.txt" "$OPT" > "$TMP" || { rm -f "$TMP"; die "cannot merge options.txt"; }
if [ -s "$REPORT" ]; then
backup options.txt
mv "$TMP" "$OPT" || die "cannot write options.txt"
echo " options.txt keys changed:"
cat "$REPORT"
else
rm -f "$TMP"
echo " options.txt: already matches the tier"
fi
fi
if [ -z "$(ls -A "$BACKUP")" ]; then
rmdir "$BACKUP"
BACKUP="(nothing changed, no backup needed)"
fi
echo "Done: tier '$TIER'; $replaced file(s) replaced, $unchanged already up to date."
echo "Backup: $BACKUP"
echo "Also set Java memory in your launcher (5 GB is enough): see PLAYER-TUNING.md section 2."