Add AI-upscaled critter/object art as a new MDL mod type
build / build (push) Successful in 3m36s

Extends the MDL system beyond text overrides: bitmaps/<label>.json
names a model/scale and resource list, and mdlp extracts each
resource's frames, runs them through an ONNX Runtime CPU upscaler
baked into mdlp-image, re-quantizes to the game's palette, and writes
the result back - same build-time pipeline as message overrides.

Adds animgallery, a standalone viewer that renders any data
directory's animated resources as an HTML/GIF gallery with a
checkbox-driven MDL JSON generator, and -only-changed to preview just
what a mod overrides against the base game.

Fixes a real data race in hacked's ChangeNotifier.hashAll() (found via
go build -race causing non-deterministic resource counts), via a new
numbered patch rather than editing the vendored source.

Adds engine-patches/, a general-fixes counterpart to
android/engine-patches/ now staged and applied to the desktop builds
too (previously unpatched): a real GL_UNPACK_ROW_LENGTH stride bug, an
audio error-logging improvement, and two critter-rendering fixes -
mod art was losing to the base game's own re-opened resource files,
and critters rendered at the wrong size/position once that was fixed,
both from how the billboard renderer derives on-screen size and
placement straight from bitmap pixel dimensions.

Updates README.md and AGENTS.md to document engine-patches/.
This commit is contained in:
ml
2026-09-27 20:52:35 +02:00
parent 389abd7de7
commit ab2b778f44
25 changed files with 2009 additions and 35 deletions
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env bash
# Builds and runs modding/src/animgallery/ (see README.md section 4) inside
# the mdlp-image's Go toolchain - animgallery has no cgo dependencies of its
# own, so it reuses that image rather than needing one of its own.
#
# Every argument is forwarded verbatim to animgallery itself. -data is
# repeatable and layers directories in the order given, later wins - the
# whole repository is mounted at /workspace here, so paths are relative to
# the repository root, for example:
#
# ./gen_animgallery.sh -data res/assets/ss_ee/data -out modding/build/gallery
# ./gen_animgallery.sh -data res/assets/ss_ee/data \
# -data modding/dist/mods/mymod/mod -out modding/build/gallery-mymod
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
MODDING_ROOT="$(pwd)"
REPO_ROOT="$(cd .. && pwd)"
fail() { echo "PREFLIGHT FAIL: $*" >&2; exit 1; }
command -v docker >/dev/null 2>&1 \
|| fail "docker not found in PATH"
IMAGE="${MDLP_REGISTRY_IMAGE:-questshock/mdlp}"
if [ -f "$MODDING_ROOT/../registry.env" ]; then
# shellcheck disable=SC1091
source "$MODDING_ROOT/../registry.env"
IMAGE="${MDLP_REGISTRY_IMAGE:-$IMAGE}"
fi
IMAGE_TAG="$(<"$MODDING_ROOT/mdlp-image/VERSION")"
[ -n "$IMAGE_TAG" ] || fail "mdlp-image/VERSION is empty"
IMAGE="$IMAGE:$IMAGE_TAG"
docker image inspect "$IMAGE" >/dev/null 2>&1 \
|| fail "$IMAGE not found locally - run ./mdlp-image.sh first"
TTY_FLAGS="-i"
[ -t 1 ] && TTY_FLAGS="-it"
# shellcheck disable=SC2086
docker run --rm $TTY_FLAGS \
-v "$REPO_ROOT:/workspace" \
-w /workspace \
-e HOST_UID="$(id -u)" \
-e HOST_GID="$(id -g)" \
"$IMAGE" \
bash -c '
set -euo pipefail
# animgallery, like mdlp, builds against ../hacked via its own
# go.mod replace - stage a patched copy (see src/hacked-patches/)
# rather than building against the unpatched vendored source.
SCRATCH_DIR="modding/build/animgallery-src"
rm -rf "$SCRATCH_DIR"
mkdir -p "$SCRATCH_DIR"
bash modding/mdlp-image/stage-hacked.sh modding "$SCRATCH_DIR/hacked"
cp -a modding/src/animgallery "$SCRATCH_DIR/animgallery"
(cd "$SCRATCH_DIR/animgallery" && go build -o /tmp/animgallery .)
exec /tmp/animgallery "$@"
' _ "$@"