Add a first-party MDL mod-build system and reorganize modding/ under src/
modding/mods/ holds message edits as plain JSON (type, index, language, plus only the changed fields - a long body can live in a sibling .txt to avoid escaping in JSON), so mod authoring is reviewable in git instead of living only in hacked's GUI. mdlp (modding/src/mdlp/, its own Docker image mdlp-image/) turns them into the same mod folder/zip hacked's own Save produces, reusing hacked's ss1/edit, ss1/world and ss1/content/text packages via a go.mod replace - no GUI/GLFW/GTK needed. `make mods` builds every mod into dist/mods/<name>/, scoped per-mod so it never touches hacked's own build output; `make` (no target) now builds both. Fixes a bug this surfaced: hacked's FileLocation.AbsolutePathFrom silently writes into the current directory instead of the given output folder when passed a relative path (the GUI never hits this since its folder picker is always absolute) - mdlp now resolves its own paths up front. res/run-mods.sh/.bat are new companion launchers to run.sh/.bat: they pass every dist/mods/*/mod folder to the engine as a separate absolute argument, since ProcessModDirectory() only scans one directory level deep. Wired into `make dist`/`dist-win` only, not the release archives. modding/hacked/, its patches, sqweek-dialog/, its patches, and the new mdlp/ move under modding/src/, separating source from the surrounding Docker/script scaffolding; all path references updated to match. NOTICE.txt gains a section for hacked's distributed build, listing hacked (New BSD), sqweek/dialog (ISC - corrected from a wrong "New BSD" note), and hacked's other direct Go dependencies.
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
# Runtime environment for modding/src/mdlp/ (the first-party Mod Definition
|
||||
# Language Processor - see ../README.md): builds mdlp from source and runs it
|
||||
# against modding/mods/ to produce modding/dist/mods/. Kept as its own image,
|
||||
# separate from hacked-build-image/, because mod processing is expected to
|
||||
# grow its own external tool dependencies (image/audio conversion, etc.)
|
||||
# independent of hacked's own GTK/GLFW/mingw toolchain.
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# go.mod's own "go" directive is a minimum toolchain version, not a version to
|
||||
# fetch - pin a stable release that already satisfies it so `go build` never
|
||||
# needs to fetch a newer toolchain over the network at build time.
|
||||
ARG GO_VERSION=1.27.1
|
||||
|
||||
RUN apt-get update \
|
||||
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
ca-certificates curl gosu \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -sSLO "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
&& tar -C /usr/local -xzf "go${GO_VERSION}.linux-amd64.tar.gz" \
|
||||
&& rm "go${GO_VERSION}.linux-amd64.tar.gz"
|
||||
ENV PATH=/usr/local/go/bin:${PATH}
|
||||
ENV GOTOOLCHAIN=local
|
||||
ENV GOPATH=/opt/go
|
||||
|
||||
# Populates /opt/go/pkg/mod with every dependency mdlp/go.mod pins, so the
|
||||
# container never needs network access to build it. mdlp/go.mod replaces
|
||||
# github.com/inkyblackness/hacked with the local ../hacked (see ../README.md),
|
||||
# so that module's own go.mod/go.sum have to be present too for dependency
|
||||
# resolution - only these two go.mod/go.sum pairs are copied in for this, not
|
||||
# the rest of either source tree, so editing .go files doesn't invalidate
|
||||
# this layer's cache.
|
||||
COPY src/hacked/go.mod src/hacked/go.sum /tmp/mdlp-deps/hacked/
|
||||
COPY src/mdlp/go.mod src/mdlp/go.sum /tmp/mdlp-deps/mdlp/
|
||||
RUN cd /tmp/mdlp-deps/mdlp && go mod download && rm -rf /tmp/mdlp-deps
|
||||
|
||||
COPY mdlp-image/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
COPY mdlp-image/process-mods.sh /usr/local/bin/process-mods.sh
|
||||
# 755, not +x: see hacked-build-image/Dockerfile's identical comment - the
|
||||
# entrypoint drops to a `builder` user matching the host's UID/GID, which is
|
||||
# never in these root-owned files' group.
|
||||
RUN chmod 755 /usr/local/bin/docker-entrypoint.sh /usr/local/bin/process-mods.sh
|
||||
|
||||
WORKDIR /workspace/modding
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
CMD ["/usr/local/bin/process-mods.sh"]
|
||||
|
||||
# Marks a shell as already running inside this image, same convention as
|
||||
# hacked-build-image/Dockerfile - lets ../Makefile compile directly instead
|
||||
# of trying to docker-run this image again from inside itself.
|
||||
ENV MDLP_IMAGE=1
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Drops from root (needed to read the Go toolchain and module cache under
|
||||
# /usr/local/go and /opt/go) to a user matching the host's UID/GID, so
|
||||
# anything written into the bind-mounted repo (modding/dist/, ...) is owned
|
||||
# by the host user instead of root.
|
||||
set -euo pipefail
|
||||
|
||||
USER_UID="${HOST_UID:-1000}"
|
||||
USER_GID="${HOST_GID:-1000}"
|
||||
|
||||
groupadd -g "$USER_GID" builder 2>/dev/null || true
|
||||
useradd -u "$USER_UID" -g "$USER_GID" -m -s /bin/bash builder 2>/dev/null || true
|
||||
|
||||
# /workspace (the bind-mounted repo) may actually be owned by a group the
|
||||
# host user only has via *supplementary* membership rather than their
|
||||
# primary GID above - e.g. a VirtualBox vboxsf shared folder, which shows
|
||||
# up as root:vboxsf on the host and would otherwise be inaccessible to
|
||||
# `builder` here (falls through to "other", which vboxsf's default mode
|
||||
# leaves with no permissions at all). Join whatever group actually owns
|
||||
# /workspace too, if it differs.
|
||||
WORKSPACE_GID="$(stat -c %g /workspace 2>/dev/null || true)"
|
||||
if [ -n "$WORKSPACE_GID" ] && [ "$WORKSPACE_GID" != "$USER_GID" ]; then
|
||||
groupadd -g "$WORKSPACE_GID" workspace 2>/dev/null || true
|
||||
usermod -aG "$WORKSPACE_GID" builder 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# The Go module cache under /opt/go was populated as root at image-build
|
||||
# time (see Dockerfile) - readable by anyone, but go build also wants to
|
||||
# write GOCACHE (build cache) under there by default. Point it at a
|
||||
# per-run tmpfs-friendly location inside the builder's own home instead of
|
||||
# fighting permissions on the image's baked-in GOPATH.
|
||||
export GOCACHE=/home/builder/.cache/go-build
|
||||
export GOMODCACHE=/opt/go/pkg/mod
|
||||
|
||||
exec gosu builder "$@"
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
# Builds modding/src/mdlp/ (the first-party Mod Definition Language
|
||||
# Processor, see ../README.md) and runs it against modding/mods/ to produce
|
||||
# modding/dist/mods/, entirely offline - mdlp's own Go module dependencies
|
||||
# were already fetched into the image at image-build time (see Dockerfile).
|
||||
#
|
||||
# Baked into the image at /usr/local/bin/process-mods.sh (see Dockerfile's
|
||||
# CMD) - run via ../mdlp-run-image.sh, which bind-mounts the whole
|
||||
# repository (not just modding/) at /workspace, since mdlp also needs the
|
||||
# game's own data directory outside modding/.
|
||||
#
|
||||
# Set MODS="name1 name2" (before calling ../mdlp-run-image.sh) to build only
|
||||
# those mods; unset or empty builds every subdirectory under mods/.
|
||||
set -euo pipefail
|
||||
|
||||
MODDING_ROOT="$(pwd)"
|
||||
REPO_ROOT="$(cd .. && pwd)"
|
||||
|
||||
DATA_DIR="${MDLP_DATA_DIR:-$REPO_ROOT/res/assets/ss_ee/data}"
|
||||
OUT_DIR="$MODDING_ROOT/dist/mods"
|
||||
|
||||
[ -d "$DATA_DIR" ] \
|
||||
|| { echo "Game data not found at $DATA_DIR - see the root README.md section 3." >&2; exit 1; }
|
||||
|
||||
echo "== Building mdlp =="
|
||||
BIN_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$BIN_DIR"' EXIT
|
||||
(cd "$MODDING_ROOT/src/mdlp" && go build -trimpath -o "$BIN_DIR/mdlp" .)
|
||||
|
||||
MDLP_ARGS=(-data "$DATA_DIR" -mods "$MODDING_ROOT/mods" -out "$OUT_DIR")
|
||||
if [ -n "${MODS:-}" ]; then
|
||||
MDLP_ARGS+=(-only "$MODS")
|
||||
fi
|
||||
|
||||
echo "== Processing mods =="
|
||||
"$BIN_DIR/mdlp" "${MDLP_ARGS[@]}"
|
||||
|
||||
echo "== Done =="
|
||||
echo "Output: $OUT_DIR"
|
||||
Reference in New Issue
Block a user