Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
631 changes: 631 additions & 0 deletions docs/games/gtnh-daily.md

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions docs/gtnh-daily/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# GTNH Daily reproducible setup

This folder is the from-scratch reference for our GT New Horizons Daily deployment.

In plain language: **GTNH Daily** is a frequently rebuilt test/development version of the GT New Horizons Minecraft modpack. This repo uses Nix/NixOS/Home Manager to recreate the Daily server and the matching Prism Launcher client after a rebuild or disk wipe. It recreates the pack files, updater state, services, timers, launchers, resource packs, and shader packs. It does **not** recreate the Minecraft world unless you restore a separate world backup.

The main goal is: after a drive wipe and rebuild, mutable world data aside, the Daily server and Prism client can be recreated, updated to the same exact server-published manifest, and used to join the server once downloads complete.

## If you just want to play

1. Make sure the Daily server is running or reachable through an SSH tunnel.
2. Close Prism/Minecraft.
3. Run `gtnh-daily-client-sync` as your normal user, not with `sudo`.
4. Launch the `GT New Horizons (Daily)` desktop entry.

If the server is remote and the desktop entry expects `localhost:25566`, run this in another terminal first:

```sh
ssh -N -L 25566:localhost:25566 nemesis
```

## If you administer the server

1. Check `gtnh-daily-bootstrap.service` after rebuild; it creates missing server files.
2. Check `gtnh-daily-server.service`; it runs the Minecraft server on port `25566`.
3. Check `gtnh-daily-update.timer`; it schedules Daily updates.
4. Keep separate backups of `/var/lib/gtnh-daily/server/World` if the world must survive disk loss.

## Read in this order

1. [glossary.md](./glossary.md) — plain-language definitions for Minecraft, Linux, systemd, Nix, and updater terms.
2. [concepts.md](./concepts.md) — Minecraft/Forge/GTNH concepts and file layout.
3. [daily-builds.md](./daily-builds.md) — GTNH Daily artifacts, manifests, and why client/server pinning matters.
4. [gtnh-daily-updater.md](./gtnh-daily-updater.md) — updater behavior, state, extras/excludes, config git repo, and our patch.
5. [server.md](./server.md) — NixOS server user, paths, services, bootstrap, update, rollback, firewall, and world-data boundary.
6. [client.md](./client.md) — Prism Launcher instance, bootstrap, client sync, resource packs, shader packs, desktop entries, and user timer.
7. [state-and-drift.md](./state-and-drift.md) — what we found on the live server/client and how it maps to declarative config.
8. [recovery.md](./recovery.md) — wipe/rebuild flow and operational recovery notes.
9. [implementation-notes.md](./implementation-notes.md) — guide for reading the Nix modules and generated shell/Python scripts.
10. [research-server-management.md](./research-server-management.md) — research note comparing itzg Docker GTNH, nixpkgs, and Minecraft server flakes.
11. [research-server-management.html](./research-server-management.html) — exhaustive plain HTML walkthrough of the same research, with each implementation separated into sections.

`docs/games/gtnh-daily.md` is the older long-form administration/history record. Start here instead unless you need historical migration notes.
107 changes: 107 additions & 0 deletions docs/gtnh-daily/client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Client and Prism Launcher

For definitions of Prism, Home Manager, SSH, resource packs, shader packs, and other terms, see [glossary.md](./glossary.md). For implementation details, see [implementation-notes.md](./implementation-notes.md).

## Prism Launcher

Prism Launcher manages Minecraft instances: separate installed copies of Minecraft/modpacks. Our Home Manager module installs Prism with JDK 25 available because GTNH Daily Java 17-25 builds are intended for modern Java/LWJGL3ify use. In practice that means Prism can launch this old Minecraft pack using a modern Java runtime.

The Daily instance name is exactly this. The name matters because the desktop entry and sync scripts use it in commands and paths:

```text
GT New Horizons (Daily)
```

The instance directory is:

```text
~/.local/share/PrismLauncher/instances/GT New Horizons (Daily)
```

The game directory is:

```text
~/.local/share/PrismLauncher/instances/GT New Horizons (Daily)/.minecraft
```

## Desktop entries

A desktop entry is the launcher icon/menu item shown by a desktop environment. Home Manager declares:

- a stable GTNH desktop entry for `GT_New_Horizons_2.8.4_Java_17-25`;
- a Daily desktop entry that launches `GT New Horizons (Daily)` and passes `--server localhost:25566`.

`--server localhost:25566` asks Prism/Minecraft to connect to a server on this machine at port `25566` after launch. If an SSH tunnel is running, that local port is forwarded to the remote server.

The Daily entry assumes the server is reachable locally or through whatever networking/SSH forwarding makes `localhost:25566` valid. For a remote server named `nemesis`, one simple tunnel is `ssh -N -L 25566:localhost:25566 nemesis`.

## Client bootstrap

`gtnh-daily-client-bootstrap` is installed on Linux Home Manager systems. Close Prism/Minecraft before running it; the command refuses to mutate the instance while the game appears active. It is idempotent and does the following:

1. reads `/var/lib/gtnh-daily/current-manifest.sha256` from the server over SSH, so passwordless SSH to the server host must work;
2. copies `/var/lib/gtnh-daily/current-manifest.json` with `scp`;
3. verifies the copied manifest against the server hash;
4. creates the Prism instance from a recent non-expired `mmcprism-java17-25` artifact if `.minecraft` is missing;
5. extracts the manifest config version;
6. runs `gtnh-daily-updater init --side client` if updater state is missing;
7. reconciles declared client extra mods into `.gtnh-daily-updater.json`;
8. installs declared resource pack and shader pack files;
9. unpacks the resource packs whose active names are directories;
10. writes the active `resourcePacks:` line in `options.txt` when the file exists.

If SSH is not configured, bootstrap fails before changing the instance. If `.minecraft` already exists but is broken or incomplete, bootstrap does not overwrite it; move the broken instance aside after backing up anything important, then rerun bootstrap/sync.

The bootstrap defaults to SSH host `nemesis`, the server hostname used by this repo. Override with:

```sh
GTNH_DAILY_SERVER=<host> gtnh-daily-client-bootstrap
```

## Client sync

`gtnh-daily-client-sync` is the normal update command. It:

1. takes a user lock under `~/.cache/gtnh-daily-client-sync`;
2. refuses to run if Prism/Minecraft appears active;
3. runs the client bootstrap first, so a missing client can be created;
4. exits early if the local applied hash equals the server hash;
5. copies and verifies the server manifest;
6. creates a full instance backup under `~/.local/share/PrismLauncher/backups`;
7. runs `gtnh-daily-updater update --manifest-file <server-manifest>`;
8. records the server hash locally.

The user timer runs hourly with a 15 minute randomized delay and `Persistent=true`. If the timer fires while Prism/Minecraft is open, the sync command refuses to change files and exits. Logs are visible with `journalctl --user -u gtnh-daily-client-sync.service`.

Backups are full directory copies under `~/.local/share/PrismLauncher/backups`. They can be large, and this script does not prune old backups automatically.

## Resource packs

A resource pack changes client-side textures, models, sounds, or UI. It does not change server gameplay. The live client had these selected resource packs:

```text
AE2-Dark-Mode.v.1.18
shadowui
Modernity-GTNH-main
```

The repo does not store these zip files because large binary assets make git history heavy and are harder to review. Instead, `nix/modules/prismlauncher.nix` declares each download URL and SHA-256 hash. Bootstrap downloads the files into `.minecraft/resourcepacks` when missing or when the local copy has the wrong hash. It then unpacks the zips into the directory names used by `options.txt`, because Minecraft enables these packs by directory name.

Declared resource pack downloads:

- `AE2-Dark-Mode.v.1.18.zip` from `Ranzuu/AE2-Dark-Mode`;
- `Shadow.UI.v5.30-Modernity.version.zip` from `Ranzuu/Shadow-UI`;
- `Modernity-GTNH-main.zip` from a pinned `ModernityGTNH/Modernity-GTNH` commit archive.

The GTNH-provided resource pack zips that come with the pack also remain present after artifact/bootstrap/update; our declared packs add the current custom selection on top.

## Shader packs

A shader pack changes client-side graphics such as lighting, shadows, and color. Shader packs are handled the same way as resource packs: URLs and hashes are declared in Nix, and bootstrap downloads them into `.minecraft/shaderpacks`.

Declared shader pack downloads:

- `ComplementaryReimagined_r5.8.1.zip` from Modrinth;
- `ComplementaryUnbound_r5.8.1.zip` from Modrinth.

Bootstrap also writes the small `ComplementaryUnbound_r5.8.1.zip.txt` option sidecar because it is plain text, not a large binary asset. The sidecar stores Complementary Unbound settings such as light color multipliers/night brightness. Shader selection itself is normally local/client preference; the files are what matters for being able to select/use the same shaders after rebuild.
67 changes: 67 additions & 0 deletions docs/gtnh-daily/concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Concepts: GTNH and modded Minecraft

If any term here is unfamiliar, check [glossary.md](./glossary.md). This page gives the short conceptual overview; the glossary gives one-line definitions.

## GT New Horizons

GT New Horizons (GTNH) is a large Minecraft 1.7.10 expert modpack. It combines Forge, GregTech, questing, many technology/magic mods, custom configs, scripts, resources, and launcher/server packaging. A working instance is not just a list of mod jars: it is the combination of jars, configuration trees, scripts, resources, Java arguments, launcher metadata, and runtime state.

## Client vs server sides

Many mods are side-specific:

- **Server-required mods** run in the dedicated server JVM and define gameplay, world generation, blocks, items, recipes, networking, permissions, and backend integrations.
- **Client-required mods** run in the player JVM and provide rendering, UI, keybinds, minimaps, shader support, resource loading, and client-only helpers.
- **Both-side mods** must exist on both sides with compatible versions so Forge networking and registries line up.

A modpack update must keep the client and server on compatible builds. For Daily builds, compatibility means both sides should use the same Daily manifest or at least the same coherent build set.

## Forge 1.7.10 layout

A dedicated server directory contains items such as:

- `mods/` — Forge mod jars loaded by the server.
- `config/` — mod configuration files.
- `scripts/` — CraftTweaker/pack scripts.
- `libraries/` — Forge/Minecraft libraries.
- `java9args.txt` — Java 9+ / modern Java argument file used by GTNH packaging.
- `lwjgl3ify-forgePatches.jar` — patched launch jar used by modern Java/LWJGL3ify setups.
- `server.properties` — vanilla server settings such as port and level name.
- `eula.txt` — Mojang EULA acceptance; must contain `eula=true` before starting.
- `ops.json`, `whitelist.json`, ban lists, `usercache.json` — server identity/admin state.
- `World/` — mutable world data. This is intentionally outside our reproducibility guarantee.

A Prism/MultiMC client instance directory contains:

- `.minecraft/mods/` — client mod jars.
- `.minecraft/config/` — client mod config.
- `.minecraft/resourcepacks/` — resource packs and unpacked resource pack directories.
- `.minecraft/shaderpacks/` — shader zip files and sidecar config files.
- `.minecraft/options.txt` — selected resource packs and many local client options.
- launcher metadata at the instance root, plus `.gtnh-daily-updater.json` at the instance root.

`gtnh-daily-updater` deliberately treats Prism/MultiMC clients differently from servers: if `<instance-dir>/.minecraft` exists, the game directory is `.minecraft`; otherwise the game directory is the instance directory itself.

## Mutable vs declarative data

We reproduce pack and environment state, not world history. “Declarative” means the desired state is written in repo config so it can be recreated. “Mutable” means the data changes during play and must be backed up separately if it matters.

Declarative state includes:

- chosen Daily artifact/update mechanism;
- updater extras/excludes;
- server port and service launch policy;
- EULA acceptance;
- client bootstrap/sync commands;
- current resource/shader pack files that are not generated by play;
- timers and firewall ports.

Mutable data includes:

- `World/` and all dimensions/chunk/player/world mod data;
- logs;
- backups;
- generated map tiles/cache (`dynmap`, web-map output);
- download caches;
- transient runtime files;
- local player-only preferences that are not required to join, such as many video/keybind/UI preferences. The docs only force the resource-pack selection needed to restore the intended visual setup.
45 changes: 45 additions & 0 deletions docs/gtnh-daily/daily-builds.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# GTNH Daily builds, artifacts, and manifests

For definitions of GitHub Actions, artifacts, manifests, SHA-256, and tokens, see [glossary.md](./glossary.md).

## Source of Daily builds

GTNH Daily builds are produced by the `GTNewHorizons/DreamAssemblerXXL` GitHub Actions workflow `daily-modpack-build.yml`. GitHub Actions is GitHub's build automation; this workflow assembles GTNH Daily packages. They are not normal stable GitHub releases from `GT-New-Horizons-Modpack`.

The workflow publishes artifacts whose names follow this pattern:

- `GTNH-daily-YYYY-MM-DD+NNN-server-java17-25.zip` — dedicated server bootstrap files.
- `GTNH-daily-YYYY-MM-DD+NNN-mmcprism-java17-25.zip` — Prism/MultiMC client bootstrap files.
- `gtnh-daily-YYYY-MM-DD+NNN-manifest.json` — build manifest; includes the config version.
- `daily-build-bundle` — convenience bundle.

Artifacts can expire, meaning GitHub may delete old downloadable build files. Our bootstrap scripts therefore search recent successful workflow runs and choose a run with non-expired required artifacts. If GitHub requires authenticated artifact download or rate-limit help, provide `GITHUB_TOKEN` in the service/user environment. Recovery examples show how to set it temporarily.

## Published latest manifest

Normal updates use the published Daily manifest URL:

```text
https://raw.githubusercontent.com/GTNewHorizons/DreamAssemblerXXL/master/releases/manifests/daily.json
```

This manifest is the current latest Daily metadata. It records pack version information, the config version, timestamp, and selected mods. “Selected mods” means the exact mod entries the Daily build expects for that side/version.

## Why the server publishes its applied manifest

If the server updated directly from the latest remote manifest and the client later independently updated from the latest remote manifest, the client could accidentally advance beyond the server if a newer Daily appeared between the two operations. “Advance beyond the server” means the client installs a newer/different mod set than the server is running, which can cause join failures or mod mismatch errors.

To prevent this, our server update flow:

1. downloads the current Daily manifest into a temporary file;
2. updates the server using that exact local file;
3. publishes that exact file to `/var/lib/gtnh-daily/current-manifest.json`;
4. writes `/var/lib/gtnh-daily/current-manifest.sha256`.

The client sync flow then fetches those two files from the server over SSH and updates against the same pinned manifest. This keeps client and server coherent: both sides use the same intended mod/config metadata.

## Bootstrap versus update

Initial bootstrap requires a full artifact because `gtnh-daily-updater init` needs an existing instance to scan. The updater is not a from-nothing installer; it records what is already present, then can update it. After that, updates can use `gtnh-daily-updater update` plus the manifest.

Our server bootstrap creates the initial server files from a server artifact only when the expected launch files are missing. Our client bootstrap creates the Prism instance from a client artifact only when `.minecraft` is missing. Re-running bootstrap is therefore idempotent and does not clobber an already-created instance.
Loading