From fda2ed5997f81ddc29df5992a608df77d2174936 Mon Sep 17 00:00:00 2001 From: "Derek T. Jones" Date: Thu, 6 Aug 2026 08:56:24 -0700 Subject: [PATCH 1/2] Package Archetype for a base that can compile it The snapcraft.yaml had not been touched since 2021 and could not have built anything since the move to C++20. core18 is Ubuntu 18.04, whose g++ is 7; the part also still described a make build, from before the interpreter was built with CMake, and claimed version 2.0. core24 brings g++ 13. The part is now the cmake plugin pointed at src/, which already has an install() rule, so the binary stages without help. The version is read out of main.cc at pull time via adopt-info rather than repeated here, which is how the old file came to sit five years behind. Moved back to snap/snapcraft.yaml. Snapcraft looks in snapcraft.yaml, snap/, build-aux/snap/ and .snapcraft.yaml, and nowhere else -- so the move to drivers/snap/ in e22fc85, collateral from an unrelated restructure, left the file somewhere the tool would never find. Four years unbuildable for two separate reasons is enough. Strict confinement now names the interfaces it actually needs. A game is a file the player names on the command line and a save is written next to it, which is the 'home' plug; 'removable-media' is there for anyone keeping games on a stick, and needs connecting by hand. The three games from the browser build ship compiled, along with the library sources an author's own game includes. Compiling a game means running an interpreter, so that part waits for the native one to stage -- which also makes it the step that cannot be cross-compiled. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019g4fqvhoV5MtLJJXM7uFLZ --- drivers/snap/snapcraft.yaml | 22 ---------- snap/snapcraft.yaml | 88 +++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 22 deletions(-) delete mode 100644 drivers/snap/snapcraft.yaml create mode 100644 snap/snapcraft.yaml diff --git a/drivers/snap/snapcraft.yaml b/drivers/snap/snapcraft.yaml deleted file mode 100644 index a4f1bf8..0000000 --- a/drivers/snap/snapcraft.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: archetype -base: core18 -version: '2.0' -summary: Archetype -description: | - A programming language for writing and playing text adventure games, - and other text-based games. - -confinement: strict - -parts: - archetype: - source: archetype - artifacts: - - archetype - build-packages: - - g++ - plugin: make - -apps: - archetype: - command: archetype diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 0000000..b9b2957 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,88 @@ +name: archetype +title: Archetype +base: core24 +adopt-info: interpreter +license: MIT +summary: A language for writing and playing text adventure games + +description: | + Archetype is a message-passing, object-oriented programming language for + writing text-based adventure games, and the interpreter that plays them. + + Compile and run a game of your own: + + archetype --source=mygame.arch --include=$SNAP/usr/share/archetype/games + + The library sources -- standard.arch, intrptr.arch, utility.arch and the rest + -- are installed in that directory, which is what --include has to be pointed + at for `include "standard"` to resolve. + + Three games come compiled and ready to play: + + archetype --perform=$SNAP/usr/share/archetype/games/gorreven.acx + + Those live on read-only squashfs, so --autosave needs a path of its own in + your home directory. A save file is a mutated copy of the game binary, and + either one can be resumed with --perform. + +grade: stable +confinement: strict + +platforms: + amd64: + arm64: + +apps: + archetype: + command: usr/bin/archetype + plugs: + # A game is a file the player names on the command line, and saves are + # written alongside it, so the interpreter has to see the directory it + # was invoked from. 'home' is auto-connected from the store; + # 'removable-media' is not, and needs `snap connect` to be of use. + - home + - removable-media + +parts: + interpreter: + plugin: cmake + source: . + # The CMakeLists.txt is in src/, not at the root of the repository. + source-subdir: src + cmake-parameters: + - -DCMAKE_INSTALL_PREFIX=/usr + - -DCMAKE_BUILD_TYPE=Release + build-packages: + # core24 is Ubuntu 24.04, so this is g++ 13 -- the reason the base had to + # move. core18's g++ 7 cannot compile the C++20 this interpreter is + # written in. + - g++ + override-pull: | + craftctl default + # Take the version from the interpreter itself rather than repeating it + # here, which is how the old file came to claim 2.0 for five years after + # the interpreter had moved on. + craftctl set version="$(sed -n 's/.*VersionString = "\([^"]*\)".*/\1/p' src/main.cc)" + + games: + plugin: nil + source: games + # Compiling a game means running an interpreter, so the native one has to be + # built and staged before this part builds. That also makes this the one + # step that cannot be cross-compiled: building for an architecture the + # builder cannot execute needs a native or emulated runner per platform. + after: + - interpreter + override-build: | + craftctl default + games="$CRAFT_PART_INSTALL/usr/share/archetype/games" + mkdir -p "$games" + # The sources ship too: they are the library an author's own game + # includes, not just the input that produced the .acx files below. + cp "$CRAFT_PART_SRC"/*.arch "$games/" + for game in gorreven starship animal; do + "$CRAFT_STAGE/usr/bin/archetype" --silent \ + --source="$CRAFT_PART_SRC/$game.arch" \ + --include="$CRAFT_PART_SRC" \ + --create="$games/$game.acx" + done From 05ebee7ebcaa6313843bd101c47bc32d3761c0c9 Mon Sep 17 00:00:00 2001 From: "Derek T. Jones" Date: Thu, 6 Aug 2026 08:56:24 -0700 Subject: [PATCH 2/2] Build the snap in CI, and play a turn with it Nothing else in this repository proves the packaging works, and snapcraft does not run on the machine the interpreter is developed on, so until now the only way to find out was to publish and hear about it. Building proves it packages. Installing the result and playing a turn proves the binary runs under confinement and that the bundled games are where the snap's own description promises they are -- which is the part most likely to rot, since it is prose about paths. Restricted to changes under snap/, plus workflow_dispatch. A snap build compiles the whole interpreter in an LXD container, minutes against the seconds CI takes, and a C++ change that will not compile has already failed in CI before it could fail here. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019g4fqvhoV5MtLJJXM7uFLZ --- .github/workflows/snap.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/snap.yml diff --git a/.github/workflows/snap.yml b/.github/workflows/snap.yml new file mode 100644 index 0000000..02d44d6 --- /dev/null +++ b/.github/workflows/snap.yml @@ -0,0 +1,35 @@ +name: Snap + +# Only when the packaging itself changes, plus on demand. Building a snap +# spins up an LXD container and compiles the interpreter from scratch, which is +# minutes rather than the seconds CI takes -- and a C++ change that fails to +# compile has already failed in CI by the time it would fail here. +on: + pull_request: + paths: + - 'snap/**' + - '.github/workflows/snap.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: snapcore/action-build@v1 + id: snapcraft + # Building proves it packages; installing and playing a turn proves the + # binary runs under confinement and that the bundled games are where the + # snap's own description says they are. + - name: Install and play a turn + run: | + sudo snap install --dangerous "${{ steps.snapcraft.outputs.snap }}" + echo look | archetype \ + --perform=/snap/archetype/current/usr/share/archetype/games/gorreven.acx + - uses: actions/upload-artifact@v4 + with: + name: archetype-snap + path: ${{ steps.snapcraft.outputs.snap }}